Skip to content

Commit 92d6370

Browse files
committed
GDALDataset::ComputeInterBandCovarianceMatrix(): optimize for a all-invalid block
1 parent 25c4fb2 commit 92d6370

File tree

2 files changed

+55
-7
lines changed

2 files changed

+55
-7
lines changed

autotest/gcore/gdal_stats.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,6 +1501,35 @@ def test_stats_ComputeInterBandCovarianceMatrix_nan_result():
15011501
###############################################################################
15021502

15031503

1504+
def test_stats_ComputeInterBandCovarianceMatrix_whole_block_nodata():
1505+
1506+
ds = gdal.GetDriverByName("MEM").Create("", 2, 3, 2, gdal.GDT_Float32)
1507+
ds.GetRasterBand(1).WriteRaster(
1508+
0, 0, 2, 1, struct.pack("f" * 2, math.nan, math.nan)
1509+
)
1510+
ds.GetRasterBand(1).WriteRaster(0, 1, 2, 1, struct.pack("f" * 2, 0, 1))
1511+
ds.GetRasterBand(1).WriteRaster(
1512+
0, 2, 2, 1, struct.pack("f" * 2, math.nan, math.nan)
1513+
)
1514+
ds.GetRasterBand(2).WriteRaster(
1515+
0, 0, 2, 1, struct.pack("f" * 2, math.nan, math.nan)
1516+
)
1517+
ds.GetRasterBand(2).WriteRaster(0, 1, 2, 1, struct.pack("f" * 2, 1, 0))
1518+
ds.GetRasterBand(2).WriteRaster(
1519+
0, 2, 2, 1, struct.pack("f" * 2, math.nan, math.nan)
1520+
)
1521+
1522+
expected_cov_matrix = [[0.5, -0.5], [-0.5, 0.5]]
1523+
1524+
cov_matrix = ds.ComputeInterBandCovarianceMatrix()
1525+
assert list(chain.from_iterable(cov_matrix)) == pytest.approx(
1526+
list(chain.from_iterable(expected_cov_matrix))
1527+
)
1528+
1529+
1530+
###############################################################################
1531+
1532+
15041533
def test_stats_ComputeInterBandCovarianceMatrix_failed_to_compute_stats():
15051534

15061535
ds = gdal.GetDriverByName("MEM").Create("", 2, 1, 1, gdal.GDT_Float32)

gcore/gdaldataset.cpp

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12953,6 +12953,7 @@ ComputeInterBandCovarianceMatrixInternal(GDALDataset *poDS,
1295312953
return eErr;
1295412954

1295512955
// Compute the mean of all bands for this block
12956+
bool bAllBandsAreAllNodata = false;
1295612957
bool bNoBandHasNodata = false;
1295712958
for (int i = 0; i < nBandCount; ++i)
1295812959
{
@@ -12975,19 +12976,24 @@ ComputeInterBandCovarianceMatrixInternal(GDALDataset *poDS,
1297512976
}
1297612977
adfCurBlockMean[i] = nCount > 0 ? dfSum / nCount : ZERO;
1297712978
anCurBlockCount[i] = nCount;
12979+
bAllBandsAreAllNodata =
12980+
(i == 0 || bAllBandsAreAllNodata) && (nCount == 0);
1297812981
bNoBandHasNodata = (i == 0 || bNoBandHasNodata) &&
1297912982
(nCount == nThisBlockPixelCount);
1298012983
}
1298112984

1298212985
// Modify the pixel values to shift them by minus the mean
12983-
for (int i = 0; i < nBandCount; ++i)
12986+
if (!bAllBandsAreAllNodata)
1298412987
{
12985-
T *padfI =
12986-
adfCurBlockPixelsAllBands.data() + i * nThisBlockPixelCount;
12987-
const T dfMeanI = adfCurBlockMean[i];
12988-
for (size_t iPixel = 0; iPixel < nThisBlockPixelCount; ++iPixel)
12988+
for (int i = 0; i < nBandCount; ++i)
1298912989
{
12990-
padfI[iPixel] -= dfMeanI;
12990+
T *padfI =
12991+
adfCurBlockPixelsAllBands.data() + i * nThisBlockPixelCount;
12992+
const T dfMeanI = adfCurBlockMean[i];
12993+
for (size_t iPixel = 0; iPixel < nThisBlockPixelCount; ++iPixel)
12994+
{
12995+
padfI[iPixel] -= dfMeanI;
12996+
}
1299112997
}
1299212998
}
1299312999

@@ -13057,7 +13063,20 @@ ComputeInterBandCovarianceMatrixInternal(GDALDataset *poDS,
1305713063
}
1305813064
};
1305913065

13060-
if (bNoBandHasNodata)
13066+
if (bAllBandsAreAllNodata)
13067+
{
13068+
// Optimized code path where all values in the current block
13069+
// are invalid
13070+
13071+
for (int i = 0; i < nBandCount; ++i)
13072+
{
13073+
for (int j = i; j < nBandCount; ++j)
13074+
{
13075+
UpdateGlobalValues(i, j, 0, ZERO);
13076+
}
13077+
}
13078+
}
13079+
else if (bNoBandHasNodata)
1306113080
{
1306213081
// Optimized code path where there are no invalid value in the
1306313082
// current block

0 commit comments

Comments
 (0)