예제 #1
0
int dblhashLength(dblhash_ *h, unsigned int *length)
{
    ReturnErrIf(h == NULL);
	ReturnErrIf(length == NULL);
	*length = h->records_count;
	return 0;
}
예제 #2
0
int dblhashRemove(dblhash_ *h, char *key)
{
    unsigned int code;
    record_ *recs;
    unsigned int off, ind, size;

	ReturnErrIf(h == NULL);
	ReturnErrIf(key == NULL);

	code = strhash(key);

    recs = h->records;
    size = sizes[h->size_index];
    ind = code % size;
    off = 0;

    while (recs[ind].hash) {
        if ((code == recs[ind].hash) && (recs[ind].key != NULL)) {
			if(!strcmp(key, recs[ind].key)) {
				/* Do not erase hash, so probes for collisions succeed */
				if((recs[ind].freeMem != 'n') && (recs[ind].key != NULL)) {
					free(recs[ind].key);
				}
				recs[ind].key = NULL;
				recs[ind].value = HUGE_VAL;
				h->records_count--;
				return 0;
			}
        }
        ind = (code + (int)pow(++off, 2)) % size;
    }

	ReturnErr("Couldn't find %s", key);
}
예제 #3
0
int integratorInitialize(integrator_ *r, double ic, double *ydtdx)
{
	int i;
	ReturnErrIf(r == NULL);
	ReturnErrIf(ydtdx == NULL);

	r->ydtdx = ydtdx;

	r->y0 = 0.0;
	r->dydx0 = 0.0;
	r->n = 0;

	for(i = 0; i < N; i++) {
		r->t[i] = 0.0;
		r->h[i] = r->control->tstop;
		r->y[i] = 0.0;
		r->f[i] = *ydtdx;
		r->x[i] = ic;
		r->f[i] = (*r->ydtdx);
	}

	if(r->units == 'V') {
		r->abstol = r->control->vntol;
	} else if(r->units == 'A') {
		r->abstol = r->control->abstol;
	} else if(r->units == 'F') {
		r->abstol = r->control->captol;
	} else {
		ReturnErr("Unsupported units type");
	}

	return 0;
}
예제 #4
0
int dblhashFindPtr(dblhash_ *h, char *key, double **value)
{
    record_ *recs;
    unsigned int off, ind, size;
    unsigned int code;

	ReturnErrIf(h == NULL);
	ReturnErrIf(key == NULL);
	ReturnErrIf(value == NULL);

	code = strhash(key);

    recs = h->records;
    size = sizes[h->size_index];
    ind = code % size;
    off = 0;

    /* search on hash which remains even if a record has been removed,
     * so hash_remove() does not need to move any collision records
	 */
    while (recs[ind].hash) {
        if ((code == recs[ind].hash) && (recs[ind].key != NULL)) {
			if(!strcmp(key, recs[ind].key)) {
				*value = &recs[ind].value;
				return 0;
			}
		}
        ind = (code + (int)pow(++off,2)) % size;
    }

    	/* Couldn't find the key */
	*value = NULL;
    return 0;
}
예제 #5
0
파일: history.c 프로젝트: Narrat/eispice
int historyGetTime(history_ *r, double *time)
{
	ReturnErrIf(r == NULL);
	ReturnErrIf(time == NULL);
	*time = r->time;
	return 0;
}
예제 #6
0
static int dblhashGrow(dblhash_ *h)
{
	int i;
    record_ *old_recs, *new_recs;
    unsigned int old_recs_length;

	Debug("Growing Hash %p", h);

	ReturnErrIf(h->size_index == (sizes_count - 1));

    old_recs_length = sizes[h->size_index];
    old_recs = h->records;

	new_recs = calloc(sizes[++h->size_index], sizeof(record_));
	ReturnErrIf(new_recs == NULL);
	h->records = new_recs;

    h->records_count = 0;

    /* rehash table */
    for (i=0; i < old_recs_length; i++) {
        if (old_recs[i].hash && old_recs[i].key) {
            ReturnErrIf(dblhashAdd(h, old_recs[i].key, old_recs[i].freeMem,
					old_recs[i].value));
		}
	}

    free(old_recs);

    return 0;
}
예제 #7
0
파일: history.c 프로젝트: Narrat/eispice
int historyRecall(history_ *r, double *data, int length)
{
	ReturnErrIf(r == NULL);
	ReturnErrIf(data == NULL);
	ReturnErrIf(length != r->length);
	memcpy(data, r->data, length*sizeof(double));
	return 0;
}
예제 #8
0
파일: history.c 프로젝트: Narrat/eispice
int historyGetAllData(history_ *r, double *data, int length)
{
	ReturnErrIf(r == NULL);
	ReturnErrIf(data == NULL);
	ReturnErrIf(length != (r->length + 1));
	data[0] = r->time;
	memcpy(&data[1], r->data, r->length*sizeof(double));
	return 0;
}
예제 #9
0
파일: history.c 프로젝트: Narrat/eispice
int historyGetData(history_ *r, double *data, int index)
{
	ReturnErrIf(r == NULL);
	ReturnErrIf(data == NULL);
	ReturnErrIf(index < 0);
	ReturnErrIf(index >= r->length);
	*data = r->data[index];
	return 0;
}
예제 #10
0
int integratorDestroy(integrator_ **r)
{
	ReturnErrIf(r == NULL);
	ReturnErrIf((*r) == NULL);
	Debug("Destroying NI %p", (*r));

	free(*r);
	*r = NULL;

	return 0;
}
예제 #11
0
int integratorIntegrate(integrator_ *r, double x0, double *dydx0, double *y0)
{
	double t0, mult;

	ReturnErrIf(r == NULL);
	ReturnErrIf(dydx0 == NULL);
	ReturnErrIf(y0 == NULL);
	ReturnErrIf(isnan(x0));

	/* Only step time when time is increasing, the simulator can search back
	 * in time for a more appropiate point (i.e. based on next step above)
	 */
	t0 = r->control->time;
	ReturnNaNIf(isnan(t0));
	if(t0 > r->t[(r->n+1)%N]) {
		r->n++;
	}

	/* Set New Time */
	r->h[r->n%N] = t0 - r->t[r->n%N];
	r->t[(r->n+1)%N] = t0;

	/* Record X, Y, and F*/
	r->x[r->n%N] = x0;
	r->y[r->n%N] = r->dydx0 * x0 - r->y0;
	r->f[r->n%N] = (*r->ydtdx);

	/* Calculate Next dydx0 and y0 Using Numerical Integration */

	if(r->control->integratorOrder < 2) { /* Backward-Euler */
		*dydx0 = r->f[(r->n-1)%N] / r->h[r->n%N];
		*y0 = (*dydx0) * r->x[r->n%N];
	} else { /* Trapazoidal */
		*dydx0 = 2.0 * r->f[r->n%N] / r->h[r->n%N];
		mult = r->f[r->n%N]/r->f[(r->n-1)%N];
		if(isnan(mult)) {
			mult = 1/r->control->gmin;
		}
		/* y multiplier compensates for a changing function value,
				i.e. not your basic trapazoidal integration, refer to
				"Electronic Circuit and System Simulation Methods" by
				Pillage, Rohrer, and Visweswariah page 310 for more
				details */
		*y0 = (*dydx0) * r->x[r->n%N] + mult*r->y[r->n%N];

	}


	/* Store values for next time */
	r->dydx0 = *dydx0;
	r->y0 = *y0;

	return 0;
}
예제 #12
0
int devicePrint(device_ *r, void *data)
{
	ReturnErrIf(r == NULL);
	ReturnErrIf(data != NULL);
	ReturnErrIf(r->class == NULL);
	if(r->class->print != NULL) {
		ReturnErrIf(r->class->print(r));
	}

	return 0;
}
예제 #13
0
int deviceIntegrate(device_ *r, void *data)
{
	ReturnErrIf(r == NULL);
	ReturnErrIf(data != NULL);
	ReturnErrIf(r->class == NULL);
	if(r->class->integrate != NULL) {
		ReturnErrIf(r->class->integrate(r));
	}

	return 0;
}
예제 #14
0
int deviceLoad(device_ *r, void *data)
{
	ReturnErrIf(r == NULL);
	ReturnErrIf(data != NULL);
	ReturnErrIf(r->class == NULL);
	if(r->class->load != NULL) {
		ReturnErrIf(r->class->load(r));
	}

	return 0;
}
예제 #15
0
int deviceInitStep(device_ *r, void *data)
{
	ReturnErrIf(r == NULL);
	ReturnErrIf(data != NULL);
	ReturnErrIf(r->class == NULL);
	if(r->class->initStep != NULL) {
		ReturnErrIf(r->class->initStep(r));
	}

	return 0;
}
예제 #16
0
int checkbreakDestroy(checkbreak_ **r)
{
	ReturnErrIf(r == NULL);
	ReturnErrIf((*r) == NULL);
	Debug("Destroying Break Check %p", *r);

	free(*r);
	*r = NULL;

	return 0;
}
예제 #17
0
파일: calc.c 프로젝트: Narrat/eispice
int calcDiff(calc_ *r, char *variable, double *solution)
{
	tokenSolveArgs_ args;
	
	ReturnErrIf(r == NULL);
	ReturnErrIf(solution == NULL);
	ReturnErrIf(variable == NULL);
	
	args.parser = r->parser;
	args.solution = solution;
	
	ReturnErrIf(hashFind(r->variables, variable, (void*)&args.diffVariable));
	ReturnErrIf(args.diffVariable == NULL, 
			"Couldn't find variable %s.", variable);
	
	/* Put Parser in differentiation mode */
	Debug("%s", ParseTokenName(TOKEN_DIFF));
	Parse(r->parser, TOKEN_DIFF, NULL, solution);
	ReturnErrIf(isnan(*solution), "Parser failed");
	
	ReturnErrIf(listExecute(r->tokens, (listExecute_)tokenSolve, &args));
	ReturnErrIf(isnan(*solution), "Parser failed");
	
	return 0;
}
예제 #18
0
int waveformNextStep(waveform_ *r, double *nextStep)
{
	double tp, time;
	ReturnErrIf(r == NULL);
	ReturnErrIf(nextStep == NULL);

	time = r->control->time;

	switch(r->type) {
	case 'p': /* pulse */
		tp = fmod(time,  *r->d.pulse.per);
		*nextStep = *r->d.pulse.td - tp;
		if(*nextStep > 0) break;
		*nextStep += *r->d.pulse.tr;
		if(*nextStep > 0) break;
		*nextStep += *r->d.pulse.pw;
		if(*nextStep > 0) break;
		*nextStep += *r->d.pulse.tf;
		if(*nextStep > 0) break;
		*nextStep = *r->d.pulse.per - tp;
		break;
	case 'g': /* gauss */
		/* Should be a smooth waveform so don't expect break-points */
		break;
	case 's': /* sin */
		if(time < *r->d.sin.td) {
			*nextStep = *r->d.sin.td;
		}
		break;
	case 'e': /* exp */
		if(time < *r->d.exp.td1) {
			*nextStep = *r->d.exp.td1 - time;
		} else if(time < *r->d.exp.td2) {
			*nextStep = *r->d.exp.td2 - time;
		}
		break;
	case 'l': /* pwl */
	case 'c': /* pwc */
		ReturnErrIf(piecewiseGetNextX(r->d.pw.pw, &r->d.pw.index, time, &tp));
		if(tp != HUGE_VAL) {
			*nextStep = tp - time;
		}
		break;
	default:
		break;
	}

	return 0;
}
예제 #19
0
int deviceStep(device_ *r, int *breakPoint)
{
	int localBreakPoint = 0;

	ReturnErrIf(r == NULL);
	ReturnErrIf(breakPoint == NULL);
	ReturnErrIf(r->class == NULL);

	if(r->class->step != NULL) {
		ReturnErrIf(r->class->step(r, &localBreakPoint));
		*breakPoint = (*breakPoint) || (localBreakPoint);
	}

	return 0;
}
예제 #20
0
int deviceLinearize(device_ *r, int *linear)
{
	int localLinear = 1;

	ReturnErrIf(r == NULL);
	ReturnErrIf(linear == NULL);
	ReturnErrIf(r->class == NULL);

	if(r->class->linearize != NULL) {
			ReturnErrIf(r->class->linearize(r, &localLinear));
			*linear = (*linear) && (localLinear);
	}

	return 0;
}
예제 #21
0
파일: calc.c 프로젝트: Narrat/eispice
int calcSolve(calc_ *r, double *solution)
{
	tokenSolveArgs_ args;
	
	ReturnErrIf(r == NULL);
	ReturnErrIf(solution == NULL);
	
	args.parser = r->parser;
	args.solution = solution;
	args.diffVariable = NULL;
	
	ReturnErrIf(listExecute(r->tokens, (listExecute_)tokenSolve, &args));
	ReturnErrIf(isnan(*solution), "Parser failed");
	
	return 0;
}
예제 #22
0
int checkbreakIsBreak(checkbreak_ *r, double x)
{
	ReturnErrIf(r == NULL);

	/* Only step time when time is increasing, the simulator can search back
	 * in time for a more appropiate point (i.e. based on next step above)
	 */
	if(r->control->time > r->t[r->n%N]) {
		r->n++;
	}

	/* update x, t, and angle */
	r->x[r->n%N] = x;
	r->t[r->n%N] = r->control->time;
	r->theta[r->n%N] = atan2(r->x[r->n%N] - r->x[(r->n-1)%N],
			r->t[r->n%N] - r->t[(r->n-1)%N]);

	if(fabs(r->theta[r->n%N] - r->theta[(r->n-1)%N]) > r->maxAngle) {
		Debug("Break at %e with angles %e,%e",
				r->t[r->n%N], r->theta[r->n%N], r->theta[(r->n-1)%N]);
		return 1;
	}

	return 0;
}
예제 #23
0
int checkbreakInitialize(checkbreak_ *r, double ic)
{
	int i;

	ReturnErrIf(r == NULL);

	/* Make a local copy, this allows the control value to
		be changed between runs */
	if(r->units == 'V') {
		r->maxAngle = r->control->maxAngleV;
	} else if(r->units == 'A') {
		r->maxAngle = r->control->maxAngleA;
	} else {
		ReturnErr("Unsupported unit type %c, should be 'A' or 'V'", r->units);
	}

	for(i = 0; i < N; i++) {
		r->x[i] = ic;
		r->t[i] = 0.0;
	}

	r->n = 0;

	return 0;
}
예제 #24
0
int integratorNextStep(integrator_ *r, double x0, double *h)
{
	double y0, ey = 0.0, eyp, e, dd;

	ReturnErrIf(r == NULL);
	ReturnErrIf(h == NULL);
	ReturnErrIf(isnan(x0));

	y0 =  r->dydx0 * x0 - r->y0;

	/* Calculate y error */
	ey = r->control->reltol * MaxAbs(r->y[r->n%N], y0) + r->abstol;

	/* Calculate y' error */
	eyp = r->control->reltol * MaxAbs(MaxAbs(x0, r->x[r->n%N]) *
			(*r->ydtdx / r->h[r->n%N]), r->control->chgtol);

	e = MaxAbs(eyp, ey);

	/* Calculate Estimated Error of Numerical Intergration */
	if(r->control->integratorOrder < 2) { /* Backward-Euler */
		dd = DD2(((*r->ydtdx) * x0),
				(r->f[r->n%N] * r->x[r->n%N]),
				(r->f[(r->n-1)%N] * r->x[(r->n-1)%N]),
				r->h[r->n%N],
				r->h[(r->n-1)%N]);
		dd *= 1.0/2.0;
		*h = r->control->trtol * e / MaxAbs(dd , r->abstol);
	} else { /* Trapazoidal */
		dd = DD3(((*r->ydtdx) * x0),
				(r->f[r->n%N] * r->x[(r->n)%N]),
				(r->f[(r->n-1)%N] * r->x[(r->n-1)%N]),
				(r->f[(r->n-2)%N] * r->x[(r->n-2)%N]),
				r->h[r->n%N],
				r->h[(r->n-1)%N],
				r->h[(r->n-2)%N]);
				/* See page 309 of "The Spice Book" */
		dd *= 1.0/12.0;
		*h = sqrtf(r->control->trtol * e / MaxAbs(dd , r->abstol));
	}

	Debug("h = %e, e = %e, dd = %e", *h, e, dd);
	ReturnErrIf(isnan(*h));

	return 0;
}
예제 #25
0
int deviceMinStep(device_ *r, double *minStep)
{
	double localMinStep = 0.0;

	ReturnErrIf(r == NULL);
	ReturnErrIf(minStep == NULL);
	ReturnErrIf(r->class == NULL);

	if(r->class->minStep != NULL) {
			ReturnErrIf(r->class->minStep(r, &localMinStep));
			if((localMinStep > 0.0) && (localMinStep < *minStep)) {
				*minStep = localMinStep;
			}
	}

	return 0;
}
예제 #26
0
int deviceNextStep(device_ *r, double *nextStep)
{
	double localNextStep = 0.0;

	ReturnErrIf(r == NULL);
	ReturnErrIf(nextStep == NULL);
	ReturnErrIf(r->class == NULL);

	if(r->class->nextStep != NULL) {
			ReturnErrIf(r->class->nextStep(r, &localNextStep));
			if((localNextStep > r->control->minstep) &&
					(localNextStep < *nextStep)) {
				*nextStep = localNextStep;
			}
	}

	return 0;
}
예제 #27
0
int waveformDestroy(waveform_ **r)
{
	ReturnErrIf(r == NULL);
	ReturnErrIf((*r) == NULL);
	Debug("Destroying Waveform %p", *r);

	if((((*r)->type == 'l') || ((*r)->type == 'c')) &&
			((*r)->d.pw.pw != NULL)) {
		if(piecewiseDestroy(&(*r)->d.pw.pw)) {
			Warn("Error destroying piecewise");
		}
	}

	free(*r);
	*r = NULL;

	return 0;
}
예제 #28
0
int dblhashFind(dblhash_ *h, char *key, double *value)
{
    double *valuePtr;
	ReturnErrIf(dblhashFindPtr(h, key, &valuePtr));
	if(valuePtr != NULL) {
		*value = *valuePtr;
	} else {
		*value = HUGE_VAL;
	}
	return 0;
}
예제 #29
0
파일: history.c 프로젝트: Narrat/eispice
int historyDestroy(history_ *r)
{
	ReturnErrIf(r == NULL);
	
	if(r->data != NULL) {
		free(r->data);
	}
	
	free(r);
	
	return 0;
}
예제 #30
0
int dblhashDestroy(dblhash_ **h)
{
	int i;

	ReturnErrIf(h == NULL);
	ReturnErrIf((*h) == NULL);
	Debug("Destroying Hash %p", *h);

	if((*h)->records != NULL) {
		for(i = 0; i < sizes[(*h)->size_index]; i++) {
			if(((*h)->records[i].freeMem != 'n') &&
					((*h)->records[i].key != NULL)) {
				free((*h)->records[i].key);
			}
		}
		free((*h)->records);
	}

	free(*h);
	*h = NULL;

	return 0;
}