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); }
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; }
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; }
static int waveformParseArgs(waveform_ *r, double *args[7], double **dcPtr) { int i, argsUsed = 0; switch(r->type) { case 'p': /* pulse */ argsUsed = 7; r->d.pulse.v1 = args[0]; r->d.pulse.v2 = args[1]; r->d.pulse.td = args[2]; r->d.pulse.tr = args[3]; r->d.pulse.tf = args[4]; r->d.pulse.pw = args[5]; r->d.pulse.per = args[6]; *dcPtr = r->d.pulse.v1; break; case 'g': /* gauss */ argsUsed = 7; r->d.pulse.v1 = args[0]; r->d.pulse.v2 = args[1]; r->d.pulse.td = args[2]; r->d.pulse.tr = args[3]; r->d.pulse.tf = args[4]; r->d.pulse.pw = args[5]; r->d.pulse.per = args[6]; *dcPtr = r->d.pulse.v1; break; case 's': /* sin */ argsUsed = 5; r->d.sin.vo = args[0]; r->d.sin.va = args[1]; r->d.sin.fc = args[2]; r->d.sin.td = args[3]; r->d.sin.df = args[4]; *dcPtr = r->d.sin.vo; break; case 'e': /* exp */ argsUsed = 6; r->d.exp.v1 = args[0]; r->d.exp.v2 = args[1]; r->d.exp.td1 = args[2]; r->d.exp.tu1 = args[3]; r->d.exp.td2 = args[4]; r->d.exp.tu2 = args[5]; *dcPtr = r->d.exp.v1; break; case 'l': /* pwl */ case 'c': /* pwc */ argsUsed = 2; r->d.pw.pw = piecewiseNew(r->d.pw.pw, (double**)args[0], (int*)args[1], r->type); ReturnErrIf(r->d.pw.pw == NULL); *dcPtr = &r->d.pw.dc; break; case 'f': /* sffm */ argsUsed = 5; r->d.sffm.vo = args[0]; r->d.sffm.va = args[1]; r->d.sffm.fc = args[2]; r->d.sffm.mdi = args[3]; r->d.sffm.fs = args[4]; *dcPtr = r->d.sffm.vo; break; default: ReturnErr("Unsupported waveform type %c", r->type); } for(i = 0; i < argsUsed; i++) { ReturnErrIf(args[i] == NULL, "Argument %i is NULL", i); } return 0; }
int waveformCalcValue(waveform_ *r, double *value) { double time; double v1, v2, tr, td, tf, pw, per, tn; double vo, va, freq, theta, td1, td2; double tau1, tau2; double fc, mdi, fs; double dvdt; time = r->control->time; *value = 0.0; switch(r->type) { case 'p': /* pulse */ v1 = *r->d.pulse.v1; v2 = *r->d.pulse.v2; td = *r->d.pulse.td; tr = *r->d.pulse.tr; tf = *r->d.pulse.tf; pw = *r->d.pulse.pw; per = *r->d.pulse.per; tn = fmod(time, per); if(tn <= td) { *value = v1; } else if(tn <= (tr + td)) { *value = v1 + ((v2 - v1)/tr)*(tn - td); } else if(tn <= (tr + td + pw)) { *value = v2; } else if(tn <= (tr + td + pw + tf)) { *value = v2 - ((v2 - v1)/(tf))*(tn - (tr + td + pw)); } else { *value = v1; } break; case 'g': /* gauss */ /* This is based on the equations in "High-Speed Digital Design" by Johnson and Graham, Appendix B, scaling was done using table B.1 */ v1 = *r->d.pulse.v1; v2 = *r->d.pulse.v2; td = *r->d.pulse.td; tr = *r->d.pulse.tr; tf = *r->d.pulse.tf; pw = *r->d.pulse.pw; per = *r->d.pulse.per; tn = fmod(time, per); /* Calculate 't3' using the relationships in table B.1, remember that the provided values (td and tf from the user) are the 20% to 80% rise and fall times */ tr = (tr/0.672)*0.281*2; tf = (tf/0.672)*0.281*2; /* Calculate the values to send to the error function */ tr = (tn - (tr/0.281)*0.672-td)/tr; tf = (tn - (tf/0.281)*0.672-td-pw)/tf; /* Calculate the error functions */ ReturnErrIf(netlibERF(tr, &vo)); ReturnErrIf(netlibERF(tf, &va)); /* Calculate the voltage value */ *value = v1; *value += 0.5*(v2-v1)*(1+vo); *value += 0.5*(v1-v2)*(1+va); break; case 's': /* sin */ vo = *r->d.sin.vo; va = *r->d.sin.va; freq = *r->d.sin.fc; td = *r->d.sin.td; theta = *r->d.sin.df; if(time <= td) { *value = vo; } else { *value = vo + va*exp(-(time-td)*theta)*sin(2*M_PI*freq*(time-td)); } break; case 'e': /* exp */ v1 = *r->d.exp.v1; v2 = *r->d.exp.v2; td1 = *r->d.exp.td1; tau1 = *r->d.exp.tu1; td2 = *r->d.exp.td2; tau2 = *r->d.exp.tu2; if(time <= td1) { *value = v1; } else if(time <= td2) { *value = v1 + (v2-v1)*(1-exp(-(time-td1)/tau1)); } else { *value = v1 + (v2-v1)*(1-exp(-(time-td1)/tau1)) + (v1-v2)*(1-exp(-(time-td2)/tau2)); } break; case 'l': /* pwl */ case 'c': /* pwc */ ReturnErrIf(piecewiseCalcValue(r->d.pw.pw, &r->d.pw.index, time, value, &dvdt)); break; case 'f': /* sffm */ vo = *r->d.sffm.vo; va = *r->d.sffm.va; fc = *r->d.sffm.fc; mdi = *r->d.sffm.mdi; fs = *r->d.sffm.fs; *value = vo + va*sin(2*M_PI*fc*time + mdi*sin(2*M_PI*fs*time)); break; default: ReturnErr("Unsupported waveform type %c", r->type); } return 0; }