inp.c, incom.c: enable evaluation of all statistical functions agauss, gauss, aunif, unif, limit
inp.c: agauss in MC with prof. libraries, second part: after subcircuit expansion, replace all agauss occurrencies in b-lines by their respective return value of fcn agauss()
This commit is contained in:
parent
79373b8933
commit
2391a5b686
|
|
@ -59,7 +59,7 @@ static void inp_parse_temper_trees(void);
|
|||
|
||||
static wordlist *inp_savecurrents(struct line *deck, struct line *options, wordlist *wl, wordlist *controls);
|
||||
|
||||
static void eval_agauss_bsource(struct line *deck);
|
||||
static void eval_agauss_bsource(struct line *deck, char *fcn);
|
||||
|
||||
void line_free_x(struct line *deck, bool recurse);
|
||||
void create_circbyline(char *line);
|
||||
|
|
@ -611,7 +611,10 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile)
|
|||
inp_parse_temper(deck);
|
||||
|
||||
/* replace agauss(x,y,z) in each b-line by suitable value */
|
||||
eval_agauss_bsource(deck);
|
||||
static char *statfcn[] = { "agauss", "gauss", "aunif", "unif", "limit" };
|
||||
int ii;
|
||||
for (ii = 0; ii < 5; ii++)
|
||||
eval_agauss_bsource(deck, statfcn[ii]);
|
||||
|
||||
/* If user wants all currents saved (.options savecurrents), add .save
|
||||
to wl_first with all terminal currents available on selected devices */
|
||||
|
|
@ -1692,7 +1695,38 @@ agauss(double nominal_val, double abs_variation, double sigma)
|
|||
}
|
||||
|
||||
|
||||
/* Second step to enable agauss in professional parameter decks:
|
||||
static double
|
||||
gauss(double nominal_val, double rel_variation, double sigma)
|
||||
{
|
||||
double stdvar;
|
||||
stdvar = nominal_val * rel_variation / sigma;
|
||||
return (nominal_val + stdvar * gauss0());
|
||||
}
|
||||
|
||||
|
||||
static double
|
||||
unif(double nominal_val, double rel_variation)
|
||||
{
|
||||
return (nominal_val + nominal_val * rel_variation * drand());
|
||||
}
|
||||
|
||||
|
||||
static double
|
||||
aunif(double nominal_val, double abs_variation)
|
||||
{
|
||||
return (nominal_val + abs_variation * drand());
|
||||
}
|
||||
|
||||
|
||||
static double
|
||||
limit(double nominal_val, double abs_variation)
|
||||
{
|
||||
return (nominal_val + (drand() > 0 ? abs_variation : -1. * abs_variation));
|
||||
}
|
||||
|
||||
|
||||
/* Second step to enable functions agauss, gauss, aunif, unif, limit
|
||||
* in professional parameter decks:
|
||||
* agauss has been preserved by replacement operation of .func
|
||||
* (function inp_fix_agauss_in_param() in inpcom.c).
|
||||
* After subcircuit expansion, agauss may be still existing in b-lines,
|
||||
|
|
@ -1705,7 +1739,7 @@ agauss(double nominal_val, double abs_variation, double sigma)
|
|||
*/
|
||||
|
||||
static void
|
||||
eval_agauss_bsource(struct line *deck)
|
||||
eval_agauss_bsource(struct line *deck, char *fcn)
|
||||
{
|
||||
struct line *card;
|
||||
double x, y, z, val;
|
||||
|
|
@ -1732,7 +1766,7 @@ eval_agauss_bsource(struct line *deck)
|
|||
if (*curr_line != 'b')
|
||||
continue;
|
||||
|
||||
while ((ap = search_identifier(curr_line, "agauss", curr_line)) != NULL) {
|
||||
while ((ap = search_identifier(curr_line, fcn, curr_line)) != NULL) {
|
||||
char *lparen, *rparen, *begstr, *contstr = NULL, *new_line, *midstr;
|
||||
char *tmp1str, *tmp2str, *delstr;
|
||||
int nerror;
|
||||
|
|
@ -1752,10 +1786,35 @@ eval_agauss_bsource(struct line *deck)
|
|||
delstr = tmp2str = gettok(&tmp1str);
|
||||
y = INPevaluate(&tmp2str, &nerror, 1);
|
||||
tfree(delstr);
|
||||
delstr = tmp2str = gettok(&tmp1str);
|
||||
z = INPevaluate(&tmp2str, &nerror, 1);
|
||||
tfree(delstr);
|
||||
val = agauss(x, y, z);
|
||||
if (cieq(fcn, "agauss")) {
|
||||
delstr = tmp2str = gettok(&tmp1str);
|
||||
z = INPevaluate(&tmp2str, &nerror, 1);
|
||||
tfree(delstr);
|
||||
val = agauss(x, y, z);
|
||||
}
|
||||
else if (cieq(fcn, "gauss")) {
|
||||
delstr = tmp2str = gettok(&tmp1str);
|
||||
z = INPevaluate(&tmp2str, &nerror, 1);
|
||||
tfree(delstr);
|
||||
val = gauss(x, y, z);
|
||||
}
|
||||
else if (cieq(fcn, "aunif")) {
|
||||
val = aunif(x, y);
|
||||
}
|
||||
else if (cieq(fcn, "unif")) {
|
||||
val = unif(x, y);
|
||||
}
|
||||
else if (cieq(fcn, "limit")) {
|
||||
val = limit(x, y);
|
||||
}
|
||||
else {
|
||||
fprintf(cp_err, "ERROR: Unknown function %s, cannot evaluate\n", fcn);
|
||||
tfree(begstr);
|
||||
tfree(contstr);
|
||||
tfree(midstr);
|
||||
return;
|
||||
}
|
||||
|
||||
new_line = tprintf("%s%g%s", begstr, val, contstr);
|
||||
tfree(card->li_line);
|
||||
curr_line = card->li_line = new_line;
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ static void replace_token(char *string, char *token, int where, int total);
|
|||
static void inp_add_series_resistor(struct line *deck);
|
||||
static void subckt_params_to_param(struct line *deck);
|
||||
static void inp_fix_temper_in_param(struct line *deck);
|
||||
static void inp_fix_agauss_in_param(struct line *deck);
|
||||
static void inp_fix_agauss_in_param(struct line *deck, char *fcn);
|
||||
|
||||
static char *inp_spawn_brace(char *s);
|
||||
|
||||
|
|
@ -518,7 +518,11 @@ inp_readall(FILE *fp, char *dir_name, bool comfile, bool intfile)
|
|||
rv . line_number = inp_split_multi_param_lines(working, rv . line_number);
|
||||
|
||||
inp_fix_macro_param_func_paren_io(working);
|
||||
inp_fix_agauss_in_param(working);
|
||||
|
||||
static char *statfcn[] = { "agauss", "gauss", "aunif", "unif", "limit" };
|
||||
int ii;
|
||||
for (ii = 0; ii < 5; ii++)
|
||||
inp_fix_agauss_in_param(working, statfcn[ii]);
|
||||
|
||||
inp_fix_temper_in_param(working);
|
||||
|
||||
|
|
@ -6117,8 +6121,9 @@ inp_fix_temper_in_param(struct line *deck)
|
|||
}
|
||||
|
||||
|
||||
/* Convert .param lines containing function 'agauss' into .func lines:
|
||||
* .param xxx1 = 'agauss()' ---> .func xxx1() 'agauss()'
|
||||
/* Convert .param lines containing function 'agauss' and others
|
||||
* (function name handed over by *fcn), into .func lines:
|
||||
* .param xxx1 = 'aunif()' ---> .func xxx1() 'aunif()'
|
||||
* Add info about the functions (name, subcircuit depth, number of
|
||||
* subckt) to linked list new_func.
|
||||
* Then scan new_func, for each xxx1 scan all lines of deck,
|
||||
|
|
@ -6131,7 +6136,7 @@ inp_fix_temper_in_param(struct line *deck)
|
|||
*/
|
||||
|
||||
static void
|
||||
inp_fix_agauss_in_param(struct line *deck)
|
||||
inp_fix_agauss_in_param(struct line *deck, char *fcn)
|
||||
{
|
||||
int skip_control = 0, subckt_depth = 0, j, *sub_count;
|
||||
char *funcbody, *funcname;
|
||||
|
|
@ -6185,7 +6190,7 @@ inp_fix_agauss_in_param(struct line *deck)
|
|||
|
||||
char *p, *temper, *equal_ptr, *lhs_b, *lhs_e;
|
||||
|
||||
temper = search_identifier(curr_line, "agauss", curr_line);
|
||||
temper = search_identifier(curr_line, fcn, curr_line);
|
||||
|
||||
if (!temper)
|
||||
continue;
|
||||
|
|
@ -6218,9 +6223,9 @@ inp_fix_agauss_in_param(struct line *deck)
|
|||
|
||||
if (temper < equal_ptr) {
|
||||
fprintf(stderr,
|
||||
"Error: you cannot assign a value to TEMPER\n"
|
||||
"Error: you cannot assign a value to %s\n"
|
||||
" Line no. %d, %s\n",
|
||||
card->li_linenum, curr_line);
|
||||
fcn, card->li_linenum, curr_line);
|
||||
controlled_exit(EXIT_BAD);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue