public static int encodeLinear(
      double[] data,
      int dataSize,
      byte[] result,
      double fixedPoint
  ) {
    long[] ints = new long[3];
    int i, ri, halfByteCount, hbi;
    byte halfBytes[] = new byte[10];
    long extrapol, diff;

    encodeFixedPoint(fixedPoint, result);

    if (dataSize == 0) {
      return 8;
    }

    ints[1] = (long) (data[0] * fixedPoint + 0.5);
    for (i = 0; i < 4; i++) {
      result[8 + i] = (byte) ((ints[1] >> (i * 8)) & 0xff);
    }

    if (dataSize == 1) {
      return 12;
    }

    ints[2] = (long) (data[1] * fixedPoint + 0.5);
    for (i = 0; i < 4; i++) {
      result[12 + i] = (byte) ((ints[2] >> (i * 8)) & 0xff);
    }

    halfByteCount = 0;
    ri = 16;

    for (i = 2; i < dataSize; i++) {
      ints[0] = ints[1];
      ints[1] = ints[2];
      ints[2] = (long) (data[i] * fixedPoint + 0.5);
      extrapol = ints[1] + (ints[1] - ints[0]);
      diff = ints[2] - extrapol;
      halfByteCount += encodeInt(diff, halfBytes, halfByteCount);

      for (hbi = 1; hbi < halfByteCount; hbi += 2) {
        result[ri++] = (byte) ((halfBytes[hbi - 1] << 4) | (halfBytes[hbi] & 0xf));
      }

      if (halfByteCount % 2 != 0) {
        halfBytes[0] = halfBytes[halfByteCount - 1];
        halfByteCount = 1;
      } else {
        halfByteCount = 0;
      }

    }
    if (halfByteCount == 1) {
      result[ri++] = (byte) (halfBytes[0] << 4);
    }

    return ri;
  }
public static int encodeLinear ( double [ ] data , int dataSize , byte [ ] result , double fixedPoint ) { long [ ] ints = new long [ 3 ] ; int i , ri , halfByteCount , hbi ; byte halfBytes [ ] = new byte [ 10 ] ; long extrapol , diff ; encodeFixedPoint ( fixedPoint , result ) ; if ( dataSize == 0 ) { return 8 ; } ints [ 1 ] = ( long ) ( data [ 0 ] * fixedPoint + 0.5 ) ; for ( i = 0 ; i < 4 ; i ++ ) { result [ 8 + i ] = ( byte ) ( ( ints [ 1 ] > > ( i * 8 ) ) & 0xff ) ; } if ( dataSize == 1 ) { return 12 ; } ints [ 2 ] = ( long ) ( data [ 1 ] * fixedPoint + 0.5 ) ; for ( i = 0 ; i < 4 ; i ++ ) { result [ 12 + i ] = ( byte ) ( ( ints [ 2 ] > > ( i * 8 ) ) & 0xff ) ; } halfByteCount = 0 ; ri = 16 ; for ( i = 2 ; i < dataSize ; i ++ ) { ints [ 0 ] = ints [ 1 ] ; ints [ 1 ] = ints [ 2 ] ; ints [ 2 ] = ( long ) ( data [ i ] * fixedPoint + 0.5 ) ; extrapol = ints [ 1 ] + ( ints [ 1 ] - ints [ 0 ] ) ; diff = ints [ 2 ] - extrapol ; halfByteCount += encodeInt ( diff , halfBytes , halfByteCount ) ; for ( hbi = 1 ; hbi < halfByteCount ; hbi += 2 ) { result [ ri ++ ] = ( byte ) ( ( halfBytes [ hbi - 1 ] << 4 ) | ( halfBytes [ hbi ] & 0xf ) ) ; } if ( halfByteCount % 2 != 0 ) { halfBytes [ 0 ] = halfBytes [ halfByteCount - 1 ] ; halfByteCount = 1 ; } else { halfByteCount = 0 ; } } if ( halfByteCount == 1 ) { result [ ri ++ ] = ( byte ) ( halfBytes [ 0 ] << 4 ) ; } return ri ; }
Encodes the doubles in data by first using a - lossy conversion to a 4 byte 5 decimal fixed
point repressentation - storing the residuals from a linear prediction after first to values -
encoding by encodeInt (see above)
<p>
The resulting binary is maximally 8 + dataSize * 5 bytes, but much less if the data is
reasonably smooth on the first order.
<p>
This encoding is suitable for typical m/z or retention time binary arrays. On a test set, the
encoding was empirically show to be accurate to at least 0.002 ppm.

@param data array of doubles to be encoded
@param dataSize number of doubles from data to encode
@param result array were resulting bytes should be stored
@param fixedPoint the scaling factor used for getting the fixed point repr. This is stored in
the binary and automatically extracted on decoding.
@return the number of encoded bytes