* src/include/complex.h, src/include/macros.h,

src/include/memory.h, src/maths/sparse/spdefs.h: Moved definitions
        of complex into complex.h.  There are three different ways to
        declare a complex number in Spice.  We need further work to reduce
        this to only one.

        * src/maths/cmaths/Makefile.am, src/maths/cmaths/.cvsignore,
        src/maths/cmaths/test_cx_ph.c:  Added a new test and updated the
        corresponding support files.
This commit is contained in:
arno 2000-06-03 12:08:35 +00:00
parent 7e88315320
commit 1025e978bc
8 changed files with 369 additions and 107 deletions

View File

@ -1,3 +1,15 @@
2000-06-03 Arno W. Peters <A.W.Peters@ieee.org>
* src/include/complex.h, src/include/macros.h,
src/include/memory.h, src/maths/sparse/spdefs.h: Moved definitions
of complex into complex.h. There are three different ways to
declare a complex number in Spice. We need further work to reduce
this to only one.
* src/maths/cmaths/Makefile.am, src/maths/cmaths/.cvsignore,
src/maths/cmaths/test_cx_ph.c: Added a new test and updated the
corresponding support files.
2000-06-02 Arno W. Peters <A.W.Peters@ieee.org>
* src/circuit/inp2dot.c: Refactoring introduced a bug in the line

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1985 Thomas L. Quarles
* Modified: Paolo Nenzi 1999, Arno W. Peters 2000
* Modified: 1999 Paolo Nenzi, 2000 Arno W. Peters
*/
#ifndef _COMPLEX_H
#define _COMPLEX_H
@ -18,8 +18,7 @@ typedef struct _complex complex;
#define imagpart(cval) ((struct _complex *) (cval))->cx_imag
/* header file containing definitions for complex functions
*
/*
* Each expects two arguments for each complex number - a real and an
* imaginary part.
*/
@ -28,6 +27,61 @@ typedef struct {
double imag;
} SPcomplex;
/*
* COMPLEX NUMBER DATA STRUCTURE
*
* >>> Structure fields:
* Real (RealNumber)
* The real portion of the number. Real must be the first
* field in this structure.
* Imag (RealNumber)
* The imaginary portion of the number. This field must follow
* immediately after Real.
*/
#define spREAL double
/* Begin `RealNumber'. */
typedef spREAL RealNumber, *RealVector;
/* Begin `ComplexNumber'. */
typedef struct
{ RealNumber Real;
RealNumber Imag;
} ComplexNumber, *ComplexVector;
/* Some defines used mainly in cmath.c. */
#define alloc_c(len) ((complex *) tmalloc((len) * sizeof (complex)))
#define alloc_d(len) ((double *) tmalloc((len) * sizeof (double)))
#define FTEcabs(d) (((d) < 0.0) ? - (d) : (d))
#define cph(c) (atan2(imagpart(c), (realpart(c))))
#define cmag(c) (sqrt(imagpart(c) * imagpart(c) + realpart(c) * realpart(c)))
#define radtodeg(c) (cx_degrees ? ((c) / 3.14159265358979323846 * 180) : (c))
#define degtorad(c) (cx_degrees ? ((c) * 3.14159265358979323846 / 180) : (c))
#define rcheck(cond, name) if (!(cond)) { \
fprintf(cp_err, "Error: argument out of range for %s\n", name); \
return (NULL); }
#define cdiv(r1, i1, r2, i2, r3, i3) \
{ \
double r, s; \
if (FTEcabs(r2) > FTEcabs(i2)) { \
r = (i2) / (r2); \
s = (r2) + r * (i2); \
(r3) = ((r1) + r * (i1)) / s; \
(i3) = ((i1) - r * (r1)) / s; \
} else { \
r = (r2) / (i2); \
s = (i2) + r * (r2); \
(r3) = (r * (r1) + (i1)) / s; \
(i3) = (r * (i1) - (r1)) / s; \
} \
}
#define DC_ABS(a,b) (fabs(a) + fabs(b))
@ -215,6 +269,228 @@ typedef struct {
(A).imag = (B.imag) - (C.imag); \
}
/* Macro function that returns the approx absolute value of a complex number. */
#if spCOMPLEX
#define ELEMENT_MAG(ptr) (ABS((ptr)->Real) + ABS((ptr)->Imag))
#else
#define ELEMENT_MAG(ptr) ((ptr)->Real < 0.0 ? -(ptr)->Real : (ptr)->Real)
#endif
/* Complex assignment statements. */
#define CMPLX_ASSIGN(to,from) \
{ (to).Real = (from).Real; \
(to).Imag = (from).Imag; \
}
#define CMPLX_CONJ_ASSIGN(to,from) \
{ (to).Real = (from).Real; \
(to).Imag = -(from).Imag; \
}
#define CMPLX_NEGATE_ASSIGN(to,from) \
{ (to).Real = -(from).Real; \
(to).Imag = -(from).Imag; \
}
#define CMPLX_CONJ_NEGATE_ASSIGN(to,from) \
{ (to).Real = -(from).Real; \
(to).Imag = (from).Imag; \
}
#define CMPLX_CONJ(a) (a).Imag = -(a).Imag
#define CMPLX_NEGATE(a) \
{ (a).Real = -(a).Real; \
(a).Imag = -(a).Imag; \
}
/* Macro that returns the approx magnitude (L-1 norm) of a complex number. */
#define CMPLX_1_NORM(a) (ABS((a).Real) + ABS((a).Imag))
/* Macro that returns the approx magnitude (L-infinity norm) of a complex. */
#define CMPLX_INF_NORM(a) (MAX (ABS((a).Real),ABS((a).Imag)))
/* Macro function that returns the magnitude (L-2 norm) of a complex number. */
#define CMPLX_2_NORM(a) (sqrt((a).Real*(a).Real + (a).Imag*(a).Imag))
/* Macro function that performs complex addition. */
#define CMPLX_ADD(to,from_a,from_b) \
{ (to).Real = (from_a).Real + (from_b).Real; \
(to).Imag = (from_a).Imag + (from_b).Imag; \
}
/* Macro function that performs complex subtraction. */
#define CMPLX_SUBT(to,from_a,from_b) \
{ (to).Real = (from_a).Real - (from_b).Real; \
(to).Imag = (from_a).Imag - (from_b).Imag; \
}
/* Macro function that is equivalent to += operator for complex numbers. */
#define CMPLX_ADD_ASSIGN(to,from) \
{ (to).Real += (from).Real; \
(to).Imag += (from).Imag; \
}
/* Macro function that is equivalent to -= operator for complex numbers. */
#define CMPLX_SUBT_ASSIGN(to,from) \
{ (to).Real -= (from).Real; \
(to).Imag -= (from).Imag; \
}
/* Macro function that multiplies a complex number by a scalar. */
#define SCLR_MULT(to,sclr,cmplx) \
{ (to).Real = (sclr) * (cmplx).Real; \
(to).Imag = (sclr) * (cmplx).Imag; \
}
/* Macro function that multiply-assigns a complex number by a scalar. */
#define SCLR_MULT_ASSIGN(to,sclr) \
{ (to).Real *= (sclr); \
(to).Imag *= (sclr); \
}
/* Macro function that multiplies two complex numbers. */
#define CMPLX_MULT(to,from_a,from_b) \
{ (to).Real = (from_a).Real * (from_b).Real - \
(from_a).Imag * (from_b).Imag; \
(to).Imag = (from_a).Real * (from_b).Imag + \
(from_a).Imag * (from_b).Real; \
}
/* Macro function that implements to *= from for complex numbers. */
#define CMPLX_MULT_ASSIGN(to,from) \
{ RealNumber to_real_ = (to).Real; \
(to).Real = to_real_ * (from).Real - \
(to).Imag * (from).Imag; \
(to).Imag = to_real_ * (from).Imag + \
(to).Imag * (from).Real; \
}
/* Macro function that multiplies two complex numbers, the first of which is
* conjugated. */
#define CMPLX_CONJ_MULT(to,from_a,from_b) \
{ (to).Real = (from_a).Real * (from_b).Real + \
(from_a).Imag * (from_b).Imag; \
(to).Imag = (from_a).Real * (from_b).Imag - \
(from_a).Imag * (from_b).Real; \
}
/* Macro function that multiplies two complex numbers and then adds them
* to another. to = add + mult_a * mult_b */
#define CMPLX_MULT_ADD(to,mult_a,mult_b,add) \
{ (to).Real = (mult_a).Real * (mult_b).Real - \
(mult_a).Imag * (mult_b).Imag + (add).Real; \
(to).Imag = (mult_a).Real * (mult_b).Imag + \
(mult_a).Imag * (mult_b).Real + (add).Imag; \
}
/* Macro function that subtracts the product of two complex numbers from
* another. to = subt - mult_a * mult_b */
#define CMPLX_MULT_SUBT(to,mult_a,mult_b,subt) \
{ (to).Real = (subt).Real - (mult_a).Real * (mult_b).Real + \
(mult_a).Imag * (mult_b).Imag; \
(to).Imag = (subt).Imag - (mult_a).Real * (mult_b).Imag - \
(mult_a).Imag * (mult_b).Real; \
}
/* Macro function that multiplies two complex numbers and then adds them
* to another. to = add + mult_a* * mult_b where mult_a* represents mult_a
* conjugate. */
#define CMPLX_CONJ_MULT_ADD(to,mult_a,mult_b,add) \
{ (to).Real = (mult_a).Real * (mult_b).Real + \
(mult_a).Imag * (mult_b).Imag + (add).Real; \
(to).Imag = (mult_a).Real * (mult_b).Imag - \
(mult_a).Imag * (mult_b).Real + (add).Imag; \
}
/* Macro function that multiplies two complex numbers and then adds them
* to another. to += mult_a * mult_b */
#define CMPLX_MULT_ADD_ASSIGN(to,from_a,from_b) \
{ (to).Real += (from_a).Real * (from_b).Real - \
(from_a).Imag * (from_b).Imag; \
(to).Imag += (from_a).Real * (from_b).Imag + \
(from_a).Imag * (from_b).Real; \
}
/* Macro function that multiplies two complex numbers and then subtracts them
* from another. */
#define CMPLX_MULT_SUBT_ASSIGN(to,from_a,from_b) \
{ (to).Real -= (from_a).Real * (from_b).Real - \
(from_a).Imag * (from_b).Imag; \
(to).Imag -= (from_a).Real * (from_b).Imag + \
(from_a).Imag * (from_b).Real; \
}
/* Macro function that multiplies two complex numbers and then adds them
* to the destination. to += from_a* * from_b where from_a* represents from_a
* conjugate. */
#define CMPLX_CONJ_MULT_ADD_ASSIGN(to,from_a,from_b) \
{ (to).Real += (from_a).Real * (from_b).Real + \
(from_a).Imag * (from_b).Imag; \
(to).Imag += (from_a).Real * (from_b).Imag - \
(from_a).Imag * (from_b).Real; \
}
/* Macro function that multiplies two complex numbers and then subtracts them
* from the destination. to -= from_a* * from_b where from_a* represents from_a
* conjugate. */
#define CMPLX_CONJ_MULT_SUBT_ASSIGN(to,from_a,from_b) \
{ (to).Real -= (from_a).Real * (from_b).Real + \
(from_a).Imag * (from_b).Imag; \
(to).Imag -= (from_a).Real * (from_b).Imag - \
(from_a).Imag * (from_b).Real; \
}
/*
* Macro functions that provide complex division.
*/
/* Complex division: to = num / den */
#define CMPLX_DIV(to,num,den) \
{ RealNumber r_, s_; \
if (((den).Real >= (den).Imag AND (den).Real > -(den).Imag) OR \
((den).Real < (den).Imag AND (den).Real <= -(den).Imag)) \
{ r_ = (den).Imag / (den).Real; \
s_ = (den).Real + r_*(den).Imag; \
(to).Real = ((num).Real + r_*(num).Imag)/s_; \
(to).Imag = ((num).Imag - r_*(num).Real)/s_; \
} \
else \
{ r_ = (den).Real / (den).Imag; \
s_ = (den).Imag + r_*(den).Real; \
(to).Real = (r_*(num).Real + (num).Imag)/s_; \
(to).Imag = (r_*(num).Imag - (num).Real)/s_; \
} \
}
/* Complex division and assignment: num /= den */
#define CMPLX_DIV_ASSIGN(num,den) \
{ RealNumber r_, s_, t_; \
if (((den).Real >= (den).Imag AND (den).Real > -(den).Imag) OR \
((den).Real < (den).Imag AND (den).Real <= -(den).Imag)) \
{ r_ = (den).Imag / (den).Real; \
s_ = (den).Real + r_*(den).Imag; \
t_ = ((num).Real + r_*(num).Imag)/s_; \
(num).Imag = ((num).Imag - r_*(num).Real)/s_; \
(num).Real = t_; \
} \
else \
{ r_ = (den).Real / (den).Imag; \
s_ = (den).Imag + r_*(den).Real; \
t_ = (r_*(num).Real + (num).Imag)/s_; \
(num).Imag = (r_*(num).Imag - (num).Real)/s_; \
(num).Real = t_; \
} \
}
/* Complex reciprocation: to = 1.0 / den */
#define CMPLX_RECIPROCAL(to,den) \
{ RealNumber r_; \
if (((den).Real >= (den).Imag AND (den).Real > -(den).Imag) OR \
((den).Real < (den).Imag AND (den).Real <= -(den).Imag)) \
{ r_ = (den).Imag / (den).Real; \
(to).Imag = -r_*((to).Real = 1.0/((den).Real + r_*(den).Imag)); \
} \
else \
{ r_ = (den).Real / (den).Imag; \
(to).Real = -r_*((to).Imag = -1.0/((den).Imag + r_*(den).Real));\
} \
}
#endif /*CMPLX*/
#endif /*_COMPLEX_H */

