<commit_before>package etomica.data;

import etomica.data.types.DataDoubleArray;
import etomica.data.types.DataGroup;
import etomica.data.types.DataGroup.DataInfoGroupFactory;
import etomica.units.Null;
import etomica.util.Arrays;

/**
 * Accumulator for calculating ratio between sums.  This class calculates all
 * possible ratios vi/vj (as opposed to AccumulatorRatioAverageCovariance,
 * which calculates vi/v0.  
 */
public class AccumulatorRatioAverageCovarianceFull extends AccumulatorAverageCovariance {

    private static final long serialVersionUID = 1L;

    public AccumulatorRatioAverageCovarianceFull() {
        this(1000);
    }

    public AccumulatorRatioAverageCovarianceFull(long blockSize) {
        super(blockSize);
        ratioTag = new DataTag();
        ratioErrorTag = new DataTag();
    }

    public DataTag getTag(StatType statType) {
        if (statType == RATIO) {
            return ratioTag;
        }
        if (statType == RATIO_ERROR) {
            return ratioErrorTag;
        }
        return super.getTag(statType);
    }

    public IData getData() {
        if (sum == null) return null;
        // let superclass calculate its quantities
        super.getData();
        // now, calculate ratios
        int n = sum.getLength();
        double[] r = ratio.getData();
        double[] re = ratioError.getData();
        if (count > 1) {
            // calculate uncertainties on ratios
            for (int i=0; i<n-1; i++) {
                re[i*n+i] = 0;
                double avgi = sum.getValue(i)/(count*blockSize);
                double rei = error.getValue(i)/(avgi);
                rei *= rei;
                for (int j=i+1; j<n; j++) {
                    double avgj = sum.getValue(j)/(count*blockSize);
                    double rej = error.getValue(j)/(avgj);
                    rej *= rej;
                    int k = i*n+j;
                    double rk = avgi/avgj;
                    double covarianceContribution = -2*blockCovariance.getValue(i*n+j)/(avgi*avgj*(count-1));
                    double rek = rk*rk * (rei + rej + covarianceContribution);
                    if (Double.isNaN(rek)) {
                        re[j*n+i] = Double.NaN;
                        re[k] = Double.NaN;
                        continue;
                    }
                    rek = (rek >= 0) ? rek : 0;
                    re[k] = Math.sqrt(rek);
                    
                    re[j*n+i] = re[k] / (rk*rk);
                }
            }
        }
        if (count > 0 || blockCountDown < blockSize) {
            // now use *all* of the data to calculate ratios
            for (int i=0; i<n; i++) {
                r[i*n+i] = 1;
                for (int j=i+1; j<n; j++) {
                    r[i*n+j] = average.getValue(i)/average.getValue(j);
                }
            }
        }

        return dataGroup;
    }

    public void reset() {
        if (sum == null || ratio == null) {
            //no data has been added yet, so nothing to reset
            return;
        }
        super.reset();
        ratio.E(Double.NaN);
        ratioError.E(Double.NaN);
    }
    
    public IEtomicaDataInfo processDataInfo(IEtomicaDataInfo incomingDataInfo) {
        super.processDataInfo(incomingDataInfo);

        int n = incomingDataInfo.getLength();
        ratio = new DataDoubleArray(new int[]{n,n});
        ratioError = new DataDoubleArray(new int[]{n,n});
<commit_msg>ratioError is NaN if we don't have 2 blocks<commit_after>package etomica.data;

import etomica.data.types.DataDoubleArray;
import etomica.data.types.DataGroup;
import etomica.data.types.DataGroup.DataInfoGroupFactory;
import etomica.units.Null;
import etomica.util.Arrays;

/**
 * Accumulator for calculating ratio between sums.  This class calculates all
 * possible ratios vi/vj (as opposed to AccumulatorRatioAverageCovariance,
 * which calculates vi/v0.  
 */
public class AccumulatorRatioAverageCovarianceFull extends AccumulatorAverageCovariance {

    private static final long serialVersionUID = 1L;

    public AccumulatorRatioAverageCovarianceFull() {
        this(1000);
    }

    public AccumulatorRatioAverageCovarianceFull(long blockSize) {
        super(blockSize);
        ratioTag = new DataTag();
        ratioErrorTag = new DataTag();
    }

    public DataTag getTag(StatType statType) {
        if (statType == RATIO) {
            return ratioTag;
        }
        if (statType == RATIO_ERROR) {
            return ratioErrorTag;
        }
        return super.getTag(statType);
    }

    public IData getData() {
        if (sum == null) return null;
        // let superclass calculate its quantities
        super.getData();
        // now, calculate ratios
        int n = sum.getLength();
        double[] r = ratio.getData();
        double[] re = ratioError.getData();
        if (count > 1) {
            // calculate uncertainties on ratios
            for (int i=0; i<n-1; i++) {
                re[i*n+i] = 0;
                double avgi = sum.getValue(i)/(count*blockSize);
                double rei = error.getValue(i)/(avgi);
                rei *= rei;
                for (int j=i+1; j<n; j++) {
                    double avgj = sum.getValue(j)/(count*blockSize);
                    double rej = error.getValue(j)/(avgj);
                    rej *= rej;
                    int k = i*n+j;
                    double rk = avgi/avgj;
                    double covarianceContribution = -2*blockCovariance.getValue(i*n+j)/(avgi*avgj*(count-1));
                    double rek = rk*rk * (rei + rej + covarianceContribution);
                    if (Double.isNaN(rek)) {
                        re[j*n+i] = Double.NaN;
                        re[k] = Double.NaN;
                        continue;
                    }
                    rek = (rek >= 0) ? rek : 0;
                    re[k] = Math.sqrt(rek);
                    
                    re[j*n+i] = re[k] / (rk*rk);
                }
            }
        }
        else {
        	ratioError.E(Double.NaN);
        }
        if (count > 0 || blockCountDown < blockSize) {
            // now use *all* of the data to calculate ratios
            for (int i=0; i<n; i++) {
                r[i*n+i] = 1;
                for (int j=i+1; j<n; j++) {
                    r[i*n+j] = average.getValue(i)/average.getValue(j);
                }
            }
        }

        return dataGroup;
    }

    public void reset() {
        if (sum == null || ratio == null) {
            //no data has been added yet, so nothing to reset
            return;
        }
        super.reset();
        ratio.E(Double.NaN);
        ratioError.E(Double.NaN);
    }
    
    public IEtomicaDataInfo processDataInfo(IEtomicaDataInfo incomingDataInfo) {
        super.processDataInfo(incomingDataInfo);

        int n = incomingDataInfo.getLength();
        ratio = new DataDoubleArray(new int[]{n,n});
        ratioError = new DataDoubleArray(new int[]{n,n});

{'fraction_non_alphanumeric': 0.11285714285714285, 'fraction_numerical': 0.005571428571428572, 'mean_word_length': 1.6319548872180452, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6610407', 'n_tokens_mistral': 2163, 'n_tokens_neox': 2001, 'n_words': 476}