/* PZT_poze.h API specifying POZE objects and their manipulations/calculations. PoZeTools v 0.53, december 19, 2006. Copyright (c) 2002-2006 Pieter Suurmond. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. Any person wishing to distribute modifications to the Software is requested to send the modifications to the original developer so that they can be incorporated into the canonical version. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. This header needs PZT_complexMath.h to be included prior to this file. String functions to read and write complex numbers from and to text format. Structure definitions for Z-plane, time-domain and complex arrays. File I/O functions. */ typedef struct { complexPolar gain; /* Only gain is in POLAR format! */ cartesian_array zero; cartesian_array pole; } POZE; /*----------------------------------------------------------------------------*/ /* Reads ASCII file 'filename', line by line, if the first argument is zero. It reads from the second argument itself if the first argument is non-zero. Empty lines and lines that start with a '#' are ignored. Whitespace and tabs are ignored as well. A (complex) gain may be given and a number of poles and zero. Both polar and cartesian notations are accepted. Case and the order does not matter. Only one gain, pole, or zero per line. Not more than 1 gain may be given. If no gain is specified, the system will be normalized by the software. For example: Z = 4j - 0.6 G = 2.5 j z = -j P = 0.92 exp (0.5 pi j) p = exp (2j) See file 'poze.ebnf' for a formal description of the PoZeTools syntax. Also see example input file 'x.poze'. Returns NULL pointer on failure. On success memory structures were allo- cated. These should be released after use by 'free_frequency_domain()'. Diagnostics are written to 'msg' which must point to enough memory space. If argument 'msg' is NULL, the function immediately returns NULL. */ int POZE_read(POZE** pz, short content, /* 0 if next arg is filename. */ const char* filename_or_content, char* msg); /*----------------------------------------------------------------------------*/ /* Free memory after succesfully calling 'read_frequency_domain()'. */ void POZE_free(POZE** pz); /*----------------------------------------------------------------------------*/ /* Outputs to an already opended stream, all poles and zeroes and the gain. It may write to 'stdout', or to a testfile. Returns zero on success, nonzero on failure. Middle argument 'stamp' may be null. */ int POZE_write(const POZE* pz, /* Supply P, Z and G here. */ const char* stamp, /* Printed as comment (in the file). */ FILE* dest); /* Destination to write to. */ /*----------------------------------------------------------------------------*/ /* Calculates the response, given a set of poles, zeros, a gain and certain z. Writes the result in polar form to *H_p. Be aware that the phase-result is INVALID when magnitude is zero (it may say the angle is zero because atan() for zero magnitude yields a zero angle, but actually, the angle is undefined or may be calculated by lim w->... */ void POZE_response(const POZE *pz, /* Z=, P=, G=. */ const complexCartesian *z_c, /* Frequency. */ complexPolar *H_p); /* Response. */ /*----------------------------------------------------------------------------*/ typedef struct { double min_magnitude; double max_magnitude; double min_angle; double max_angle; double start_omega; /* Initial input phase. */ double start_angle; /* Output phase for unwrapper. */ double min_time; double max_time; } response_range; /*----------------------------------------------------------------------------*/ /* Tries to find minima and maxima of magnitude and phase (both angle and time) of the supplied system 'pz'. It searches from 0 to PI inclusive. Writes found values into struct 'r_range'. Is used for autozooming. v0.53: For time, some (very negative values) are disregarded. Introduced a time-bottom-clip, based on the causality of the system: the number of poles - the number of zeros. And also a time-top-clip... */ void POZE_response_range(const POZE* pz, response_range* r_range); /*----------------------------------------------------------------------------*/ /* Returns 1 if the given Z-plane (P,Z,G) describes a causal system. Returns 0 if it's a non-causal filter. */ int POZE_causal(const POZE *pz); /*----------------------------------------------------------------------------*/ /* Returns 1 if given poles and zeros represents a finite impulse response system. Returns 0 if it's an infinite impulse response filter. */ int POZE_fir(const POZE *pz); /*----------------------------------------------------------------------------*/ /* Returns 1 if the filter is stable (no poles on or outside unit circle). Returns 0 if the filter is unstable. Call this function before evaluating any response fomula! */ int POZE_stable(const POZE *pz); /*----------------------------------------------------------------------------*/ /* Tests for pole-zero cancellation. When argument 'doit' is nonzero, poles and zeros may be actually removed from the arrays as well. Returns the number of cancelled pairs. Called by function process() in cgi/nph-PZT.cgi.c and by function poze() in PZT.c. */ int POZE_cancelled(POZE* pz, /* Supply poles, zeros and gain here. */ double e, /* Distance below we cancel. */ short doit); /* Only check or really remove? */ /*----------------------------------------------------------------------------*/ /* Test if system is normalized, and when argument 'doit' is nonzero it actually normalizes the system, so its' maximum output becomes 1.0. The gain must be nonzero before calling 'normalize()' in case 'doit' is not set. Returns 1 if system was normalized, 0 if not. */ int POZE_normalized(POZE *pz, short doit);