Libpolycomp  1.0
A compression/decompression library that implements the polynomial compression and other simple compression schemes
Polynomial compression functions

Enumerations

enum  pcomp_transform_direction_t { PCOMP_TD_DIRECT = 0, PCOMP_TD_INVERSE = 1 }
 Direction of a Chebyshev transform. More...
 
enum  pcomp_polycomp_algorithm_t { PCOMP_ALG_USE_CHEBYSHEV = 0, PCOMP_ALG_NO_CHEBYSHEV = 1 }
 Kind of algorithm used for the polynomial compression. More...
 

Functions

pcomp_polycomp_tpcomp_init_polycomp (pcomp_chunk_size_t samples_per_chunk, pcomp_poly_size_t num_of_coeffs, double max_allowable_error, pcomp_polycomp_algorithm_t algorithm)
 Allocate space for a pcomp_polycomp_t structure. More...
 
void pcomp_free_polycomp (pcomp_polycomp_t *params)
 Free the memory allocated by pcomp_init_polycomp for a pcomp_polycomp_t structure. More...
 
pcomp_chunk_size_t pcomp_polycomp_samples_per_chunk (const pcomp_polycomp_t *params)
 Return the number of samples per chunk. More...
 
pcomp_poly_size_t pcomp_polycomp_num_of_poly_coeffs (const pcomp_polycomp_t *params)
 Return the number of coefficients for the fitting polynomial used in the polynomial compression. More...
 
double pcomp_polycomp_max_error (const pcomp_polycomp_t *params)
 Return the upper bound on the error of the polynomial compression. More...
 
pcomp_polycomp_algorithm_t pcomp_polycomp_algorithm (const pcomp_polycomp_t *params)
 Return the kind of algorithm used for a polynomial compression. More...
 
double pcomp_polycomp_period (const pcomp_polycomp_t *params)
 Return the period of the input data, or a number less than or equal to 0 if the data have no periodicity. More...
 
void pcomp_polycomp_set_period (pcomp_polycomp_t *params, double period)
 Set the periodicity of the data to be compressed. More...
 
int pcomp_compress_polycomp (pcomp_polycomp_chunk_t **output_buf[], size_t *num_of_chunks, const double *input_buf, size_t input_size, const pcomp_polycomp_t *params)
 Compress the array input_buf using polynomial compression. More...
 
size_t pcomp_total_num_of_samples (pcomp_polycomp_chunk_t *const chunk_array[], size_t num_of_chunks)
 Compute the sum of the number of samples encoded in chunk_array. More...
 
int pcomp_decompress_polycomp (double *output_buf, pcomp_polycomp_chunk_t *const chunk_array[], size_t num_of_chunks)
 Decompress a sequence of chunks. More...
 
void pcomp_free_chunks (pcomp_polycomp_chunk_t *chunk_array[], size_t num_of_chunks)
 Free an array of chunks. More...
 
size_t pcomp_chunks_num_of_bytes (pcomp_polycomp_chunk_t *const chunks[], size_t num_of_chunks)
 Number of bytes required by pcomp_encode_chunks. More...
 
int pcomp_encode_chunks (void *buf, size_t *buf_size, pcomp_polycomp_chunk_t *const chunk_array[], size_t num_of_chunks)
 Encode a list of chunks into a sequence of raw bytes. More...
 
int pcomp_decode_chunks (pcomp_polycomp_chunk_t **chunk_array[], size_t *num_of_chunks, const void *buf)
 Decode a byte sequence created by pcomp_encode_chunks into an array of chunks. More...
 

Detailed Description

Polynomial compression relies on a simple idea, that is to divide the input data stream into subsets of consecutive samples (called "chunks"), and to approximate each chunk by means of a polynomial. Such compression is inherently lossy, as the residuals of the fitting procedure are usually discarded. If the polynomial used for the fitting produces residuals that are too large, usually the samples in the chunk are saved in uncompressed form.

This idea has been widely applied in the literature. Libpolycomp implements an improvement over it, because if the fit residuals are too large, the library saves a chopped sequence of the Chebyshev transform of the residuals. This allows to achieve better compression ratios in those cases where polynomial fitting is not always enough to keep compression errors below the desired threshold. This kind of compression works quite well for smooth data series, where changes between consecutive samples are well described by slowly varying continuous functions. It is not suitable if the signal contains noise, unless this noise is significantly smaller than the signal and than the error threshold.

Libpolycomp allows to avoid the usage of Chebyshev transforms. In this case, if no polynomial of the desired degree are able to fit the data with the given error threshold, the data for that chunk is saved uncompressed.

The typical workflow for applying polynomial compression is the following:

  1. Allocate a new pcomp_polycomp_t object via a call to pcomp_init_polycomp. Such object contains the parameters to be used for the compression, e.g., the size of each chunk, the degree of the fitting polynomial, whether to apply or not the Chebyshev transform to the residuals, etc.
  2. Split the data into chunks and compress each of them using the function pcomp_compress_polycomp.
  3. Convert the list of chunks into a byte sequence using pcomp_encode_chunks, typically with the purpose of saving it into a file or sending it through a pipe/socket/etc.

The decompression workflow is specular:

  1. Process the byte sequence containing the compressed data using pcomp_decode_chunks. This will produce a list of chunks that are still compressed.
  2. Decompress the chunks using the function pcomp_decompress_polycomp.

The compression functions described in this page use the pcomp_polycomp_t structure to determine which parameters to use for the compression. The functions that allow to allocate/free/manage this structure are the following:

It is possible to use a set of more low-level functions to use polynomial compression. Refer to Polynomial compression (low-level functions) for further information.

Enumeration Type Documentation

Kind of algorithm used for the polynomial compression.

See the discussion in the section Polynomial compression functions for more information.

Enumerator
PCOMP_ALG_USE_CHEBYSHEV 

When needed, apply the Chebyshev transform to the residuals of the polynomial fit.

PCOMP_ALG_NO_CHEBYSHEV 

If the absolute value of the residuals of a polynomial fit are too large, store the data in uncompressed form.

Definition at line 355 of file libpolycomp.h.

Direction of a Chebyshev transform.

Enumerator
PCOMP_TD_DIRECT 

Compute a forward Chebyshev transform, with a normalization factor 1/(N + 1)

PCOMP_TD_INVERSE 

Compute a backward Chebyshev transform, with a normalization factor equal to one.

Definition at line 320 of file libpolycomp.h.

Function Documentation

size_t pcomp_chunks_num_of_bytes ( pcomp_polycomp_chunk_t *const  chunks[],
size_t  num_of_chunks 
)

Number of bytes required by pcomp_encode_chunks.

This function computes the number of bytes required to encode the array of chunks in the variable chunks. Unlike functions like pcomp_rle_bufsize, this function provides an exact estimate, not an upper bound.

Parameters
[in]chunksArray of chunks to encode. This should have been initialized via a call to pcomp_compress_polycomp.
[in]num_of_chunksNumber of elements in chunks.
Returns
The number of bytes required for the output buffer used by pcomp_encode_chunks.

Definition at line 2138 of file poly.c.

int pcomp_compress_polycomp ( pcomp_polycomp_chunk_t **  output_buf[],
size_t *  num_of_chunks,
const double *  input_buf,
size_t  input_size,
const pcomp_polycomp_t params 
)

Compress the array input_buf using polynomial compression.

This function compresses the first input_size elements of the array input_buf using the polynomial compression scheme. The output is an array of chunks saved in output_buf (the number of elements of this array is saved in num_of_chunks). The params variable specifies the parameters used by the compression algorithm.

Here is an example showing how to compress a sequence of numbers in the variable input:

double input[] = { 1.0, 2.0, 3.0, 4.0, 3.0, 2.0,
1.0, 2.0, 6.0, 7.0, 9.0 };
size_t input_size = sizeof(input) / sizeof(input[0]);
double* decompr;
size_t decompr_size;
size_t num_of_chunks;
size_t idx;
pcomp_compress_polycomp(&chunks, &num_of_chunks, input, input_size,
params);
// Print some information for each chunk
for(idx = 0; idx < num_of_chunks; ++idx) {
printf("Chunk %lu of %lu: %s\n", idx + 1, num_of_chunks,
"compressed" : "uncompressed");
}

