Re: [ng-spice] Kernel
I have looked at the proposed API. Some of the remarks I have, I put
inside comments in the source. It looks promising.
--
Arno
/**************/
/* si_units.h */
/**************/
/* Enum for SI units */
enum si_units {SECOND, METER, KILOGRAM, AMPERE};
/* IMPORTANT NOTE: unit_t needs to be a signed type to allow units to
have negative dimensions. */
typedef char unit_t;
/* Some basic units */
unit_t scalar_unit[SI_UNITS] = {0, 0, 0, 0};
unit_t time_unit[SI_UNITS] = {1, 0, 0, 0};
unit_t distance_unit[SI_UNITS] = {0, 1, 0, 0};
unit_t mass_unit[SI_UNITS] = {0, 0, 1, 0};
unit_t current_unit[SI_UNITS] = {0, 0, 0, 1};
unit_t frequency_unit[SI_UNITS] = {-1, 0, 0, 0};
/************/
/* sample.h */
/************/
include "si_units.h"
typedef sample_t double;
enum data_t { REAL, COMPLEX }; /* Type of data */
typedef struct sample {
int size; /* Length of the sample */
char *units; /* Physical measurement units */
enum data_t data_type; /* Type of data */
sample_t *data; /* Has size SIZE */
} SAMPLE;
typedef struct measurement {
char *name; /* Measurement name */
unit_t type; /* Type of measurement */
int id; /* ID of measurement */
int count; /* Number of dependent variables */
struct sample *indep; /* Independent variables (complex) */
struct sample *data; /* Dependent variables */
} MEASUREMENT;
/* Functions to create & destroy a sample */
/* units and data_type can be set to a NOT_VALID value to ensure
correctness; data is not zeroed, use sample_zero instead, if
necessary. */
SAMPLE *sample_malloc(int size);
SAMPLE *sample_copy(SAMPLE *);
/* Define various fieds of SAMPLE * */
int sample_define_units(SAMPLE *, unit_t *units);
int sample_define_type(SAMPLE *, enum data_t type);
/* Do not know if it is useful to have a clear function and a destroy
* function for samples. The second one should be sufficient. */
void sample_zero(SAMPLE *);
void sample_free(SAMPLE *);
/* Functions for creating independent variable ranges */
/* Null pointer returned means operation failure */
/* Range functions.
*
* start: initial value
* stop: end value
* step: increment
*
* Constraints:
*
* (start < stop && step > 0) || (start > stop && step < 0)
* data_type REAL */
SAMPLE *sample_linear_range(sample_t start, sample_t stop, sample_t step);
SAMPLE *sample_decadic_range(sample_t start, sample_t stop, sample_t step);
SAMPLE *sample_octave_range(sample_t start, sample_t stop, sample_t step);
/* Now some functions to do math on samples */
/* The operations are:
* sum: a = a + b
* subtraction: a = a - b
* multiplication: a = a * b
* division: a = a / b (each b(i) must be <> 0)
* absolute value a = abs(a) (for real numbers).
* deciBel
* unary negation
*
* IMPORTANT: samples length must be equal; non-zero return value
* indicates error. */
int sample_add(SAMPLE *a, SAMPLE *b);
int sample_sub(SAMPLE *a, SAMPLE *b);
int sample_mul(SAMPLE *a, SAMPLE *b);
int sample_div(SAMPLE *a. SAMPLE *b);
int sample_abs(SAMPLE *a);
int sample_neg(SAMPLE *a);
/* What is this supposed to do? */
int sample_dB(SAMPLE *a);
/* Same as before but the results of operations will be put in a new
* sample: c = a + b, ... . "cr" stands for create.
*
* IMPORTANT: samples length must be equal; NULL return value
* indicates error. */
/* These functions can be implemented using sample_copy() and the
two-sample variants of the same functionality. */
SAMPLE *sample_cr_add(SAMPLE *a, SAMPLE *b);
SAMPLE *sample_cr_sub(SAMPLE *a, SAMPLE *b);
SAMPLE *sample_cr_mul(SAMPLE *a, SAMPLE *b);
SAMPLE *sample_cr_div(SAMPLE *a, SAMPLE *b);
SAMPLE *sample_cr_abs(SAMPLE *a);
SAMPLE *sample_cr_dB(SAMPLE *a);
SAMPLE *sample_cr_neg(SAMPLE *a);
/* Now some functions for complex numbers, */
/* result will be put into the first sample */
int sample_modulus(SAMPLE *real_part, SAMPLE *imaginary_part);
int sample_phase(SAMPLE *real_part, SAMPLE *imaginary_part);
/* ... and the three vectors versions */
SAMPLE *sample_cr_modulus(SAMPLE *real_part, SAMPLE *imaginary_part);
SAMPLE *sample_cr_phase(SAMPLE *real_part, SAMPLE *imaginary_part);
Partial thread listing: