All Downloads are FREE. Search and download functionalities are using the official Maven repository.

me.lemire.integercompression.differential.Delta Maven / Gradle / Ivy

Go to download

It is a library to compress and uncompress arrays of integers very fast. The assumption is that most (but not all) values in your array use less than 32 bits.

There is a newer version: 0.2.1
Show newest version
/**
 * This code is released under the
 * Apache License Version 2.0 http://www.apache.org/licenses/.
 *
 * (c) Daniel Lemire, http://lemire.me/en/
 */

package me.lemire.integercompression.differential;

/**
 * Generic class to compute differential coding.
 * 
 * @author Daniel Lemire
 * 
 */
public final class Delta {

        /**
         * Apply differential coding (in-place).
         * 
         * @param data
         *                data to be modified
         */
        public static void delta(int[] data) {
                for (int i = data.length - 1; i > 0; --i) {
                        data[i] -= data[i - 1];
                }
        }

        /**
         * Apply differential coding (in-place) given an initial value.
         * 
         * @param data
         *                data to be modified
         * @param start
         *                starting index
         * @param length
         *                number of integers to process
         * @param init
         *                initial value
         * @return next initial vale
         */
        public static int delta(int[] data, int start, int length, int init) {
                final int nextinit = data[start + length - 1];
                for (int i = length - 1; i > 0; --i) {
                        data[start + i] -= data[start + i - 1];
                }
                data[start] -= init;
                return nextinit;
        }

        /**
         * Compute differential coding given an initial value. Output is written
         * to a provided array: must have length "length" or better.
         * 
         * @param data
         *                data to be modified
         * @param start
         *                starting index
         * @param length
         *                number of integers to process
         * @param init
         *                initial value
         * @param out
         *                output array
         * @return next initial vale
         */
        public static int delta(int[] data, int start, int length, int init,
                int[] out) {
                for (int i = length - 1; i > 0; --i) {
                        out[i] = data[start + i] - data[start + i - 1];
                }
                out[0] = data[start] - init;
                return data[start + length - 1];
        }

        /**
         * Undo differential coding (in-place). Effectively computes a prefix
         * sum.
         * 
         * @param data
         *                to be modified.
         */
        public static void inverseDelta(int[] data) {
                for (int i = 1; i < data.length; ++i) {
                        data[i] += data[i - 1];
                }
        }

        /**
         * Undo differential coding (in-place). Effectively computes a prefix
         * sum. Like inverseDelta, only faster.
         * 
         * @param data
         *                to be modified
         */
        public static void fastinverseDelta(int[] data) {
                int sz0 = data.length / 4 * 4;
                int i = 1;
                if (sz0 >= 4) {
                        int a = data[0];
                        for (; i < sz0 - 4; i += 4) {
                                a = data[i] += a;
                                a = data[i + 1] += a;
                                a = data[i + 2] += a;
                                a = data[i + 3] += a;
                        }
                }

                for (; i != data.length; ++i) {
                        data[i] += data[i - 1];
                }
        }

        /**
         * Undo differential coding (in-place). Effectively computes a prefix
         * sum. Like inverseDelta, only faster. Uses an initial value.
         * 
         * @param data
         *                to be modified
         * @param start
         *                starting index
         * @param length
         *                number of integers to process
         * @param init
         *                initial value
         * @return next initial value
         */
        public static int fastinverseDelta(int[] data, int start, int length,
                int init) {
                data[start] += init;
                int sz0 = length / 4 * 4;
                int i = 1;
                if (sz0 >= 4) {
                        int a = data[start];
                        for (; i < sz0 - 4; i += 4) {
                                a = data[start + i] += a;
                                a = data[start + i + 1] += a;
                                a = data[start + i + 2] += a;
                                a = data[start + i + 3] += a;
                        }
                }

                for (; i != length; ++i) {
                        data[start + i] += data[start + i - 1];
                }
                return data[start + length - 1];
        }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy