157 lines
3.1 KiB
C
157 lines
3.1 KiB
C
/**********
|
|
Copyright 1991 Regents of the University of California. All rights reserved.
|
|
Author: 1987 Kartikeya Mayaram, U. C. Berkeley CAD Group
|
|
**********/
|
|
|
|
#include "ngspice/ngspice.h"
|
|
#include "ngspice/numenum.h"
|
|
#include "ngspice/cidersupt.h"
|
|
|
|
/* compute the coefficient for the integration and predictor methods */
|
|
/* based on the Lagrange polynomial method in Liniger et. al. */
|
|
|
|
void
|
|
computeIntegCoeff(int method, int order, double *intCoeff, double *delta)
|
|
{
|
|
int i, j, k;
|
|
double sum, temp, preMult;
|
|
double num, denom, prod;
|
|
|
|
switch( method ) {
|
|
case BDF:
|
|
/* determine coeff[0] first */
|
|
|
|
sum = 0.0;
|
|
temp = 0.0;
|
|
for( j = 0 ; j < order; j++ ) {
|
|
temp += delta[ j ];
|
|
sum += 1.0 / temp;
|
|
}
|
|
intCoeff[ 0 ] = sum;
|
|
|
|
/* now compute the higher order coefficients */
|
|
for( j = 1; j <= order ; j++ ) {
|
|
/* compute the pre multiplier */
|
|
temp = 0.0;
|
|
for( i = 0; i < j; i++ ) {
|
|
temp += delta[ i ];
|
|
}
|
|
preMult = 1.0 / temp;
|
|
prod = 1.0;
|
|
/* now compute the product */
|
|
for( i = 1; i <= order; i++ ) {
|
|
/* product loop */
|
|
if( i != j ) {
|
|
num = 0.0;
|
|
for( k = 0; k < i; k++ ) {
|
|
/* first the numerator */
|
|
num += delta[ k ];
|
|
}
|
|
if( i > j ) {
|
|
/* denom is positive */
|
|
denom = 0.0;
|
|
for( k = j; k < i; k++ ) {
|
|
denom += delta[ k ];
|
|
}
|
|
}
|
|
else {
|
|
/* i < j */
|
|
denom = 0.0;
|
|
for( k = i; k < j; k++ ) {
|
|
denom += delta[ k ];
|
|
}
|
|
denom = -denom;
|
|
}
|
|
prod *= num / denom ;
|
|
}
|
|
}
|
|
intCoeff[ j ] = -preMult * prod;
|
|
}
|
|
break;
|
|
case TRAPEZOIDAL:
|
|
default:
|
|
switch( order ) {
|
|
case 1:
|
|
temp = 1.0 / delta[ 0 ];
|
|
intCoeff[ 0 ] = temp;
|
|
intCoeff[ 1 ] = -temp;
|
|
break;
|
|
case 2:
|
|
temp = 2.0 / delta[ 0 ];
|
|
intCoeff[ 0 ] = temp;
|
|
intCoeff[ 1 ] = -temp;
|
|
intCoeff[ 2 ] = -1.0;
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void
|
|
computePredCoeff(int method, int order, double *predCoeff, double *delta)
|
|
{
|
|
int i, j, k;
|
|
double num, denom, prod;
|
|
|
|
if( method == TRAPEZOIDAL && order > 2 ) {
|
|
printf("\n computePredCoeff: order > 2 for trapezoidal");
|
|
exit( -1 );
|
|
}
|
|
for( j = 1; j <= order+1 ; j++ ) {
|
|
prod = 1.0;
|
|
/* now compute the product */
|
|
for( i = 1; i <= order+1; i++ ) {
|
|
/* product loop */
|
|
if( i != j ) {
|
|
num = 0.0;
|
|
for( k = 0; k < i; k++ ) {
|
|
/* first the numerator */
|
|
num += delta[ k ];
|
|
}
|
|
if( i > j ) {
|
|
/* denom is positive */
|
|
denom = 0.0;
|
|
for( k = j; k < i; k++ ) {
|
|
denom += delta[ k ];
|
|
}
|
|
}
|
|
else {
|
|
/* i < j */
|
|
denom = 0.0;
|
|
for( k = i; k < j; k++ ) {
|
|
denom += delta[ k ];
|
|
}
|
|
denom = -denom;
|
|
}
|
|
prod *= num / denom ;
|
|
}
|
|
}
|
|
predCoeff[ j - 1 ] = prod;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* main program to check the coefficients
|
|
main()
|
|
{
|
|
double intCoeff[ 7 ], predCoeff[ 7 ];
|
|
double delta[ 7 ];
|
|
int order = 1;
|
|
int i;
|
|
|
|
for( i = 0; i <= 6; i++ ) {
|
|
delta[ i ] = 1.0;
|
|
}
|
|
|
|
computeIntegCoeff(TRAPEZOIDAL, order, intCoeff, delta );
|
|
computePredCoeff(TRAPEZOIDAL, order, predCoeff, delta );
|
|
|
|
for(i = 0; i <= order; i++ ) {
|
|
printf("\n IntCoeff[ %d ] = %e PredCoeff[ %d ] = %e ", i, intCoeff[ i ], i, predCoeff[ i ] );
|
|
}
|
|
}
|
|
*/
|