#ifndef pz_double_chain_H #define pz_double_chain_H /* Sequences (possibly periodic) of {double}s --- times, labels, curvatures, etc. */ /* Last edited on 2015-01-20 16:48:58 by stolfilocal */ #include #include #include typedef double_vec_t pz_double_chain_t; /* A {pz_double_chain_t} is a sequence,open or closed, of arbitrary double values. If closed, the elements may be samples from a periodic function, or from the integral of a periodic function. */ /* BASIC MANIPULATION */ /* The {DoXXX} procedures below are analogous to the {XXX} procedures, except that the result is returned in an array provided by the client (which must have the correct size). */ pz_double_chain_t pz_double_chain_cut ( pz_double_chain_t *c, unsigned start, unsigned length ); /* Returns a new {pz_double_chain_t} containing {length} consecutive samples of chain {c}, beginning with {c[start]}. Assumes that the chain is periodic, i.e. the samples may wrap around to the beginning of {c}, i.e. {c[i+c.ne]==c[i]} for all {i}. */ void pz_double_chain_do_cut ( pz_double_chain_t *c, unsigned start, unsigned length, pz_double_chain_t *x ); /* Same as {pz_double_chain_do_cut} but stores the selected samples in the chain {*t}, which must have been previously allocated with {t.ne == length}. */ void pz_double_chain_reverse ( pz_double_chain_t *c ); /* Reverses the chain {c} back-to-front. */ void pz_double_chain_complement ( pz_double_chain_t *c ); /* Negates all the elements of {c}. */ pz_double_chain_t pz_double_chain_extract_segment ( pz_double_chain_t *c, pz_segment_t s, bool_t curvature ); /* Extracts the specified segment of chain {c}, assumed periodic, as a new chain. If {s.rev} is TRUE, also reverses the extracted segment; in that case, if {curvature} is TRUE, also negates all its elements. */ void pz_double_chain_do_extract_segment ( pz_double_chain_t *c, pz_segment_t s, bool_t curvature, pz_double_chain_t *t ); /* Same as {pz_double_chain_t}, but stores the extracted segment in the chain {*t}, which must have been previously allocated with {t.ne == s.ns}. */ /* INTEGRAL-PERIODIC FUNCTIONS */ /* The procedures in this section interpret a chain {c} as a continuous function {c(x)} that is the integral of some non-negative periodic function {f(x)} with period {m == (c.ne)}. Specifically, the procedures assume that (1) {c[i]} is the integral of {f(x)} from an arbitrary parameter {x == x0} to parameter {x == i}; (2) {stride} is the integral of {f(x)} over a whole period, so that {c(x + m) == c(x) + stride}, for any {x}; and (3) {c(x)} is linear (i.e., {f(x)} is constant) between successive integer values of the argument {x}. */ double pz_double_chain_delta ( pz_double_chain_t *c, double stride, int ini, int fin ); /* Returns {c(fin) - c(ini)}, where the chain {c} is implicitly extended as explained above. */ double pz_double_chain_value_from_arg ( pz_double_chain_t *c, double stride, double x ); /* Returns {c(x)}; that is, a value {y} such that {c[floor(x)] <= y <= c[ceiling(x)]}, interpolating linearly between these two points. The chain {c} is implicitly extended as explained above. */ double pz_double_chain_arg_from_value ( pz_double_chain_t *c, double stride, double y ); /* Returns a fractional argument {x} such that {c(x) == y}; that is, such that {c[floor(x)] <= y <= c[ceiling(x)]}, with linear interpolation between these two points. The chain {c} is implicitly extended as explained above. */ void pz_double_chain_values_from_args ( pz_double_chain_t *c, double stride, double_vec_t *x, double_vec_t *y ); /* Sets {y[i] = pz_double_chain_value_from_arg(c, stride, x[i])} for all {i}. */ void pz_double_chain_args_from_values ( pz_double_chain_t *c, double stride, double_vec_t *y, double_vec_t *x ); /* Sets {x[i]} to {pz_double_chain_arg_from_value(c, stride, y[i])} for every i, but faster if {y} is sorted. */ double pz_double_chain_value_from_value ( pz_double_chain_t *a, double aStride, pz_double_chain_t *b, double bStride, double ya ); /* Finds the value {yb} of function {b(x)} for an argument {x} such that the function {a(x)} has value {ya}. The chains {a} and {b} are implicitly extended as explained above. */ double pz_double_chain_arg_from_arg ( pz_double_chain_t *a, double aStride, pz_double_chain_t *b, double bStride, double xa ); /* Finds an argument {xb} such that {b(xb) == a(xa)}, where {xa} is given. The chains {a} and {b} are implicitly extended as explained above. */ pz_segment_t pz_double_chain_map_segment ( pz_segment_t *sOld, pz_double_chain_t *tOld, pz_double_chain_t *tNew, double stride ); /* Maps a segment of a sampled function to another version of the same function (presumably filtered at different scales and/or resampled with different times). The procedure assumes that corresponding points of the two chains have the same parameter {t}. They assume that sample {i} of eacg chain has parameter value {tOld[i]} or {tNew[i]}, respectively; and that both versions are periodic, with same period {stride}. */ /* INPUT/OUTPUT */ double pz_double_chain_adjust_unit ( double givenUnit, pz_double_chain_t *c ); /* Adjusts the {givenUnit} if needed to avoid overflow or excessive error when quantizing the values in {c}. May print warnings to {stderr}. */ void pz_double_chain_write ( FILE *wr, char *cmt, pz_double_chain_t *c, double stride, double unit ); /* Writes chain {c} to {wr}, prefixed with comments {cmt} and the given {stride}. The samples will be written as integer multiples of the given {unit}. */ typedef struct pz_double_chain_read_data_t { char *cmt; /* Comments */ unsigned samples; /* Number of samples in chain. */ pz_double_chain_t c; /* Times, values, etc. */ double stride; /* Period, total length, etc; 0 if not applicable. */ double unit; /* Unit used when recording the samples */ } pz_double_chain_read_data_t; pz_double_chain_read_data_t pz_double_chain_read ( FILE *rd, bool_t header_only ); /* pz_double_chain_reads a chain from {rd}. If {header_only==TRUE}, reads only the parameters, and leaves the {c} field as NULL. */ typedef struct pz_double_chain_read_all_data_t { pz_double_chain_read_data_t *chData; double unitMin; /* Minimum quantization unit. */ double unitMax; /* Maximum quantization unit. */ char *cmt; /* Comment of first chain, if any. */ } pz_double_chain_read_all_data_t; pz_double_chain_read_all_data_t pz_double_chain_read_all ( char *prefix, unsigned band, char *extension, bool_vec_t *sel, bool_t header_only, char *dir /* default was "." */ ); /* Reads a set of numbered chains, returns a {pz_double_chain_read_all_data_t} record {r}. Chain number {i} is read if and only if {sel[i] == TRUE}, and its {pz_double_chain_read_data_t} is stored in {r.chain[i]}; otherwise {r.chain[i] } is set to a record with null {c} field. The data is read from file "{DDD}/{KKKK}/{PPP}{BBB}{EEE}", where {DDD} is the directory {dir}, {KKKK} is the chain number {k} (4 digits, zero padded), {PPP} is the given {prefix}, {BBB} is the {band} number (3 digits, zero padded), and {EEE} is the given {extension}. If {header_only} is TRUE, only the header of each file is read; the {c} fields are all set to NULL. The range of quantization {unit}s of the chains that were read is returned in {r.unitMin}, {r.unitMax}. The comment of the first chain read, plus the call arguments, are stored in {r.cmt}. */ /* Copyright © 2001 Universidade Estadual de Campinas (UNICAMP). Authors: Helena C. G. Leitão and Jorge Stolfi. This file can be freely distributed, used, and modified, provided that this copyright and authorship notice is preserved, and that any modified versions are clearly marked as such. This software has NO WARRANTY of correctness or applicability for any purpose. Neither the authors nor their employers chall be held responsible for any losses or damages that may result from its use. */ #endif