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

📄 cfunc.mod

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 MOD
📖 第 1 页 / 共 2 页
字号:
          if (INIT==1) {  /* First pass...allocate storage for previous value... */        /* Allocate storage for last_x_value */        STATIC_VAR(last_x_value) = (double *) malloc(sizeof(double));        last_x_value = STATIC_VAR(last_x_value);        /* Allocate storage for breakpoint domain & range values */        STATIC_VAR(x) = (double *) calloc(size, sizeof(double));        x = STATIC_VAR(x);        if (x == '\0') {            cm_message_send(allocation_error);         }        STATIC_VAR(y) = (double *) calloc(size, sizeof(double));        y = STATIC_VAR(y);        if (y == '\0') {            cm_message_send(allocation_error);          }        /* Retrieve x and y values. */               for (i=0; i<size; i++) {            x[i] = PARAM(x_array[i]);            y[i] = PARAM(y_array[i]);        }                           }      else {        last_x_value = STATIC_VAR(last_x_value);        x = STATIC_VAR(x);        y = STATIC_VAR(y);    }    /* See if input_domain is absolute...if so, test against   */    /* breakpoint segments for violation of 50% rule...        */    if (PARAM(fraction) == MIF_FALSE) {        if ( 3 < size ) {            for (i=1; i<(size-2); i++) {                 /* Test for overlap...0.999999999 factor is to      */                /* prevent floating point problems with comparison. */                if ( (test1 = x[i+1] - x[i]) <                      (test2 = 0.999999999 * (2.0 * input_domain)) ) {                    cm_message_send(limit_error);                          }                }        }    }    /* Retrieve x_input value. */           x_input = INPUT(in);                                          /* If this is the first call, set *last_x_value to x_input */    if (INIT == 1)         *last_x_value=x_input;    /*** Add debugging printf statement ***/    /* printf("Last x_input=%e, Current x_input=%e,\n",            *last_x_value,x_input);    */                                                                                  /**** Add internal limiting to input value ****/    /* Determine region of input, and limit accordingly */    if ( *last_x_value < x[0] ) { /** Non-limited input less than x[0] **/        /* Obtain the test value of the input, if it has changed excessively */        if ( (x[0] - x_input) > (x[1] - x[0]) ) {            test = limit_x_value(x_input,x[0],x_input,FRACTION,last_x_value);        }        else {            test = limit_x_value(x[0],x[1],x_input,FRACTION,last_x_value);        }                /* If the test value is greater than x[0], force to x[0]  */        if ( test >= x[0] ) {            x_input = *last_x_value = x[0];            /* Alert the simulator to non-convergence */            cm_analog_not_converged();        }                                                       else {            x_input = *last_x_value = test;        }    }    else     if ( *last_x_value >= x[size-1] ) { /** Non-Limited input greater than x[size-1] **/        /* Obtain the test value of the input, if it has changed excessively */        if ( (x_input - x[size-1]) > (x[size-1] - x[size-2]) ) {            test = limit_x_value(x[size-1],x_input,x_input,FRACTION,last_x_value);        }        else {            test = limit_x_value(x[size-2],x[size-1],x_input,FRACTION,last_x_value);        }                /* If the test value is less than x[size-1], force to x[size-1]  */        /* minus some epsilon value.                                     */        if ( test < x[size-1] ) {            x_input = *last_x_value = x[size-1] - EPSILON;            /* Alert the simulator to non-convergence */            cm_analog_not_converged();        }                                                       else {            x_input = *last_x_value = test;        }    }    else {        for (i=1; i<size; i++) {            if ( *last_x_value < x[i] ) {                                              /* Obtain the test value of the input */                test = limit_x_value(x[i-1],x[i],x_input,FRACTION,last_x_value);                                /* If the test value is greater than x[i], force to x[i]  */                if ( test > x[i] ) {                    x_input = *last_x_value = x[i];                    /* Alert the simulator to non-convergence */                    cm_analog_not_converged();                    break;                }                                                               else                 /* If the test value is less than x[i-1], force to x[i-1]  */                /* minus some epsilon value...                             */                if ( test < x[i-1] ) {                    x_input = *last_x_value = x[i-1] - EPSILON;                    /* Alert the simulator to non-convergence */                    cm_analog_not_converged();                    break;                }                else { /* Use returned value for next input */                    x_input = *last_x_value = test;                     break;                }            }        }    }    /* Assign new limited value back to the input for */    /* use in the matrix calculations....             */           INPUT(in) = x_input;         /*** Add debugging printf statement ***/    /* printf("Limited x_input=%e\n\n",            x_input);    */    /**** End internal limiting ****/                                                   /* Determine segment boundaries within which x_input resides */    if (x_input <= (x[0] + x[1])/2.0) {/*** x_input below lowest midpoint ***/        dout_din = (y[1] - y[0])/(x[1] - x[0]);                            /* Compute new output */        out = y[0] + (x_input - x[0]) * dout_din;           }    else {        if (x_input >= (x[size-2] + x[size-1])/2.0) {                                    /*** x_input above highest midpoint ***/            dout_din = (y[size-1] - y[size-2]) /                          (x[size-1] - x[size-2]);            out = y[size-1] + (x_input - x[size-1]) * dout_din;        }        else { /*** x_input within bounds of end midpoints...     ***/               /*** must determine position progressively & then  ***/               /*** calculate required output.                    ***/            for (i=1; i<size; i++) {                                    if (x_input < (x[i] + x[i+1])/2.0) {                                    /* approximate position known...          */                                 lower_seg = (x[i] - x[i-1]);                    upper_seg = (x[i+1] - x[i]);                    /* Calculate input_domain about this region's breakpoint.*/                    if (PARAM(fraction) == MIF_TRUE) {  /* Translate input_domain */                                                  /* into an absolute....   */                        if ( lower_seg <= upper_seg )          /* Use lower  */                                                               /* segment    */                                                               /* for % calc.*/                            input_domain = input_domain * lower_seg;                        else                                   /* Use upper  */                                                               /* segment    */                                                               /* for % calc.*/                            input_domain = input_domain * upper_seg;                    }                         /* Set up threshold values about breakpoint... */                    threshold_lower = x[i] - input_domain;                    threshold_upper = x[i] + input_domain;                    /* Determine where x_input is within region & determine */                    /* output and partial values....                        */                    if (x_input < threshold_lower) { /* Lower linear region */                        dout_din = (y[i] - y[i-1])/lower_seg;                        out = y[i] + (x_input - x[i]) * dout_din;                    }                    else {                                if (x_input < threshold_upper) { /* Parabolic region */                            lower_slope = (y[i] - y[i-1])/lower_seg;                            upper_slope = (y[i+1] - y[i])/upper_seg;                            cm_smooth_corner(x_input,x[i],y[i],input_domain,                                        lower_slope,upper_slope,&out,&dout_din);                        }                        else {        /* Upper linear region */                            dout_din = (y[i+1] - y[i])/upper_seg;                            out = y[i] + (x_input - x[i]) * dout_din;                        }                    }                    break;  /* Break search loop...x_input has been found, */                            /* and out and dout_din have been assigned.    */                }            }        }    }    if(ANALYSIS != MIF_AC) {        /* Output DC & Transient Values */        OUTPUT(out) = out;        PARTIAL(out,in) = dout_din;    }    else {                      /* Output AC Gain */        ac_gain.real = dout_din;        ac_gain.imag= 0.0;        AC_GAIN(out,in) = ac_gain;    }} 

⌨️ 快捷键说明

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