EXITPOINT to delete malloced var in case of check failure

This commit is contained in:
Jim Monte 2020-04-25 19:20:58 +02:00 committed by Holger Vogt
parent 9a83e6705c
commit b518d90509
3 changed files with 458 additions and 262 deletions

View File

@ -16,6 +16,8 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
*
*/
#include <errno.h>
#include "ngspice/ngspice.h"
#include "ngspice/memory.h"
#include "ngspice/cpdefs.h"
@ -206,7 +208,7 @@ void *cx_conj(void *data, short int type, int length,
ngcomplex_t * const c_dst = alloc_c(length);
ngcomplex_t *c_dst_cur = c_dst;
ngcomplex_t *c_src_cur = (ngcomplex_t *) data;
ngcomplex_t * const c_src_end = c_src_cur + length;
ngcomplex_t * const c_src_end = c_src_cur + length;
for ( ; c_src_cur < c_src_end; c_src_cur++, c_dst_cur++) {
c_dst_cur->cx_real = c_src_cur->cx_real;
c_dst_cur->cx_imag = -c_src_cur->cx_imag;
@ -215,7 +217,7 @@ void *cx_conj(void *data, short int type, int length,
}
/* Else real, so just copy */
return memcpy(alloc_d(length), data, length * sizeof(double));
return memcpy(alloc_d(length), data, (unsigned int) length * sizeof(double));
} /* end of function cx_conj */
@ -241,21 +243,20 @@ cx_pos(void *data, short int type, int length, int *newlength, short int *newtyp
return ((void *) d);
}
void *
cx_db(void *data, short int type, int length, int *newlength, short int *newtype)
void *cx_db(void *data, short int type, int length,
int *newlength, short int *newtype)
{
int xrc = 0;
double *d = alloc_d(length);
double *dd = (double *) data;
ngcomplex_t *cc = (ngcomplex_t *) data;
double tt;
int i;
*newlength = length;
*newtype = VF_REAL;
if (type == VF_COMPLEX)
if (type == VF_COMPLEX) {
ngcomplex_t *cc = (ngcomplex_t *) data;
int i;
for (i = 0; i < length; i++) {
tt = cmag(cc[i]);
rcheckn(tt > 0, "db", d);
const double tt = cmag(cc[i]);
rcheck(tt > 0, "db");
/*
if (tt == 0.0)
d[i] = 20.0 * - log(HUGE);
@ -263,29 +264,44 @@ cx_db(void *data, short int type, int length, int *newlength, short int *newtype
*/
d[i] = 20.0 * log10(tt);
}
else
}
else {
double *dd = (double *) data;
int i;
for (i = 0; i < length; i++) {
rcheckn(dd[i] > 0, "db", d);
const double tt = dd[i];
rcheck(tt > 0, "db");
/*
if (dd[i] == 0.0)
d[i] = 20.0 * - log(HUGE);
else
*/
d[i] = 20.0 * log10(dd[i]);
d[i] = 20.0 * log10(tt);
}
return ((void *) d);
}
}
void *
cx_log10(void *data, short int type, int length, int *newlength, short int *newtype)
EXITPOINT:
if (xrc != 0) {
txfree(d);
d = (double *) NULL;
}
return ((void *) d);
} /* end of function cx_db */
void *cx_log10(void *data, short int type, int length,
int *newlength, short int *newtype)
{
*newlength = length;
int xrc = 0;
void *rv;
if (type == VF_COMPLEX) {
ngcomplex_t *c;
ngcomplex_t *cc = (ngcomplex_t *) data;
int i;
c = alloc_c(length);
rv = c = alloc_c(length);
*newtype = VF_COMPLEX;
for (i = 0; i < length; i++) {
double td;
@ -294,78 +310,106 @@ cx_log10(void *data, short int type, int length, int *newlength, short int *newt
/* Perhaps we should trap when td = 0.0, but Ken wants
* this to be possible...
*/
rcheckn(td >= 0, "log10", c);
rcheck(td >= 0, "log10");
if (td == 0.0) {
realpart(c[i]) = - log10(HUGE);
imagpart(c[i]) = 0.0;
} else {
}
else {
realpart(c[i]) = log10(td);
imagpart(c[i]) = atan2(imagpart(cc[i]),
realpart(cc[i]));
imagpart(c[i]) = atan2(imagpart(cc[i]), realpart(cc[i]));
}
}
return ((void *) c);
} else {
}
else {
double *d;
double *dd = (double *) data;
int i;
d = alloc_d(length);
rv = d = alloc_d(length);
*newtype = VF_REAL;
for (i = 0; i < length; i++) {
rcheckn(dd[i] >= 0, "log10", d);
if (dd[i] == 0.0)
rcheck(dd[i] >= 0, "log10");
if (dd[i] == 0.0) {
d[i] = - log10(HUGE);
else
}
else {
d[i] = log10(dd[i]);
}
}
return ((void *) d);
}
}
void *
cx_log(void *data, short int type, int length, int *newlength, short int *newtype)
{
*newlength = length;
EXITPOINT:
if (xrc != 0) { /* Free resources on error */
txfree(rv);
rv = NULL;
}
return rv;
} /* end of function cx_log10 */
void *cx_log(void *data, short int type, int length,
int *newlength, short int *newtype)
{
int xrc = 0;
void *rv;
if (type == VF_COMPLEX) {
ngcomplex_t *c;
ngcomplex_t *cc = (ngcomplex_t *) data;
int i;
c = alloc_c(length);
rv = c = alloc_c(length);
*newtype = VF_COMPLEX;
int i;
for (i = 0; i < length; i++) {
double td;
td = cmag(cc[i]);
rcheckn(td >= 0, "log", c);
rcheck(td >= 0, "log");
if (td == 0.0) {
realpart(c[i]) = - log(HUGE);
imagpart(c[i]) = 0.0;
} else {
}
else {
realpart(c[i]) = log(td);
imagpart(c[i]) = atan2(imagpart(cc[i]),
realpart(cc[i]));
imagpart(c[i]) = atan2(imagpart(cc[i]), realpart(cc[i]));
}
}
return ((void *) c);
} else {
}
else {
double *d;
double *dd = (double *) data;
int i;
d = alloc_d(length);
rv = d = alloc_d(length);
*newtype = VF_REAL;
int i;
for (i = 0; i < length; i++) {
rcheckn(dd[i] >= 0, "log", d);
rcheck(dd[i] >= 0, "log");
if (dd[i] == 0.0)
d[i] = - log(HUGE);
else
d[i] = log(dd[i]);
}
return ((void *) d);
}
}
*newlength = length;
EXITPOINT:
if (xrc != 0) { /* Free resources on error */
txfree(rv);
rv = NULL;
}
return rv;
} /* end of function cx_log */
void *
cx_exp(void *data, short int type, int length, int *newlength, short int *newtype)
@ -614,19 +658,29 @@ cx_cosh(void *data, short int type, int length, int *newlength, short int *newty
}
}
static double *
d_tan(double *dd, int length)
{
double *d;
int i;
d = alloc_d(length);
static double *d_tan(double *dd, int length)
{
int xrc = 0;
double *d = alloc_d(length);
int i;
for (i = 0; i < length; i++) {
rcheckn(tan(degtorad(dd[i])) != 0, "tan", d);
rcheck(tan(degtorad(dd[i])) != 0, "tan");
d[i] = tan(degtorad(dd[i]));
}
EXITPOINT:
if (xrc != 0) { /* Free resources on error */
txfree(d);
d = (double *) NULL;
}
return d;
}
} /* end of function d_tan */
static double *
d_tanh(double *dd, int length)
@ -641,64 +695,93 @@ d_tanh(double *dd, int length)
return d;
}
static ngcomplex_t *
c_tan(ngcomplex_t *cc, int length)
/* See https://proofwiki.org/wiki/Tangent_of_Complex_Number (formulation 4) among
* others for the tangent formula:
* sin z = sin(x + iy) = sin x cos(iy) + cos x sin(iy) = sin x cosh y + i cos x sinh y
* cos z = cos(x + iy) = cos x cos(iy) + sin x sin(iy) = cos x cosh y - i sin x sinh y
* tan z = ((sin x cosh y + i cos x sinh y) / (cos x cosh y - i sin x sinh y)) *
(cos x cosh y + isin x sinh y) / (cos x cosh y + i sin x sinh y)
= ...
*
*
* tan(a + bi) = (sin(2a) + i * sinh(2b)) / (cos(2a) + cosh(2b))
*/
static ngcomplex_t *c_tan(ngcomplex_t *cc, int length)
{
ngcomplex_t *c;
ngcomplex_t * const c = alloc_c(length);
int i;
c = alloc_c(length);
for (i = 0; i < length; i++) {
double u, v;
rcheckn(cos(degtorad(realpart(cc[i]))) *
cosh(degtorad(imagpart(cc[i]))), "tan", c);
rcheckn(sin(degtorad(realpart(cc[i]))) *
sinh(degtorad(imagpart(cc[i]))), "tan", c);
u = degtorad(realpart(cc[i]));
v = degtorad(imagpart(cc[i]));
/* The Lattice C compiler won't take multi-line macros, and
* CMS won't take >80 column lines....
*/
#define xx1 sin(u) * cosh(v)
#define xx2 cos(u) * sinh(v)
#define xx3 cos(u) * cosh(v)
#define xx4 -sin(u) * sinh(v)
cdiv(xx1, xx2, xx3, xx4, realpart(c[i]), imagpart(c[i]));
}
return c;
}
/* complex tanh function, uses tanh(z) = -i * tan (i * z) */
static ngcomplex_t *
c_tanh(ngcomplex_t *cc, int length)
{
ngcomplex_t *c, *s, *t;
int i;
c = alloc_c(length);
s = alloc_c(1);
t = alloc_c(1);
for (i = 0; i < length; i++) {
/* multiply by i */
t[0].cx_real = -1. * imagpart(cc[i]);
t[0].cx_imag = realpart(cc[i]);
/* get complex tangent */
s = c_tan(t, 1);
/* if check in c_tan fails */
if (s == NULL) {
tfree(t);
return (NULL);
errno = 0;
ngcomplex_t *p_dst = c + i;
ngcomplex_t *p_src = cc + i;
const double a = p_src->cx_real;
const double b = p_src->cx_imag;
const double u = 2 * degtorad(a);
const double v = 2 * degtorad(b);
const double n_r = sin(u);
const double n_i = sinh(v);
const double d1 = cos(u);
const double d2 = cosh(v);
const double d = d1 + d2;
if (errno != 0 || d == 0.0) {
(void) fprintf(cp_err,
"Invalid argument %lf + %lf i for compex tangent", a, b);
txfree(c);
return (ngcomplex_t *) NULL;
}
/* multiply by -i */
realpart(c[i]) = imagpart(s[0]);
imagpart(c[i]) = -1. * realpart(s[0]);
}
tfree(s);
tfree(t);
p_dst->cx_real = n_r / d;
p_dst->cx_imag = n_i / d;
} /* end of loop over elements in array */
return c;
}
} /* end of function c_tan */
/* complex tanh function, uses tanh(z) = -i * tan(i * z).
* Unfortunately, it did so very inefficiently (a memory allocations per
* value calculated!) and leaked memory badly (all of the aforementioned
* allocations.) These issues were fixed 2020-03-04 */
static ngcomplex_t *c_tanh(ngcomplex_t *cc, int length)
{
ngcomplex_t * const tmp = alloc_c(length); /* i * z */
/* Build the i * z array to allow tan() to be called */
{
int i;
for (i = 0; i < length; ++i) {
ngcomplex_t *p_dst = tmp + i;
ngcomplex_t *p_src = cc + i;
/* multiply by i */
p_dst->cx_real = -p_src->cx_imag;
p_dst->cx_imag = p_src->cx_real;
}
}
/* Calculat tan(i * z), exiting on failure */
ngcomplex_t *const c = c_tan(tmp, length);
if (c == (ngcomplex_t *) NULL) {
txfree(tmp);
return (ngcomplex_t *) NULL;
}
/* Multiply by -i to find final result */
{
int i;
for (i = 0; i < length; ++i) {
ngcomplex_t *p_cur = c + i;
const double cx_real = p_cur->cx_real;
p_cur->cx_real = p_cur->cx_imag;
p_cur->cx_imag = -cx_real;
}
}
return c;
} /* end of function c_tanh */
void *
cx_tan(void *data, short int type, int length, int *newlength, short int *newtype)
@ -770,8 +853,8 @@ cx_sortorder(void *data, short int type, int length, int *newlength, short int *
double *dd = (double *) data;
int i;
amplitude_index_t *array_amplitudes;
array_amplitudes = (amplitude_index_t *) tmalloc(sizeof(amplitude_index_t) * (size_t) length);
amplitude_index_t * const array_amplitudes = (amplitude_index_t *)
tmalloc(sizeof(amplitude_index_t) * (size_t) length);
*newlength = length;
*newtype = VF_REAL;
@ -788,7 +871,7 @@ cx_sortorder(void *data, short int type, int length, int *newlength, short int *
d[i] = array_amplitudes[i].index;
}
tfree(array_amplitudes);
txfree(array_amplitudes);
/* Otherwise it is 0, but tmalloc zeros the stuff already. */
return ((void *) d);

View File

@ -361,11 +361,17 @@ cx_avg(void *data, short int type, int length, int *newlength, short int *newtyp
/* Compute the mean of a vector. */
void *
cx_mean(void *data, short int type, int length, int *newlength, short int *newtype)
void *cx_mean(void *data, short int type, int length,
int *newlength, short int *newtype)
{
if (length == 0) {
(void) fprintf(cp_err, "mean calculation requires "
"at least one element.\n");
return NULL;
}
*newlength = 1;
rcheck(length > 0, "mean");
if (type == VF_REAL) {
double *d;
double *dd = (double *) data;
@ -377,7 +383,8 @@ cx_mean(void *data, short int type, int length, int *newlength, short int *newty
*d += dd[i];
*d /= length;
return ((void *) d);
} else {
}
else {
ngcomplex_t *c;
ngcomplex_t *cc = (ngcomplex_t *) data;
int i;
@ -397,43 +404,59 @@ cx_mean(void *data, short int type, int length, int *newlength, short int *newty
/* Compute the standard deviation of all elements of a vector. */
void *
cx_stddev(void *data, short int type, int length, int *newlength, short int *newtype)
void *cx_stddev(void *data, short int type, int length,
int *newlength, short int *newtype)
{
if (length == 0) {
(void) fprintf(cp_err, "standard deviation calculation requires "
"at least one element.\n");
return NULL;
}
*newlength = 1;
rcheck(length > 1, "stddev");
if (type == VF_REAL) {
double *mean = (double *)cx_mean(data, type, length, newlength, newtype);
double *d, sum = 0.;
double *dd = (double *)data;
int i;
double *p_mean = (double *) cx_mean(data, type, length,
newlength, newtype);
double mean = *p_mean;
double *d, sum = 0.0;
double *dd = (double *) data;
d = alloc_d(1);
*newtype = VF_REAL;
for (i = 0; i < length; i++)
sum += (dd[i] - *mean) * (dd[i] - *mean);
int i;
for (i = 0; i < length; i++) {
const double tmp = dd[i] - mean;
sum += tmp * tmp;
}
*d = sqrt(sum / ((double) length - 1.0));
tfree(mean);
return ((void *)d);
txfree(p_mean);
return (void *) d;
}
else {
ngcomplex_t *cmean = (ngcomplex_t *)cx_mean(data, type, length, newlength, newtype);
double *d, sum = 0., a, b;
ngcomplex_t *cc = (ngcomplex_t *)data;
int i;
ngcomplex_t * const p_cmean = (ngcomplex_t *) cx_mean(data, type, length,
newlength, newtype);
const ngcomplex_t cmean = *p_cmean;
const double rmean = realpart(cmean);
const double imean = imagpart(cmean);
double *d, sum = 0.0;
ngcomplex_t *cc = (ngcomplex_t *) data;
d = alloc_d(1);
*newtype = VF_REAL;
int i;
for (i = 0; i < length; i++) {
a = realpart(cc[i]) - realpart(*cmean);
b = imagpart(cc[i]) - imagpart(*cmean);
const double a = realpart(cc[i]) - rmean;
const double b = imagpart(cc[i]) - imean;
sum += a * a + b * b;
}
*d = sqrt(sum / ((double) length - 1.0));
tfree(cmean);
return ((void *)d);
txfree(p_cmean);
return (void *) d;
}
}
} /* end of function cx_stddev */
void *
@ -635,35 +658,41 @@ cx_times(void *data1, void *data2, short int datatype1, short int datatype2, int
}
void *
cx_mod(void *data1, void *data2, short int datatype1, short int datatype2, int length)
void *cx_mod(void *data1, void *data2, short int datatype1, short int datatype2,
int length)
{
int xrc = 0;
void *rv;
double *dd1 = (double *) data1;
double *dd2 = (double *) data2;
double *d;
ngcomplex_t *cc1 = (ngcomplex_t *) data1;
ngcomplex_t *cc2 = (ngcomplex_t *) data2;
ngcomplex_t *c, c1, c2;
int i, r1, r2, i1, i2, r3, i3;
if ((datatype1 == VF_REAL) && (datatype2 == VF_REAL)) {
d = alloc_d(length);
double *d;
rv = d = alloc_d(length);
int i;
for (i = 0; i < length; i++) {
r1 = (int)floor(fabs(dd1[i]));
const int r1 = (int) floor(fabs(dd1[i]));
rcheck(r1 > 0, "mod");
r2 = (int)floor(fabs(dd2[i]));
const int r2 = (int)floor(fabs(dd2[i]));
rcheck(r2 > 0, "mod");
r3 = r1 % r2;
const int r3 = r1 % r2;
d[i] = (double) r3;
}
return ((void *) d);
} else {
c = alloc_c(length);
}
else {
ngcomplex_t *c, c1, c2;
ngcomplex_t *cc1 = (ngcomplex_t *) data1;
ngcomplex_t *cc2 = (ngcomplex_t *) data2;
rv = c = alloc_c(length);
int i;
for (i = 0; i < length; i++) {
if (datatype1 == VF_REAL) {
realpart(c1) = dd1[i];
imagpart(c1) = 0.0;
} else {
}
else {
c1 = cc1[i];
}
if (datatype2 == VF_REAL) {
@ -672,34 +701,47 @@ cx_mod(void *data1, void *data2, short int datatype1, short int datatype2, int l
} else {
c2 = cc2[i];
}
r1 = (int)floor(fabs(realpart(c1)));
const int r1 = (int) floor(fabs(realpart(c1)));
rcheck(r1 > 0, "mod");
r2 = (int)floor(fabs(realpart(c2)));
const int r2 = (int) floor(fabs(realpart(c2)));
rcheck(r2 > 0, "mod");
i1 = (int)floor(fabs(imagpart(c1)));
const int i1 = (int) floor(fabs(imagpart(c1)));
rcheck(i1 > 0, "mod");
i2 = (int)floor(fabs(imagpart(c2)));
const int i2 = (int) floor(fabs(imagpart(c2)));
rcheck(i2 > 0, "mod");
r3 = r1 % r2;
i3 = i1 % i2;
const int r3 = r1 % r2;
const int i3 = i1 % i2;
realpart(c[i]) = (double) r3;
imagpart(c[i]) = (double) i3;
}
return ((void *) c);
}
}
EXITPOINT:
if (xrc != 0) { /* Free resources on error */
txfree(rv);
rv = NULL;
}
return rv;
} /* end of function cx_mod */
/* Routoure JM : Compute the max of a vector. */
void *
cx_max(void *data, short int type, int length, int *newlength, short int *newtype)
void *cx_max(void *data, short int type, int length,
int *newlength, short int *newtype)
{
if (length == 0) {
(void) fprintf(cp_err, "maximum calculation requires "
"at least one element.\n");
return NULL;
}
*newlength = 1;
/* test if length >0 et affiche un message d'erreur */
rcheck(length > 0, "mean");
if (type == VF_REAL) {
double largest=0.0;
double largest = 0.0;
double *d;
double *dd = (double *) data;
int i;
@ -707,14 +749,18 @@ cx_max(void *data, short int type, int length, int *newlength, short int *newtyp
d = alloc_d(1);
*newtype = VF_REAL;
largest = dd[0];
for (i = 1; i < length; i++)
if (largest < dd[i])
largest = dd[i];
for (i = 1; i < length; i++) {
const double tmp = dd[i];
if (largest < tmp) {
largest = tmp;
}
}
*d = largest;
return ((void *) d);
} else {
double largest_real=0.0;
double largest_complex=0.0;
return (void *) d;
}
else {
double largest_real = 0.0;
double largest_complex = 0.0;
ngcomplex_t *c;
ngcomplex_t *cc = (ngcomplex_t *) data;
int i;
@ -723,27 +769,37 @@ cx_max(void *data, short int type, int length, int *newlength, short int *newtyp
*newtype = VF_COMPLEX;
largest_real = realpart(*cc);
largest_complex = imagpart(*cc);
for (i = 0; i < length; i++) {
if (largest_real < realpart(cc[i]))
largest_real = realpart(cc[i]);
if (largest_complex < imagpart(cc[i]))
largest_complex = imagpart(cc[i]);
for (i = 1; i < length; i++) {
const double tmpr = realpart(cc[i]);
if (largest_real < tmpr) {
largest_real = tmpr;
}
const double tmpi = imagpart(cc[i]);
if (largest_complex < tmpi) {
largest_complex = tmpi;
}
}
realpart(*c) = largest_real;
imagpart(*c) = largest_complex;
return ((void *) c);
return (void *) c;
}
}
} /* end of function cx_max */
/* Routoure JM : Compute the min of a vector. */
void *
cx_min(void *data, short int type, int length, int *newlength, short int *newtype)
void *cx_min(void *data, short int type, int length,
int *newlength, short int *newtype)
{
if (length == 0) {
(void) fprintf(cp_err, "minimum calculation requires "
"at least one element.\n");
return NULL;
}
*newlength = 1;
/* test if length >0 et affiche un message d'erreur */
rcheck(length > 0, "mean");
if (type == VF_REAL) {
double smallest;
double *d;
@ -753,12 +809,16 @@ cx_min(void *data, short int type, int length, int *newlength, short int *newtyp
d = alloc_d(1);
*newtype = VF_REAL;
smallest = dd[0];
for (i = 1; i < length; i++)
if (smallest > dd[i])
smallest = dd[i];
for (i = 1; i < length; i++) {
const double tmp = dd[i];
if (smallest > tmp) {
smallest = tmp;
}
}
*d = smallest;
return ((void *) d);
} else {
return (void *) d;
}
else {
double smallest_real;
double smallest_complex;
ngcomplex_t *c;
@ -770,26 +830,35 @@ cx_min(void *data, short int type, int length, int *newlength, short int *newtyp
smallest_real = realpart(*cc);
smallest_complex = imagpart(*cc);
for (i = 1; i < length; i++) {
if (smallest_real > realpart(cc[i]))
smallest_real = realpart(cc[i]);
if (smallest_complex > imagpart(cc[i]))
smallest_complex = imagpart(cc[i]);
const double tmpr = realpart(cc[i]);
if (smallest_real > tmpr) {
smallest_real = tmpr;
}
const double tmpi = imagpart(cc[i]);
if (smallest_complex > tmpi) {
smallest_complex = tmpi;
}
}
realpart(*c) = smallest_real;
imagpart(*c) = smallest_complex;
return ((void *) c);
return (void *) c;
}
}
} /* end of function cx_min */
/* Routoure JM : Compute the differential of a vector. */
void *
cx_d(void *data, short int type, int length, int *newlength, short int *newtype)
void *cx_d(void *data, short int type, int length,
int *newlength, short int *newtype)
{
if (length == 0) {
(void) fprintf(cp_err, "differential calculation requires "
"at least one element.\n");
return NULL;
}
*newlength = length;
/* test if length >0 et affiche un message d'erreur */
rcheck(length > 0, "deriv");
if (type == VF_REAL) {
double *d;
double *dd = (double *) data;
@ -799,12 +868,13 @@ cx_d(void *data, short int type, int length, int *newlength, short int *newtype)
*newtype = VF_REAL;
d[0] = dd[1] - dd[0];
d[length-1] = dd[length-1] - dd[length-2];
for (i = 1; i < length - 1; i++)
for (i = 1; i < length - 1; i++) {
d[i] = dd[i+1] - dd[i-1];
}
return ((void *) d);
} else {
return (void *) d;
}
else {
ngcomplex_t *c;
ngcomplex_t *cc = (ngcomplex_t *) data;
int i;
@ -820,11 +890,11 @@ cx_d(void *data, short int type, int length, int *newlength, short int *newtype)
for (i = 1; i < length - 1; i++) {
realpart(c[i]) = realpart(cc[i+1]) - realpart(cc[i-1]);
imagpart(c[i]) = imagpart(cc[i+1]) - imagpart(cc[i-1]);
}
return ((void *) c);
return (void *) c;
}
}
} /* end of function cx_d */
void *

View File

@ -24,50 +24,64 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
static ngcomplex_t *cexp_sp3(ngcomplex_t *c); /* cexp exist's in some newer compiler */
static ngcomplex_t *cln(ngcomplex_t *c);
static ngcomplex_t *ctimes(ngcomplex_t *c1, ngcomplex_t *c2);
static int cln(ngcomplex_t *c, ngcomplex_t *rv);
static void ctimes(ngcomplex_t *c1, ngcomplex_t *c2, ngcomplex_t *rv);
void *
cx_divide(void *data1, void *data2, short int datatype1, short int datatype2, int length)
void *cx_divide(void *data1, void *data2,
short int datatype1, short int datatype2, int length)
{
int xrc = 0;
void *rv;
double *dd1 = (double *) data1;
double *dd2 = (double *) data2;
double *d;
ngcomplex_t *cc1 = (ngcomplex_t *) data1;
ngcomplex_t *cc2 = (ngcomplex_t *) data2;
ngcomplex_t *c, c1, c2;
int i;
if ((datatype1 == VF_REAL) && (datatype2 == VF_REAL)) {
d = alloc_d(length);
double *d;
rv = d = alloc_d(length);
for (i = 0; i < length; i++) {
rcheckn(dd2[i] != 0, "divide", d);
rcheck(dd2[i] != 0, "divide");
d[i] = dd1[i] / dd2[i];
}
return ((void *) d);
} else {
c = alloc_c(length);
}
else {
rv = c = alloc_c(length);
for (i = 0; i < length; i++) {
if (datatype1 == VF_REAL) {
realpart(c1) = dd1[i];
imagpart(c1) = 0.0;
} else {
}
else {
c1 = cc1[i];
}
if (datatype2 == VF_REAL) {
realpart(c2) = dd2[i];
imagpart(c2) = 0.0;
} else {
}
else {
c2 = cc2[i];
}
rcheckn((realpart(c2) != 0) || (imagpart(c2) != 0), "divide", c);
rcheck((realpart(c2) != 0) || (imagpart(c2) != 0), "divide");
#define xx5 realpart(c1)
#define xx6 imagpart(c1)
cdiv(xx5, xx6, realpart(c2), imagpart(c2), realpart(c[i]), imagpart(c[i]));
cdiv(xx5, xx6, realpart(c2), imagpart(c2), realpart(c[i]),
imagpart(c[i]));
}
return ((void *) c);
}
}
EXITPOINT:
if (xrc != 0) { /* Free resources on error */
tfree(rv);
rv = NULL;
}
return rv;
} /* end of function cx_divide */
/* Should just use "j( )" */
/* The comma operator. What this does (unless it is part of the argument
@ -105,58 +119,82 @@ cx_comma(void *data1, void *data2, short int datatype1, short int datatype2, int
return ((void *) c);
}
void *
cx_power(void *data1, void *data2, short int datatype1, short int datatype2, int length)
void *cx_power(void *data1, void *data2,
short int datatype1, short int datatype2, int length)
{
int xrc = 0;
void *rv;
double *dd1 = (double *) data1;
double *dd2 = (double *) data2;
double *d;
ngcomplex_t *cc1 = (ngcomplex_t *) data1;
ngcomplex_t *cc2 = (ngcomplex_t *) data2;
ngcomplex_t *c, c1, c2, *t;
int i;
if ((datatype1 == VF_REAL) && (datatype2 == VF_REAL)) {
d = alloc_d(length);
double *d;
rv = d = alloc_d(length);
int i;
for (i = 0; i < length; i++) {
rcheck((dd1[i] >= 0) || (floor(dd2[i]) == ceil(dd2[i])), "power");
rcheck((dd1[i] >= 0) || (floor(dd2[i]) == ceil(dd2[i])), "power");
d[i] = pow(dd1[i], dd2[i]);
}
return ((void *) d);
} else {
c = alloc_c(length);
}
else {
ngcomplex_t *cc1 = (ngcomplex_t *) data1;
ngcomplex_t *cc2 = (ngcomplex_t *) data2;
ngcomplex_t *c, c1, c2, *t;
rv = c = alloc_c(length);
int i;
for (i = 0; i < length; i++) {
if (datatype1 == VF_REAL) {
realpart(c1) = dd1[i];
imagpart(c1) = 0.0;
} else {
}
else {
c1 = cc1[i];
}
if (datatype2 == VF_REAL) {
realpart(c2) = dd2[i];
imagpart(c2) = 0.0;
} else {
}
else {
c2 = cc2[i];
}
if ((realpart(c1) == 0.0) && (imagpart(c1) == 0.0)) {
realpart(c[i]) = 0.0;
imagpart(c[i]) = 0.0;
} else { /* if ((imagpart(c1) != 0.0) &&
}
else { /* if ((imagpart(c1) != 0.0) &&
(imagpart(c2) != 0.0)) */
t = cexp_sp3(ctimes(&c2, cln(&c1)));
ngcomplex_t tmp, tmp2;
if (cln(&c1, &tmp) != 0) {
(void) fprintf(cp_err, "power of 0 + i 0 not allowed.\n");
xrc = -1;
goto EXITPOINT;
}
ctimes(&c2, &tmp, &tmp2);
t = cexp_sp3(&tmp2);
c[i] = *t;
/*
} else {
realpart(c[i]) = pow(realpart(c1),
realpart(c2));
imagpart(c[i]) = 0.0;
*/
/*
} else {
realpart(c[i]) = pow(realpart(c1),
realpart(c2));
imagpart(c[i]) = 0.0;
*/
}
}
return ((void *) c);
}
}
EXITPOINT:
if (xrc != 0) { /* Free resources on error */
txfree(rv);
rv = NULL;
}
return rv;
} /* end of function cx_power */
/* These are unnecessary... Only cx_power uses them... */
@ -175,30 +213,35 @@ cexp_sp3(ngcomplex_t *c)
return (&r);
}
static ngcomplex_t *
cln(ngcomplex_t *c)
static int cln(ngcomplex_t *c, ngcomplex_t *rv)
{
static ngcomplex_t r;
double c_r = c->cx_real;
double c_i = c->cx_imag;
rcheck(cmag(*c) != 0, "ln");
realpart(r) = log(cmag(*c));
if (imagpart(*c) != 0.0)
imagpart(r) = atan2(imagpart(*c), realpart(*c));
else
imagpart(r) = 0.0;
return (&r);
}
if (c_r == 0 && c_i == 0) {
(void) fprintf(cp_err, "Complex log of 0 + i0 is undefined.\n");
return -1;
}
static ngcomplex_t *
ctimes(ngcomplex_t *c1, ngcomplex_t *c2)
rv->cx_real = log(cmag(*c));
if (c_i != 0.0) {
rv->cx_imag = atan2(c_i, c_r);
}
else {
rv->cx_imag = 0.0;
}
return 0;
} /* end of functon cln */
static void ctimes(ngcomplex_t *c1, ngcomplex_t *c2, ngcomplex_t *rv)
{
static ngcomplex_t r;
realpart(r) = realpart(*c1) * realpart(*c2) -
rv->cx_real = realpart(*c1) * realpart(*c2) -
imagpart(*c1) * imagpart(*c2);
imagpart(r) = imagpart(*c1) * realpart(*c2) +
rv->cx_imag = imagpart(*c1) * realpart(*c2) +
realpart(*c1) * imagpart(*c2);
return (&r);
return;
}