// -*- C++ -*-
// automatically generated by autodoc

// ========== HEADER FILE src/aux1/applyfunc.h: ==========

inline void apply_func(Type *f, ulong n, Type (*func)(Type));
// apply func to each element of f[]

inline void apply_func(Type *f, ulong n, Type (*func)(Type, Type), const Type *g);
// set f[k] = func(f[k], g[k])  for all k

inline void apply_idx_func(Type *f, ulong n, Type (*func)(Type, ulong));
// set f[k] = func(f[k], k)  for all k

inline void apply_idx_func(Type *f, ulong n, Type (*func)(Type, Type, ulong), const Type *g);
// set f[k] = func(f[k], g[k], k)  for all k

inline void val2idxvec_func(const Type *f, ulong n, ulong (* func)(Type), ulong *x);
// for all k set  x[k] = func(f[k])
// (e.g. for computing a delta sequence wrt. to some condition)

inline void idxvec2val_func(const ulong *x, ulong n, Type (* func)(ulong), Type *f);
// for all k set  f[k] = func(x[k])
// (e.g. for tabulating a function (in math sense) for permuted values)

inline void idx2val_func(Type *f, ulong n, Type (* func)(Type), Type x0=0, Type x1=1);
// for all k set  f[k] = func( x0 + k*((x1-x0)/(n-1)) )
// (e.g. for tabulating a function (in math sense) from x0 to x1)

// ========== HEADER FILE src/aux1/arith1.h: ==========

inline Type sum(const Type *f, ulong n);
// return \sum_k {f[k]}

inline Type mean(const Type *f, ulong n);
// return (\sum_k{f[k]})/n

inline Type subtract_mean(Type *f, ulong n);
// subtract from f[] its mean value
// return mean value

inline Type scalar_product(const Type *f, ulong n);
// return \sum_k {f[k]*f[k]}

inline Type scalar_product(const Type *f, const Type *g, ulong n);
// return \sum_k {f[k]*g[k]}

inline Type sum_of_squares(const Type *f, ulong n);
// return \sum_k {f[k]*f[k]}

inline Type sqr_diff(const Type *f, const Type *g, ulong n);
// return \sum_k { (f[k]-g[k])^2 }

inline void delta(Type *f, ulong n, ulong d, Type v=1);
// set array to delta(d0) (i.e. v at index d, zero else)

inline ulong test_delta(const Type *f, ulong n, Type *vp=0);
// if f[] is a delta sequence then
//   return index 0<=i<n where f[i]!=0
// else
//  return ~0
//
// if vp!=0 then
//   set vp to the value of the delta pulse
//   set vp to zero is sequence is no delta sequence

inline Type delta_sqr_diff(const Type *f, ulong n, ulong d0, Type v=1);
// return \sum { (f[]-delta(d0) )^2 }

inline void negate(Type *f, ulong n);
// negate every element of f[]

inline void add_val(Type *f, ulong n, Type s);
// f[] += g

inline void subtract_val(Type *f, ulong n, Type s);
// f[] -= g

inline void multiply_val(Type *f, ulong n, Type s);
// f[] *= s

inline void add(Type *f, ulong n, const Type *g);
// f[] += g[] element-wise

inline void subtract(Type *f, ulong n, const Type *g);
// f[] -= g[] element-wise

inline void multiply(Type *f, ulong n, const Type *g);
//  f[] *= g[] element-wise

inline void divide(Type *f, ulong n, const Type *g);
//  f[] /= g[] element-wise  (no check for overflow !)

// ========== HEADER FILE src/aux1/array.h: ==========

class array;

void copy(const array<Type> &src, array<Type> &dst);

void copy(const array<Type> &src, Type *dst);
// assuming dst[] has compatible length

void copy(const Type *src, array<Type> &dst);
// assuming dst[] has compatible length

// ========== HEADER FILE src/aux1/aux1double.h: ==========

// ----- SRCFILE=src/aux1/aux1double.cc: -----
void chop(double *f, ulong n, double eps/*=1e-6*/);
// set tiny elements to zero

double norm(const double *f, ulong n);
// return sqrt(\sum_k{f[k]*f[k]})

double normalize(double *f, ulong n, double v/*=1.0*/);
// scale f[] to norm v

double sigma(const double *f, ulong n, double *mp/*=0*/);
// return standard deviation
// = sqrt(\sum_k{sqr(f[k]-mean(f[]))}/n)

void mean_sigma(const double *f, ulong n, double *mp, double *sp);
// set *mp to mean, sp *to standard deviation of f[]

void smooth(double *f, ulong n, ulong m/*=1*/);
//  apply (1/4,1/2,1/4) - filter

double rms_diff(const double *f, const double *g, ulong n);
// return sqrt(\sum_k{sqr(f[k]-g[k])})/n

ulong * histogram(const double *f, ulong n, ulong nbox, ulong *hh/*=0*/);
// put histogram of f[] (with nbox boxes) into hh[]

void welch_win(double *f, ulong n);
// multiply f[] with a welch window
// Note: should use trig recursion here

void ri_multiply(const double *fr, const double *fi,
            double *gr, double *gi, ulong n);
// complex multiply array g[] by f[]:
//  Complex(gr[],gi[]) *= Complex(fr[],fi[])

// ========== HEADER FILE src/aux1/auxprint.h: ==========

// ----- SRCFILE=src/aux1/auxprint.cc: -----
void print(const char *bla, const double *f, ulong n, double eps/*=0.0*/);

void print_twodim(const char *bla, const double *f, ulong r, ulong c, double eps/*=0.0*/);

// ----- SRCFILE=src/aux1/graphprint.cc: -----
void graph_print(const char *bla, const double *f, ulong n, ulong width/*=60*/, double eps/*=0.0*/);

// ========== HEADER FILE src/aux1/bytescan.h: ==========

// ----- SRCFILE=src/aux1/bytescan.cc: -----
ulong long_strlen(const char *str);
// Return length of string starting at str.
// Might be a win on 64-bit machines

// ========== HEADER FILE src/aux1/copy.h: ==========

inline void memzero(Type *dst, ulong n);
// Set array (memory) to zero (bytes).

inline void fill(Type *dst, ulong n, Type v);
// Fill array with value v

inline void null(Type *dst, ulong n);
// Set array to zero.
// If the element zero consists of zero bytes only,
// then prefer memzero().

inline void memcopy(const Type *src, Type *dst, ulong n);
// Copy array (memory) src[] to dst[]

inline void copy(const Type *src, Type *dst, ulong n);
// Copy array src[] to dst[]

inline void copy_cast(const Type1 *src, Type2 *dst, ulong n);
// Copy array src[] to dst[]

inline void copy0(const Type1 *src, ulong ns, Type2 *dst, ulong nd);
// Copy as much as makes sense, fill rest with zeros
// from src[] (length ns) to dst[] (length nd):

inline void copy_cyclic(const Type *src, Type *dst, ulong n, ulong s);
// Copy array src[] to dst[]
// starting from position s in src[]
// wrap around end of src[]  (src[n-1])
//
// src[] is assumed to be of length n
// dst[] must be length n at least
//
// Equivalent to:  { copy(src, dst, n); rotate_right(dst, n, s)}

inline void copy_reverse(const Type *src, Type *dst, ulong n);
// Copy array reversed:
// dst[] <-- reverse(f[])

inline void copy_reverse_0(const Type *src, Type *dst, ulong n);
// Copy array reversed around index 0:
// dst[] <-- reverse_0(f[])

inline void skip_copy(const Type *src, Type *dst, ulong n, ulong d);
// Copy n elements from src[] at positions
//   [0],[d],[2d],[3d],...,[(n-1)*d]
//   to dst[0, 1, ..., n-1]

inline void skip_copy_back(const Type *src, Type *dst, ulong n, ulong d);
// Copy n elements from src[0, 1, ..., n-1]
//   to dst[] at positions
//   [0],[d],[2d],[3d],...,[(n-1)*d]

inline void swap(Type *f, Type *g, ulong n);
// Swap arrays

inline void swap_reverse(Type *f, Type *g, ulong n);
// Swap arrays reversed:
// f[] <-- reverse(g[])
// g[] <-- reverse(f[])

inline void set_seq(Type *dst, ulong n, Type start=0, Type step=1);
// Fill array with sequence
//   start, start+step, start+2*step, ...

inline bool is_seq(const Type *dst, ulong n, Type start=0, Type step=1);
// Check whether array elemnts are the sequence
//   start, start+step, start+2*step, ...
// (as filled in by set_seq(dst, n, start, step)

inline long compare(const Type1 *f, const Type2 *g, ulong n);
// Compare sequences, return 0 if both are identical.
// If a difference is detected, the return +-(k+1)
//  where k is the index so that  f[k]!=g[k]
//  and the sign is positive if f[k]>g[k], else negative.

// ========== HEADER FILE src/aux1/diff.h: ==========


//  in  =  (sqr func in [0...6])
//    0-        +4
//    1-     +7.84
//    2-    +12.96
//    3-    +19.36
//    4-    +27.04
//    5-       +36
//
//  apply diff:
//    0-        +4 <-- unchanged
//    1-     +3.84
//    2-     +5.12
//    3-      +6.4
//    4-     +7.68
//    5-     +8.96
//
//  apply diff:
//    0-        +4 <-- unchanged
//    1-     +3.84 <-- unchanged
//    2-     +1.28
//    3-     +1.28
//    4-     +1.28
//    5-     +1.28
//
//  apply anti_diff:
//    0-        +4 <-- unchanged
//    1-     +3.84 <-- unchanged
//    2-     +5.12
//    3-      +6.4
//    4-     +7.68
//    5-     +8.96
//
//  apply anti_diff: (got back original)
//    0-        +4 <-- unchanged
//    1-     +7.84
//    2-    +12.96
//    3-    +19.36
//    4-    +27.04
//    5-       +36

inline void diff(Type *f, ulong n, ulong j=1);
// first difference (applied j times) of f[]
// element zero ('integration constant' is preserved) in each pass

inline void anti_diff(Type *f, ulong n, ulong j=1);
// inverse of diff()

inline void diff(Type *f, ulong n, Type (*func)(Type, Type), ulong j=1);
// func on pairs (applied j times) applied to  f[] (result into right 'operand')
// element zero ('integration constant' is preserved) in each pass.
//
// With  Type func(Type a, Type b)  { return a-b; }  this is identical to
// the 'simple' diff()

inline void anti_diff(Type *f, ulong n, Type (*func)(Type, Type), ulong j=1);
// inverse of diff()
// ... whith appropriate 'inverse' func of course:
// if  func used in diff() is df with  df(a, b) =: x
// then func in anti_diff() af must be so that:  af(x, b) == a
// that is:
//  af(df(a, b), b) == a  for all a, b  (e.g. (a-b) + b == a)
// equivalently:
//  df(af(a, b), b) == a  for all a, b  (e.g. (a+b) - b == a)
//
// With  Type func(Type a, Type b)  { return a+b; }  this is identical to
// the 'simple' anti_diff()

// ========== HEADER FILE src/aux1/grsnegate.h: ==========

void grs_negate(Type *f, ulong n);
// Negate elements at indices where the Golay-Rudin-Shapiro is negative.

// ========== HEADER FILE src/aux1/resample.h: ==========

// ----- SRCFILE=src/aux1/resample.cc: -----
ulong resample_sinc(const double *a, ulong an, double af, double *b, double bf, ulong bn);
// Input: an samples with freq af.
// Output: bn samples with freq bf.
// Return number of samples produced (<=bn).

ulong sample_up_linear(const double *f, ulong nf, double v, double *g, ulong ng);
// Uses linear interpolation (if noninteger v).
// Return number of values produced.

ulong sample_down_linear(const double *f, ulong nf, double v, double *g, ulong ng);
// Uses linear interpolation (if noninteger v).
// Return number of values produced.

ulong resample_linear(const double *f, ulong nf, double v, double *g, ulong ng);
// Use linear interpolation (if noninteger v).
// Return number of values produced.

// ========== HEADER FILE src/aux1/scale.h: ==========

void linear_scale(Type *f, ulong n,;
                  Type mi, Type ma,     // old min, max
                  Type nmi, Type nma)   // new min, max
// linear scale so that
//   new_min==nmi,  ne_max==nma
// supply (or pretend) old min and max

void linear_scale(Type *f, ulong n,;
                  Type nmi, Type nma)   // new min, max
// linear scale so that
//   new_min==nmi,  ne_max==nma

void log_scale(Type *f, ulong n,;
               double xi, double xa,
               Type nma)

// ========== HEADER FILE src/aux1/scanbox.h: ==========

ulong first_ge_sumbox_idx(const Type *f, ulong n, Type v, ulong boxlen);
// Find first box of length boxlen for which sum of the elements is >=v.
// Return index of first element of that box.
// Return n if no such box is found.

ulong last_ge_sumbox_idx(const Type *f, ulong n, Type v, ulong boxlen);
// Find last box of length boxlen for which sum of the elements is >=v.
// Return index of first element of that box.
// Return n if no such box is found.
// Add boxlen-1 to the result to get end of the box.

ulong first_le_sumbox_idx(const Type *f, ulong n, Type v, ulong boxlen);
// Find first box of length boxlen for which sum of the elements is <=v.
// Return index of first element of that box.
// Return n if no such box is found.

ulong last_le_sumbox_idx(const Type *f, ulong n, Type v, ulong boxlen);
// Find last box of length boxlen for which sum of the elements is <=v.
// Return index of first element of that box.
// Return n if no such box is found.
// Add boxlen-1 to the result to get end of the box.

// ========== HEADER FILE src/aux1/shift.h: ==========

inline void shift_left(Type *f, ulong n, ulong s);
// shift towards element #0

inline void shift_right(Type *f, ulong n, ulong s);
// shift away from element #0

inline void shift_sgn(Type *f, ulong n, long s);
// positive s --> shift away from element zero

// ========== HEADER FILE src/aux1/symmetry.h: ==========

// ----- SRCFILE=src/aux1/symmetry.cc: -----
int symm_q(const double *f, ulong n, double eps/*=1e-5*/);
// check symmetry  k <--> n-1-k  (k=0..n-1)
// return:
//    0: no symmetry
//    1: symmetry
//   -1: neg. symm.

int symm_0_q(const double *f, ulong n, double eps/*=1e-5*/);
// check symmetry  k <--> n-k  (k=1..n/2-1)

int any_symm_q(const double *f, ulong n, double eps/*=1e-5*/);

void symm_0(double *f, ulong n, int s=+1);
// make symmetric  k <--> n-k  (k=1..n/2-1)

void symm(double *f, ulong n, int s=+1);
// make symmetric  k <--> n-1-k  (k=1..n/2-1)

// ========== HEADER FILE src/aux1/wordgray.h: ==========


// Gray code (and reversed Gray code) over GF(2**n)
// cf. bits/graycode.h and bits/graypower.h

void word_gray(Type *f, ulong n);

void inverse_word_gray(Type *f, ulong n);

void word_gray_pow(Type *f, ulong n, ulong x);
// result is identical to
//   for (ulong k=0; k<x; ++k)  word_gray(f, n);
// Work <= n/2

void word_rev_gray(Type *f, ulong n);

void inverse_word_rev_gray(Type *f, ulong n);

void word_rev_gray_pow(Type *f, ulong n, ulong x);
// result is identical to
//   for (ulong k=0; k<x; ++k)  word_rev_gray(f, n);
// work <= n/2