Once the sequence input_buf is compressed, the array of chunks can either be analyzed (e.g., using a for loop as in the example above) or encoded using the pcomp_encode_chunks. Once the variable output_buf is no longer used, it should be freed via a call to pcomp_free_chunks.

Parameters
[out]output_bufPointer to a variable that will receive the address of an array of pcomp_polycomp_chunk_t variables created by the function. Such array contains the whole set of data in input in compressed format. The array can be freed via a call to pcomp_free_chunks.
[out]num_of_chunksOn output, the variable will contain the number of chunks saved in output_buf.
[in]input_bufPointer to the array of numbers to compress.
[in]input_sizeNumber of elements in input_buf to compress.
[in]paramsParameters used for the compression. The variable must have been created via a call to pcomp_init_polycomp.
Returns
Either PCOMP_STAT_SUCCESS if no error occurred, or the error code.

Definition at line 1951 of file poly.c.

int pcomp_decode_chunks ( pcomp_polycomp_chunk_t **  chunk_array[],
size_t *  num_of_chunks,
const void *  buf 
)

Decode a byte sequence created by pcomp_encode_chunks into an array of chunks.

This function can be used to read from a binary file or a socket a sequence of chunks encoded by pcomp_encode_chunks. The function allocates memory for an array of pcomp_polycomp_chunk_t structures and returns it in the variable chunk_array. The latter variable must be freed using pcomp_free_chunks once it is no longer needed.

This function is the counterpart for pcomp_encode_chunks.

Parameters
[out]chunk_arrayPointer to an array that will contain the chunks decoded from buf.
[out]num_of_chunksOn exit, this variable will hold the number of chunks saved in chunk_array.
[in]Pointerto the byte sequence to decode.
Returns
Either PCOMP_STAT_SUCCESS if no error occurred, or the error code.

Definition at line 2287 of file poly.c.

int pcomp_decompress_polycomp ( double *  output_buf,
pcomp_polycomp_chunk_t *const  chunk_array[],
size_t  num_of_chunks 
)

Decompress a sequence of chunks.

This function is the counterpart for pcomp_compress_polycomp.

Parameters
[out]output_bufPointer to the variable that will hold the uncompressed data. It must have room for a number of elements at least equal to the return value of pcomp_total_num_of_samples.
[in]chunk_arrayArray of chunks holding the data in compressed format.
[in]num_of_chunksNumber of elements in the array chunk_array.
Returns
Either PCOMP_STAT_SUCCESS if no error occurred, or the error code.

Definition at line 2059 of file poly.c.

int pcomp_encode_chunks ( void *  buf,
size_t *  buf_size,
pcomp_polycomp_chunk_t *const  chunk_array[],
size_t  num_of_chunks 
)

Encode a list of chunks into a sequence of raw bytes.

This function transforms an array of instances to pcomp_polycomp_chunk_t variables into a sequence of raw bytes, suitable for I/O. It can be used together with pcomp_compress_polycomp to compress a dataset and save it into a binary file.

To decode byte sequences produced by this function, use pcomp_decode_chunks.

Parameters
[out]bufPointer to a memory buffer that will receive the result of the encoding. It must have room for a number of bytes (uint8_t) at least equal to the return value of pcomp_chunks_num_of_bytes.
[in,out]buf_sizeOn input, it should contain the number of bytes that can be written in buf. On exit, it will contain the number of bytes actually written. The latter number is equal to the value returned by pcomp_chunks_num_of_bytes.
[in]chunk_arrayArray of chunks to encode
[in]num_of_chunksNumber of elements in the array chunk_array.
Returns
Either PCOMP_STAT_SUCCESS if no error occurred, or the error code.

Definition at line 2193 of file poly.c.

void pcomp_free_chunks ( pcomp_polycomp_chunk_t chunk_array[],
size_t  num_of_chunks 
)

Free an array of chunks.

Parameters
[in]chunk_arrayAn array of chunks. This variable must have been allocated by a call to pcomp_compress_polycomp.
[in]num_of_chunksNumber of elements in the array chunk_array

Definition at line 2106 of file poly.c.

void pcomp_free_polycomp ( pcomp_polycomp_t params)

Free the memory allocated by pcomp_init_polycomp for a pcomp_polycomp_t structure.

Parameters
[in]paramsPointer to the structure to be freed

Definition at line 628 of file poly.c.

pcomp_polycomp_t* pcomp_init_polycomp ( pcomp_chunk_size_t  samples_per_chunk,
pcomp_poly_size_t  num_of_coeffs,
double  max_allowable_error,
pcomp_polycomp_algorithm_t  algorithm 
)

Allocate space for a pcomp_polycomp_t structure.

Parameters
[in]samples_per_chunkNumber of samples in each chunk
[in]num_of_coeffsNumber of polynomial coefficients to use
[in]max_allowable_errorUpper bound for the compression error (positive value)
[in]algorithmKind of compression algorithm to use
Returns
A pointer to the newly allocate pcomp_polycomp_t structure. This must be freed using pcomp_free_polycomp, once it is no longer used.

Definition at line 598 of file poly.c.

pcomp_polycomp_algorithm_t pcomp_polycomp_algorithm ( const pcomp_polycomp_t params)

Return the kind of algorithm used for a polynomial compression.

Parameters
[in]paramsPointer to a pcomp_polycomp_t structure containing the compression parameters
Returns
The algorithm to be used by the compressor.

Definition at line 714 of file poly.c.

double pcomp_polycomp_max_error ( const pcomp_polycomp_t params)

Return the upper bound on the error of the polynomial compression.

Parameters
[in]paramsPointer to a pcomp_polycomp_t structure containing the compression parameters
Returns
The maximum allowable error for the polynomial compression.

Definition at line 695 of file poly.c.

pcomp_poly_size_t pcomp_polycomp_num_of_poly_coeffs ( const pcomp_polycomp_t params)

Return the number of coefficients for the fitting polynomial used in the polynomial compression.

The return value has the same meaning as the value returned by the pcomp_poly_fit_num_of_coeffs.

Parameters
[in]paramsPointer to a pcomp_polycomp_t structure containing the compression parameters
Returns
The number of coefficients of the fitting polynomial.

Definition at line 677 of file poly.c.

double pcomp_polycomp_period ( const pcomp_polycomp_t params)

Return the period of the input data, or a number less than or equal to 0 if the data have no periodicity.

See also pcomp_polycomp_set_period.

Parameters
[in]paramsPointer to a pcomp_polycomp_t structure containing the compression parameters
Returns
The periodicity. If zero or negative, no periodicity is assumed in the data to be compressed.

Definition at line 773 of file poly.c.

pcomp_chunk_size_t pcomp_polycomp_samples_per_chunk ( const pcomp_polycomp_t params)

Return the number of samples per chunk.

This function returns the size of each chunk but the last one in the input data for a polynomial compression. Such chunks contain a set of consecutive values in the input array passed to routines as pcomp_compress_polycomp.

Parameters
[in]paramsPointer to a pcomp_polycomp_t structure containing the compression parameters
Returns
The number of samples in each chunk.

Definition at line 655 of file poly.c.

void pcomp_polycomp_set_period ( pcomp_polycomp_t params,
double  period 
)

Set the periodicity of the data to be compressed.

If period is a value greater than zero, this is assumed to be the periodicity of the input data: the value x is therefore assumed equivalent to x + period and to x - period. It is typically a multiple of Pi = 3.14159...

The polynomial compressor can improve the compression ratio for data if they have some form of periodicity.

Parameters
[in]paramsPointer to a pcomp_polycomp_t structure containing the compression parameters
[in]periodThe periodicity of the data, or a zero/negative value if no periodicity should be assumed by the compressor.

Definition at line 799 of file poly.c.

size_t pcomp_total_num_of_samples ( pcomp_polycomp_chunk_t *const  chunk_array[],
size_t  num_of_chunks 
)

Compute the sum of the number of samples encoded in chunk_array.

Parameters
[in]chunk_arrayArray of pcomp_polycomp_chunk_t variables. Typically, such array is created via a call to pcomp_compress_polycomp.
[in]num_of_chunksNumber of elements in chunk_array
Returns
The overall number of samples encoded in the sequence of chunks

Definition at line 2022 of file poly.c.