sinh, cosh, tanh
This commit is contained in:
parent
6979f1c76a
commit
4679fdf046
|
|
@ -1,3 +1,7 @@
|
|||
2011-07-18 Holger Vogt
|
||||
* cmath1.c, cmath1.h, cmath2.c, cmath2.h, parse.c, fteext.h:
|
||||
new complex functions sinh, cosh, tanh
|
||||
|
||||
2011-07-10 Holger Vogt
|
||||
* main.c, ivars.c, /xspice/icm/analog/file_source/cfunc.mod:
|
||||
environmental variable NGSPICE_INPUT_DIR
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
|||
#include <dvec.h>
|
||||
|
||||
#include "evaluate.h"
|
||||
#include "../maths/cmaths/cmath2.h"
|
||||
|
||||
#include "sim.h" /* To get SV_VOLTAGE definition */
|
||||
|
||||
|
|
|
|||
|
|
@ -18,8 +18,6 @@ $Id$
|
|||
#include "evaluate.h"
|
||||
#include "parse.h"
|
||||
|
||||
#include "../maths/cmaths/cmath2.h"
|
||||
|
||||
/* static declarations */
|
||||
static bool checkvalid(struct pnode *pn);
|
||||
static struct pnode * mkbnode(int opnum, struct pnode *arg1, struct pnode *arg2);
|
||||
|
|
@ -160,6 +158,9 @@ struct func ft_funcs[] = {
|
|||
{ "sin", cx_sin } ,
|
||||
{ "cos", cx_cos } ,
|
||||
{ "tan", cx_tan } ,
|
||||
{ "sinh", cx_sinh } ,
|
||||
{ "cosh", cx_cosh } ,
|
||||
{ "tanh", cx_tanh } ,
|
||||
{ "atan", cx_atan } ,
|
||||
{ "norm", cx_norm } ,
|
||||
{ "rnd", cx_rnd } ,
|
||||
|
|
|
|||
|
|
@ -64,7 +64,35 @@ extern void *cx_ln(void *, short int , int , int *, short int *);
|
|||
extern void *cx_exp(void *, short int , int , int *, short int *);
|
||||
extern void *cx_sqrt(void *, short int , int , int *, short int *);
|
||||
extern void *cx_sin(void *, short int , int , int *, short int *);
|
||||
extern void *cx_sinh(void *, short int , int , int *, short int *);
|
||||
extern void *cx_cos(void *, short int , int , int *, short int *);
|
||||
extern void *cx_cosh(void *, short int , int , int *, short int *);
|
||||
extern void * cx_tan(void *, short int , int , int *, short int *);
|
||||
extern void * cx_tanh(void *, short int , int , int *, short int *);
|
||||
extern void * cx_atan(void *, short int , int , int *, short int *);
|
||||
|
||||
/* cmath2.c */
|
||||
|
||||
extern void * cx_norm(void *, short int , int , int *, short int *);
|
||||
extern void * cx_uminus(void *, short int , int , int *, short int *);
|
||||
extern void * cx_rnd(void *, short int , int , int *, short int *);
|
||||
extern void * cx_sunif(void *, short int , int , int *, short int *);
|
||||
extern void * cx_sgauss(void *, short int , int , int *, short int *);
|
||||
extern void * cx_poisson(void *, short int , int , int *, short int *);
|
||||
extern void * cx_exponential(void *, short int , int , int *, short int *);
|
||||
extern void * cx_mean(void *, short int , int , int *, short int *);
|
||||
extern void * cx_length(void *, short int , int , int *, short int *);
|
||||
extern void * cx_vector(void *, short int , int , int *, short int *);
|
||||
extern void * cx_unitvec(void *, short int , int , int *, short int *);
|
||||
extern void * cx_plus(void *, void *, short int , short int , int );
|
||||
extern void * cx_minus(void *, void *, short int , short int , int );
|
||||
extern void * cx_times(void *, void *, short int , short int , int );
|
||||
extern void * cx_mod(void *, void *, short int , short int , int );
|
||||
extern void * cx_max(void *, short int , int , int *, short int *);
|
||||
extern void * cx_min(void *, short int , int , int *, short int *);
|
||||
extern void * cx_d(void *, short int , int , int *, short int *);
|
||||
extern void *cx_avg(void *, short int , int , int *, short int *);
|
||||
|
||||
|
||||
/* cmath3.c */
|
||||
|
||||
|
|
|
|||
|
|
@ -427,6 +427,40 @@ cx_sin(void *data, short int type, int length, int *newlength, short int *newtyp
|
|||
}
|
||||
}
|
||||
|
||||
void *
|
||||
cx_sinh(void *data, short int type, int length, int *newlength, short int *newtype)
|
||||
{
|
||||
*newlength = length;
|
||||
if (type == VF_COMPLEX) {
|
||||
ngcomplex_t *c;
|
||||
ngcomplex_t *cc = (ngcomplex_t *) data;
|
||||
int i;
|
||||
double u, v;
|
||||
c = alloc_c(length);
|
||||
|
||||
*newtype = VF_COMPLEX;
|
||||
for (i = 0; i < length; i++) {
|
||||
/* sinh(x+iy) = sinh(x)*cos(y) + i * cosh(x)*sin(y) */
|
||||
u = degtorad(realpart(&cc[i]));
|
||||
v = degtorad(imagpart(&cc[i]));
|
||||
realpart(&c[i]) = sinh(u)*cos(v);
|
||||
imagpart(&c[i]) = cosh(u)*sin(v);
|
||||
}
|
||||
return ((void *) c);
|
||||
} else {
|
||||
double *d;
|
||||
double *dd = (double *) data;
|
||||
int i;
|
||||
|
||||
d = alloc_d(length);
|
||||
*newtype = VF_REAL;
|
||||
for (i = 0; i < length; i++)
|
||||
d[i] = sinh(degtorad(dd[i]));
|
||||
return ((void *) d);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
cx_cos(void *data, short int type, int length, int *newlength, short int *newtype)
|
||||
{
|
||||
|
|
@ -458,3 +492,174 @@ cx_cos(void *data, short int type, int length, int *newlength, short int *newtyp
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
cx_cosh(void *data, short int type, int length, int *newlength, short int *newtype)
|
||||
{
|
||||
*newlength = length;
|
||||
if (type == VF_COMPLEX) {
|
||||
ngcomplex_t *c;
|
||||
ngcomplex_t *cc = (ngcomplex_t *) data;
|
||||
int i;
|
||||
double u, v;
|
||||
|
||||
c = alloc_c(length);
|
||||
|
||||
*newtype = VF_COMPLEX;
|
||||
for (i = 0; i < length; i++) {
|
||||
/* cosh(x+iy) = cosh(x)*cos(y) + i * sinh(x)*sin(y) */
|
||||
u = degtorad(realpart(&cc[i]));
|
||||
v = degtorad(imagpart(&cc[i]));
|
||||
realpart(&c[i]) = cosh(u)*cos(v);
|
||||
imagpart(&c[i]) = sinh(u)*sin(v);
|
||||
}
|
||||
return ((void *) c);
|
||||
} else {
|
||||
double *d;
|
||||
double *dd = (double *) data;
|
||||
int i;
|
||||
|
||||
d = alloc_d(length);
|
||||
*newtype = VF_REAL;
|
||||
for (i = 0; i < length; i++)
|
||||
d[i] = cosh(degtorad(dd[i]));
|
||||
return ((void *) d);
|
||||
}
|
||||
}
|
||||
|
||||
static double *
|
||||
d_tan(double *dd, int length)
|
||||
{
|
||||
double *d;
|
||||
int i;
|
||||
|
||||
d = alloc_d(length);
|
||||
for (i = 0; i < length; i++) {
|
||||
rcheck(cos(degtorad(dd[i])) != 0, "tan");
|
||||
d[i] = sin(degtorad(dd[i])) / cos(degtorad(dd[i]));
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
static double *
|
||||
d_tanh(double *dd, int length)
|
||||
{
|
||||
double *d;
|
||||
int i;
|
||||
|
||||
d = alloc_d(length);
|
||||
for (i = 0; i < length; i++) {
|
||||
rcheck(cosh(degtorad(dd[i])) != 0, "tanh");
|
||||
d[i] = sinh(degtorad(dd[i])) / cosh(degtorad(dd[i]));
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
static ngcomplex_t *
|
||||
c_tan(ngcomplex_t *cc, int length)
|
||||
{
|
||||
ngcomplex_t *c;
|
||||
int i;
|
||||
|
||||
c = alloc_c(length);
|
||||
for (i = 0; i < length; i++) {
|
||||
double u, v;
|
||||
|
||||
rcheck(cos(degtorad(realpart(&cc[i]))) *
|
||||
cosh(degtorad(imagpart(&cc[i]))), "tan");
|
||||
rcheck(sin(degtorad(realpart(&cc[i]))) *
|
||||
sinh(degtorad(imagpart(&cc[i]))), "tan");
|
||||
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);
|
||||
}
|
||||
/* multiply by -i */
|
||||
realpart(&c[i]) = imagpart(&s[0]);
|
||||
imagpart(&c[i]) = -1. * realpart(&s[0]);
|
||||
}
|
||||
tfree(s);
|
||||
tfree(t);
|
||||
return c;
|
||||
}
|
||||
|
||||
void *
|
||||
cx_tan(void *data, short int type, int length, int *newlength, short int *newtype)
|
||||
{
|
||||
*newlength = length;
|
||||
if (type == VF_REAL) {
|
||||
*newtype = VF_REAL;
|
||||
return (void *) d_tan((double *) data, length);
|
||||
} else {
|
||||
*newtype = VF_COMPLEX;
|
||||
return (void *) c_tan((ngcomplex_t *) data, length);
|
||||
}
|
||||
}
|
||||
|
||||
void *
|
||||
cx_tanh(void *data, short int type, int length, int *newlength, short int *newtype)
|
||||
{
|
||||
*newlength = length;
|
||||
if (type == VF_REAL) {
|
||||
*newtype = VF_REAL;
|
||||
return (void *) d_tanh((double *) data, length);
|
||||
} else {
|
||||
*newtype = VF_COMPLEX;
|
||||
return (void *) c_tanh((ngcomplex_t *) data, length);
|
||||
}
|
||||
}
|
||||
|
||||
void *
|
||||
cx_atan(void *data, short int type, int length, int *newlength, short int *newtype)
|
||||
{
|
||||
double *d;
|
||||
|
||||
d = alloc_d(length);
|
||||
*newtype = VF_REAL;
|
||||
*newlength = length;
|
||||
if (type == VF_COMPLEX) {
|
||||
ngcomplex_t *cc = (ngcomplex_t *) data;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
d[i] = radtodeg(atan(realpart(&cc[i])));
|
||||
} else {
|
||||
double *dd = (double *) data;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
d[i] = radtodeg(atan(dd[i]));
|
||||
}
|
||||
return ((void *) d);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,12 @@ void * cx_ln(void *data, short int type, int length, int *newlength, short int *
|
|||
void * cx_exp(void *data, short int type, int length, int *newlength, short int *newtype);
|
||||
void * cx_sqrt(void *data, short int type, int length, int *newlength, short int *newtype);
|
||||
void * cx_sin(void *data, short int type, int length, int *newlength, short int *newtype);
|
||||
void * cx_sinh(void *data, short int type, int length, int *newlength, short int *newtype);
|
||||
void * cx_cos(void *data, short int type, int length, int *newlength, short int *newtype);
|
||||
|
||||
void * cx_cosh(void *data, short int type, int length, int *newlength, short int *newtype);
|
||||
void * cx_tan(void *data, short int type, int length, int *newlength, short int *newtype);
|
||||
void * cx_tanh(void *data, short int type, int length, int *newlength, short int *newtype);
|
||||
void * cx_atan(void *data, short int type, int length, int *newlength, short int *newtype);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -36,87 +36,6 @@ extern double gauss0(void); /* from randnumb.c */
|
|||
extern int poisson(double); /* from randnumb.c */
|
||||
extern double exprand(double); /* from randnumb.c */
|
||||
|
||||
static double *
|
||||
d_tan(double *dd, int length)
|
||||
{
|
||||
double *d;
|
||||
int i;
|
||||
|
||||
d = alloc_d(length);
|
||||
for (i = 0; i < length; i++) {
|
||||
rcheck(cos(degtorad(dd[i])) != 0, "tan");
|
||||
d[i] = sin(degtorad(dd[i])) / cos(degtorad(dd[i]));
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
static ngcomplex_t *
|
||||
c_tan(ngcomplex_t *cc, int length)
|
||||
{
|
||||
ngcomplex_t *c;
|
||||
int i;
|
||||
|
||||
c = alloc_c(length);
|
||||
for (i = 0; i < length; i++) {
|
||||
double u, v;
|
||||
|
||||
rcheck(cos(degtorad(realpart(&cc[i]))) *
|
||||
cosh(degtorad(imagpart(&cc[i]))), "tan");
|
||||
rcheck(sin(degtorad(realpart(&cc[i]))) *
|
||||
sinh(degtorad(imagpart(&cc[i]))), "tan");
|
||||
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;
|
||||
}
|
||||
|
||||
void *
|
||||
cx_tan(void *data, short int type, int length, int *newlength, short int *newtype)
|
||||
{
|
||||
*newlength = length;
|
||||
if (type == VF_REAL) {
|
||||
*newtype = VF_REAL;
|
||||
return (void *) d_tan((double *) data, length);
|
||||
} else {
|
||||
*newtype = VF_COMPLEX;
|
||||
return (void *) c_tan((ngcomplex_t *) data, length);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void *
|
||||
cx_atan(void *data, short int type, int length, int *newlength, short int *newtype)
|
||||
{
|
||||
double *d;
|
||||
|
||||
d = alloc_d(length);
|
||||
*newtype = VF_REAL;
|
||||
*newlength = length;
|
||||
if (type == VF_COMPLEX) {
|
||||
ngcomplex_t *cc = (ngcomplex_t *) data;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
d[i] = radtodeg(atan(realpart(&cc[i])));
|
||||
} else {
|
||||
double *dd = (double *) data;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
d[i] = radtodeg(atan(dd[i]));
|
||||
}
|
||||
return ((void *) d);
|
||||
}
|
||||
|
||||
|
||||
static double
|
||||
cx_max_local(void *data, short int type, int length)
|
||||
|
|
|
|||
|
|
@ -7,8 +7,7 @@
|
|||
#define CMATH2_H_INCLUDED
|
||||
|
||||
|
||||
void * cx_tan(void *data, short int type, int length, int *newlength, short int *newtype);
|
||||
void * cx_atan(void *data, short int type, int length, int *newlength, short int *newtype);
|
||||
|
||||
void * cx_norm(void *data, short int type, int length, int *newlength, short int *newtype);
|
||||
void * cx_uminus(void *data, short int type, int length, int *newlength, short int *newtype);
|
||||
void * cx_rnd(void *data, short int type, int length, int *newlength, short int *newtype);
|
||||
|
|
|
|||
Loading…
Reference in New Issue