⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmath1.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
字号:
/**********Copyright 1990 Regents of the University of California.  All rights reserved.Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group**********//* * Routines to do complex mathematical functions. These routines require * the -lm libraries. We sacrifice a lot of space to be able * to avoid having to do a seperate call for every vector element, * but it pays off in time savings.  These routines should never * allow FPE's to happen. * * Complex functions are called as follows: *  cx_something(data, type, length, &newlength, &newtype), *  and return a char * that is cast to complex or double. * */#include "spice.h"#include "cpdefs.h"#include "ftedefs.h"#include "ftedata.h"#include "ftecmath.h"#include "suffix.h"/* This flag determines whether degrees or radians are used. The radtodeg * and degtorad macros are no-ops if this is false. */bool cx_degrees = false;char *cx_mag(data, type, length, newlength, newtype)    char *data;    short type;    int length;    int *newlength;    short *newtype;{    double *d = alloc_d(length);    double *dd = (double *) data;    complex *cc = (complex *) data;    int i;    *newlength = length;    *newtype = VF_REAL;    if (type == VF_REAL)        for (i = 0; i < length; i++)            d[i] = FTEcabs(dd[i]);    else        for (i = 0; i < length; i++)            d[i] = cmag(&cc[i]);    return ((char *) d);}char *cx_ph(data, type, length, newlength, newtype)    char *data;    short type;    int length;    int *newlength;    short *newtype;{    double *d = alloc_d(length);    complex *cc = (complex *) data;    int i;    *newlength = length;    *newtype = VF_REAL;    if (type == VF_COMPLEX)        for (i = 0; i < length; i++) {            d[i] = radtodeg(cph(&cc[i]));        }    /* Otherwise it is 0, but tmalloc zeros the stuff already. */    return ((char *) d);}/* If this is pure imaginary we might get real, but never mind... */char *cx_j(data, type, length, newlength, newtype)    char *data;    short type;    int length;    int *newlength;    short *newtype;{    complex *c = alloc_c(length);    complex *cc = (complex *) data;    double *dd = (double *) data;    int i;    *newlength = length;    *newtype = VF_COMPLEX;    if (type == VF_COMPLEX)        for (i = 0; i < length; i++) {            realpart(&c[i]) = - imagpart(&cc[i]);            imagpart(&c[i]) = realpart(&cc[i]);        }    else        for (i = 0; i < length; i++) {            imagpart(&c[i]) = dd[i];            /* Real part is already 0. */        }    return ((char *) c);}char *cx_real(data, type, length, newlength, newtype)    char *data;    short type;    int length;    int *newlength;    short *newtype;{    double *d = alloc_d(length);    double *dd = (double *) data;    complex *cc = (complex *) data;    int i;    *newlength = length;    *newtype = VF_REAL;    if (type == VF_COMPLEX)        for (i = 0; i < length; i++)            d[i] = realpart(&cc[i]);    else        for (i = 0; i < length; i++)            d[i] = dd[i];    return ((char *) d);}char *cx_imag(data, type, length, newlength, newtype)    char *data;    short type;    int length;    int *newlength;    short *newtype;{    double *d = alloc_d(length);    double *dd = (double *) data;    complex *cc = (complex *) data;    int i;    *newlength = length;    *newtype = VF_REAL;    if (type == VF_COMPLEX)        for (i = 0; i < length; i++)            d[i] = imagpart(&cc[i]);    else        for (i = 0; i < length; i++)            d[i] = dd[i];    return ((char *) d);}/* This is obsolete... */char *cx_pos(data, type, length, newlength, newtype)    char *data;    short type;    int length;    int *newlength;    short *newtype;{    double *d = alloc_d(length);    double *dd = (double *) data;    complex *cc = (complex *) data;    int i;    *newlength = length;    *newtype = VF_REAL;    if (type == VF_COMPLEX)        for (i = 0; i < length; i++)            d[i] = ((realpart(&cc[i]) > 0.0) ? 1.0 : 0.0);    else        for (i = 0; i < length; i++)            d[i] = ((dd[i] > 0.0) ? 1.0 : 0.0);    return ((char *) d);}char *cx_db(data, type, length, newlength, newtype)    char *data;    short type;    int length;    int *newlength;    short *newtype;{    double *d = alloc_d(length);    double *dd = (double *) data;    complex *cc = (complex *) data;    double tt;    int i;    *newlength = length;    *newtype = VF_REAL;    if (type == VF_COMPLEX)        for (i = 0; i < length; i++) {            tt = cmag(&cc[i]);            rcheck(tt > 0, "db");	    /*            if (tt == 0.0)                d[i] = 20.0 * - log(HUGE);            else	    */	    d[i] = 20.0 * log10(tt);        }    else        for (i = 0; i < length; i++) {            rcheck(dd[i] > 0, "db");	    /*            if (dd[i] == 0.0)                d[i] = 20.0 * - log(HUGE);            else	    */	    d[i] = 20.0 * log10(dd[i]);        }    return ((char *) d);}char *cx_log(data, type, length, newlength, newtype)    char *data;    short type;    int length;    int *newlength;    short *newtype;{    double *d, td;    complex *c;    double *dd = (double *) data;    complex *cc = (complex *) data;    int i;    if (type == VF_REAL) {        d = alloc_d(length);        *newtype = VF_REAL;    } else {        c = alloc_c(length);        *newtype = VF_COMPLEX;    }    *newlength = length;    if (type == VF_COMPLEX) {        for (i = 0; i < length; i++) {            td = cmag(&cc[i]);            /* Perhaps we should trap when td = 0.0, but Ken wants             * this to be possible...             */            rcheck(td >= 0, "log");            if (td == 0.0) {                realpart(&c[i]) = - log10(HUGE);                imagpart(&c[i]) = 0.0;            } else {                realpart(&c[i]) = log10(td);                imagpart(&c[i]) = atan2(imagpart(&cc[i]),                        realpart(&cc[i]));            }        }        return ((char *) c);    } else {        for (i = 0; i < length; i++) {            rcheck(dd[i] >= 0, "log");            if (dd[i] == 0.0)                d[i] = - log10(HUGE);            else                 d[i] = log10(dd[i]);        }        return ((char *) d);    }}char *cx_ln(data, type, length, newlength, newtype)    char *data;    short type;    int length;    int *newlength;    short *newtype;{    double *d, td;    complex *c;    double *dd = (double *) data;    complex *cc = (complex *) data;    int i;    if (type == VF_REAL) {        d = alloc_d(length);        *newtype = VF_REAL;    } else {        c = alloc_c(length);        *newtype = VF_COMPLEX;    }    *newlength = length;    if (type == VF_COMPLEX) {        for (i = 0; i < length; i++) {            td = cmag(&cc[i]);            rcheck(td >= 0, "ln");            if (td == 0.0) {                realpart(&c[i]) = - log(HUGE);                imagpart(&c[i]) = 0.0;            } else {                realpart(&c[i]) = log(td);                imagpart(&c[i]) = atan2(imagpart(&cc[i]),                    realpart(&cc[i]));            }        }        return ((char *) c);    } else {        for (i = 0; i < length; i++) {            rcheck(dd[i] >= 0, "ln");            if (dd[i] == 0.0)                d[i] = - log(HUGE);            else                d[i] = log(dd[i]);        }        return ((char *) d);    }}char *cx_exp(data, type, length, newlength, newtype)    char *data;    short type;    int length;    int *newlength;    short *newtype;{    double *d, td;    complex *c;    double *dd = (double *) data;    complex *cc = (complex *) data;    int i;    if (type == VF_REAL) {        d = alloc_d(length);        *newtype = VF_REAL;    } else {        c = alloc_c(length);        *newtype = VF_COMPLEX;    }    *newlength = length;    if (type == VF_COMPLEX) {        for (i = 0; i < length; i++) {            td = exp(realpart(&cc[i]));            realpart(&c[i]) = td * cos(imagpart(&cc[i]));            imagpart(&c[i]) = td * sin(imagpart(&cc[i]));        }        return ((char *) c);    } else {        for (i = 0; i < length; i++)            d[i] = exp(dd[i]);        return ((char *) d);    }}char *cx_sqrt(data, type, length, newlength, newtype)    char *data;    short type;    int length;    int *newlength;    short *newtype;{    double *d;    complex *c;    double *dd = (double *) data;    complex *cc = (complex *) data;    int i, cres = (type == VF_REAL) ? 0 : 1;    if (type == VF_REAL)        for (i = 0; i < length; i++)            if (dd[i] < 0.0)                cres = 1;    if (cres) {        c = alloc_c(length);        *newtype = VF_COMPLEX;    } else {        d = alloc_d(length);        *newtype = VF_REAL;    }    *newlength = length;    if (type == VF_COMPLEX) {        for (i = 0; i < length; i++) {            if (realpart(&cc[i]) == 0.0) {                if (imagpart(&cc[i]) == 0.0) {                    realpart(&c[i]) = 0.0;                    imagpart(&c[i]) = 0.0;                } else if (imagpart(&cc[i]) > 0.0) {                    realpart(&c[i]) = sqrt (0.5 *                            imagpart(&cc[i]));                    imagpart(&c[i]) = realpart(&c[i]);                } else {                     imagpart(&c[i]) = sqrt( -0.5 *                             imagpart(&cc[i]));                    realpart(&c[i]) = - imagpart(&c[i]);                }            } else if (realpart(&cc[i]) > 0.0) {                if (imagpart(&cc[i]) == 0.0) {                    realpart(&c[i]) =                         sqrt(realpart(&cc[i]));                    imagpart(&c[i]) = 0.0;                } else if (imagpart(&cc[i]) < 0.0) {                    realpart(&c[i]) = -sqrt(0.5 *                         (cmag(&cc[i]) + realpart(&cc[i])));                } else {                    realpart(&c[i]) = sqrt(0.5 *                         (cmag(&cc[i]) + realpart(&cc[i])));                }                imagpart(&c[i]) = imagpart(&cc[i]) / (2.0 *                         realpart(&c[i]));            } else { /* realpart(&cc[i]) < 0.0) */                if (imagpart(&cc[i]) == 0.0) {                    realpart(&c[i]) = 0.0;                    imagpart(&c[i]) =                        sqrt(- realpart(&cc[i]));                } else {                    if (imagpart(&cc[i]) < 0.0)                        imagpart(&c[i]) = - sqrt(0.5 *                            (cmag(&cc[i]) -                            realpart(&cc[i])));                    else                        imagpart(&c[i]) = sqrt(0.5 *                            (cmag(&cc[i]) -                            realpart(&cc[i])));                    realpart(&c[i]) = imagpart(&cc[i]) /                         (2.0 * imagpart(&c[i]));                }            }        }        return ((char *) c);    } else if (cres) {        for (i = 0; i < length; i++)            if (dd[i] < 0.0)                imagpart(&c[i]) = sqrt(- dd[i]);            else                realpart(&c[i]) = sqrt(dd[i]);        return ((char *) c);    } else {        for (i = 0; i < length; i++)            d[i] = sqrt(dd[i]);        return ((char *) d);    }}char *cx_sin(data, type, length, newlength, newtype)    char *data;    short type;    int length;    int *newlength;    short *newtype;{    double *d;    complex *c;    double *dd = (double *) data;    complex *cc = (complex *) data;    int i;    if (type == VF_REAL) {        d = alloc_d(length);        *newtype = VF_REAL;    } else {        c = alloc_c(length);        *newtype = VF_COMPLEX;    }    *newlength = length;    if (type == VF_COMPLEX) {        for (i = 0; i < length; i++) {            realpart(&c[i]) = sin(degtorad(realpart(&cc[i]))) *                    cosh(degtorad(imagpart(&cc[i])));            imagpart(&c[i]) = cos(degtorad(realpart(&cc[i]))) *                    sinh(degtorad(imagpart(&cc[i])));        }        return ((char *) c);    } else {        for (i = 0; i < length; i++)            d[i] = sin(degtorad(dd[i]));        return ((char *) d);    }}char *cx_cos(data, type, length, newlength, newtype)    char *data;    short type;    int length;    int *newlength;    short *newtype;{    double *d;    complex *c;    double *dd = (double *) data;    complex *cc = (complex *) data;    int i;    if (type == VF_REAL) {        d = alloc_d(length);        *newtype = VF_REAL;    } else {        c = alloc_c(length);        *newtype = VF_COMPLEX;    }    *newlength = length;    if (type == VF_COMPLEX) {        for (i = 0; i < length; i++) {            realpart(&c[i]) = cos(degtorad(realpart(&cc[i]))) *                    cosh(degtorad(imagpart(&cc[i])));            imagpart(&c[i]) = - sin(degtorad(realpart(&cc[i]))) *                    sinh(degtorad(imagpart(&cc[i])));        }        return ((char *) c);    } else {        for (i = 0; i < length; i++)            d[i] = cos(degtorad(dd[i]));        return ((char *) d);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -