Protect weighted mean and weighted total by ensuring double precision - #246
kanchukaitis wants to merge 1 commit into
Conversation
weightedMean and weightedTotal stored weights with their input class. Single weights (e.g. cosd of single-precision lat/lon) then mix single with the double [] of non-weighted dimensions in obj.weights, and serialize's cell2mat rejects the mixture of precisions in pre-R2025a ("All contents of the input cell array must be of the same data type"), leading to a failed stateVector.build. Solution is to cast the stored weights to double.
|
Hey @kanchukaitis, I think this makes sense. One thing I want to check though - will upgrading the weights always promote the built ensemble from single to double? For example, consider a state vector that's designed from some single precision variable. And that state vector has a weighted mean that uses single precision weights. In that case, I think the built ensemble should also be single precision - all our data so far has been single precision, and it seems like a memory waste to force everything to be twice as large. Would you be able to test that scenario with the new code and see what happens? (and if it differs from the current implementation) Brainstorming a possible alternate approach - maybe stateVectorVariable needs to handle the data type of the weights more carefully. Something along the lines of:
Very open to suggestions here, let me know what you think |
Summary
This PR addresses this issue: #242
stateVectorVariable.weightedMeanandweightedTotalstore the user's weights with their input class:obj.weights{d} = weights{k}(:);When those weights are single — e.g.
cosd()of single-precision lat/lon metadata from a gridfile — the per-dimensionobj.weightscell ends up mixing single (the weighted dimension) with double[](the non-weighted dimensions).stateVectorVariable.serializethen stacks that cell withcell2mat(viastackVectors), which prior to R2025a throws:So
stateVector.buildfails whenever a variable combines a spatial field with a pre-computed weighted (e.g. cosine-latitude hemispheric) mean and the coordinates/weights are single precision.Fix
Cast the stored weights to
doublein bothweightedMean.mandweightedTotal.m:obj.weights{d} = double(weights{k}(:));This guarantees
serialize'scell2matalways sees one class (double), matching thedouble []of the non-weighted dimensions. This doesn't matter on R2025a+ (wherecell2matbecame more forgiving for this).weightedTotalis also included because it has the identical storage line and the same potential for a precision mismatch.Reproduction
Casting the weights (or, user-side,
w = double(cosd(meta.lat(...)))) resolves it.