View File

@ -14,46 +14,6 @@
#define NUMELEMS(ARRAY) (sizeof(ARRAY)/sizeof(*ARRAY))
/*
* Macros for complex mathematical functions.
*/
/* Some defines used mainly in cmath.c. */
#define alloc_c(len) ((complex *) tmalloc((len) * sizeof (complex)))
#define alloc_d(len) ((double *) tmalloc((len) * sizeof (double)))
#define FTEcabs(d) (((d) < 0.0) ? - (d) : (d))
#define cph(c) (atan2(imagpart(c), (realpart(c))))
#define cmag(c) (sqrt(imagpart(c) * imagpart(c) + realpart(c) * realpart(c)))
#define radtodeg(c) (cx_degrees ? ((c) / 3.14159265358979323846 * 180) : (c))
#define degtorad(c) (cx_degrees ? ((c) * 3.14159265358979323846 / 180) : (c))
#define rcheck(cond, name) if (!(cond)) { \
fprintf(cp_err, "Error: argument out of range for %s\n", name); \
return (NULL); }
#define cdiv(r1, i1, r2, i2, r3, i3) \
{ \
double r, s; \
if (FTEcabs(r2) > FTEcabs(i2)) { \
r = (i2) / (r2); \
s = (r2) + r * (i2); \
(r3) = ((r1) + r * (i1)) / s; \
(i3) = ((i1) - r * (r1)) / s; \
} else { \
r = (r2) / (i2); \
s = (i2) + r * (r2); \
(r3) = (r * (r1) + (i1)) / s; \
(i3) = (r * (i1) - (r1)) / s; \
} \
}
#define tfree(x) (txfree(x), x = 0)
#define alloc(TYPE) ((TYPE *) tmalloc(sizeof(TYPE)))
#define eq(a,b) (!strcmp((a), (b)))
#define eqc(a,b) (cieq((a), (b)))
#define isalphanum(c) (isalpha(c) || isdigit(c))
@ -61,6 +21,8 @@
'a') && ((c) <= 'f')) ? ((c) - 'a' + 10) : ((((c) >= 'A') && \
((c) <= 'F')) ? ((c) - 'A' + 10) : 0)))
#define tfree(x) (txfree(x), x = 0)
#define alloc(TYPE) ((TYPE *) tmalloc(sizeof(TYPE)))
#define MALLOC(x) tmalloc((unsigned)(x))
#define FREE(x) {if (x) {free((char *)(x));(x) = 0;}}
#define REALLOC(x,y) trealloc((char *)(x),(unsigned)(y))
@ -73,29 +35,29 @@
#define ABORT() fflush(stderr);fflush(stdout);abort();
#define ERROR(CODE,MESSAGE) { \
errMsg = MALLOC(strlen(MESSAGE) + 1); \
strcpy(errMsg, (MESSAGE)); \
return (CODE); \
#define ERROR(CODE,MESSAGE) { \
errMsg = (char *) tmalloc(strlen(MESSAGE) + 1); \
strcpy(errMsg, (MESSAGE)); \
return (CODE); \
}
#define NEW(TYPE) ((TYPE *) MALLOC(sizeof(TYPE)))
#define NEWN(TYPE,COUNT) ((TYPE *) MALLOC(sizeof(TYPE) * (COUNT)))
#define NEW(TYPE) ((TYPE *) tmalloc(sizeof(TYPE)))
#define NEWN(TYPE,COUNT) ((TYPE *) tmalloc(sizeof(TYPE) * (COUNT)))
#define R_NORM(A,B) { \
if ((A) == 0.0) { \
(B) = 0; \
} else { \
while (fabs(A) > 1.0) { \
(B) += 1; \
(A) /= 2.0; \
} \
while (fabs(A) < 0.5) { \
(B) -= 1; \
(A) *= 2.0; \
} \
} \
#define R_NORM(A,B) { \
if ((A) == 0.0) { \
(B) = 0; \
} else { \
while (fabs(A) > 1.0) { \
(B) += 1; \
(A) /= 2.0; \
} \
while (fabs(A) < 0.5) { \
(B) -= 1; \
(A) *= 2.0; \
} \
} \
}

8
src/include/memory.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef _MEMORY_H
#define _MEMORY_H
extern void *tmalloc(size_t num);
extern void *trealloc(void *str, size_t num);
extern void txfree(void *ptr);
#endif

View File

@ -1,3 +1,7 @@
Makefile.in
Makefile
.deps
.libs
test_cx_mag
test_cx_j
test_cx_ph

View File

@ -12,7 +12,14 @@ libcmaths_a_SOURCES = \
cmath4.c \
cmath4.h
bin_PROGRAMS = test_cx_mag test_cx_j
bin_PROGRAMS = test_cx_mag test_cx_j test_cx_ph
test_cx_ph_SOURCES = \
test_cx_ph.c
test_cx_ph_LDADD = \
libcmaths.a \
../../misc/libmisc.a
test_cx_mag_SOURCES = \
test_cx_mag.c
@ -28,7 +35,7 @@ test_cx_j_LDADD = \
libcmaths.a \
../../misc/libmisc.a
TESTS = test_cx_mag test_cx_j
TESTS = test_cx_mag test_cx_j test_cx_ph
INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)/src/maths/poly

View File

@ -0,0 +1,34 @@
#include <stdio.h>
#include <math.h>
#include <memory.h>
#include <dvec.h>
#include <complex.h>
#include "cmath1.h"
FILE *cp_err;
int
main(void)
{
complex *c = NULL;
double *d = NULL;
short int t1;
short int t2;
int n1;
int n2;
double eps = DBL_EPSILON;
cp_err = stderr;
n1 = 1;
t1 = VF_COMPLEX;
c = alloc_c(n1);
realpart(&c[0]) = .0;
imagpart(&c[0]) = 1.0;
d = (double *) cx_ph((void *) c, t1, n1, &n2, &t2);
if (M_PI/2 - eps < d[0] && d[0] < M_PI/2 + eps)
return 0;
else
return 1;
}

View File

@ -440,48 +440,7 @@
}
/*
* REAL NUMBER
*/
/* Begin `RealNumber'. */
typedef spREAL RealNumber, *RealVector;
/*
* COMPLEX NUMBER DATA STRUCTURE
*
* >>> Structure fields:
* Real (RealNumber)
* The real portion of the number. Real must be the first
* field in this structure.
* Imag (RealNumber)
* The imaginary portion of the number. This field must follow
* immediately after Real.
*/
/* Begin `ComplexNumber'. */
typedef struct
{ RealNumber Real;
RealNumber Imag;
} ComplexNumber, *ComplexVector;
#include "complex.h"