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
56f03605dc
commit
9ae9968902
|
|
@ -60,7 +60,7 @@ static void inp_parse_temper_trees(void);
|
||||||
|
|
||||||
static wordlist *inp_savecurrents(struct line *deck, struct line *options, wordlist *wl, wordlist *controls);
|
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 line_free_x(struct line *deck, bool recurse);
|
||||||
void create_circbyline(char *line);
|
void create_circbyline(char *line);
|
||||||
|
|
@ -666,7 +666,10 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile)
|
||||||
inp_parse_temper(deck);
|
inp_parse_temper(deck);
|
||||||
|
|
||||||
/* replace agauss(x,y,z) in each b-line by suitable value */
|
/* 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
|
/* If user wants all currents saved (.options savecurrents), add .save
|
||||||
to wl_first with all terminal currents available on selected devices */
|
to wl_first with all terminal currents available on selected devices */
|
||||||
|
|
@ -1887,7 +1890,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
|
* agauss has been preserved by replacement operation of .func
|
||||||
* (function inp_fix_agauss_in_param() in inpcom.c).
|
* (function inp_fix_agauss_in_param() in inpcom.c).
|
||||||
* After subcircuit expansion, agauss may be still existing in b-lines,
|
* After subcircuit expansion, agauss may be still existing in b-lines,
|
||||||
|
|
@ -1900,7 +1934,7 @@ agauss(double nominal_val, double abs_variation, double sigma)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eval_agauss_bsource(struct line *deck)
|
eval_agauss_bsource(struct line *deck, char *fcn)
|
||||||
{
|
{
|
||||||
struct line *card;
|
struct line *card;
|
||||||
double x, y, z, val;
|
double x, y, z, val;
|
||||||
|
|
@ -1927,7 +1961,7 @@ eval_agauss_bsource(struct line *deck)
|
||||||
if (*curr_line != 'b')
|
if (*curr_line != 'b')
|
||||||
continue;
|
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 *lparen, *rparen, *begstr, *contstr = NULL, *new_line, *midstr;
|
||||||
char *tmp1str, *tmp2str, *delstr;
|
char *tmp1str, *tmp2str, *delstr;
|
||||||
int nerror;
|
int nerror;
|
||||||
|
|
@ -1947,10 +1981,35 @@ eval_agauss_bsource(struct line *deck)
|
||||||
delstr = tmp2str = gettok(&tmp1str);
|
delstr = tmp2str = gettok(&tmp1str);
|
||||||
y = INPevaluate(&tmp2str, &nerror, 1);
|
y = INPevaluate(&tmp2str, &nerror, 1);
|
||||||
tfree(delstr);
|
tfree(delstr);
|
||||||
delstr = tmp2str = gettok(&tmp1str);
|
if (cieq(fcn, "agauss")) {
|
||||||
z = INPevaluate(&tmp2str, &nerror, 1);
|
delstr = tmp2str = gettok(&tmp1str);
|
||||||
tfree(delstr);
|
z = INPevaluate(&tmp2str, &nerror, 1);
|
||||||
val = agauss(x, y, z);
|
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);
|
new_line = tprintf("%s%g%s", begstr, val, contstr);
|
||||||
tfree(card->li_line);
|
tfree(card->li_line);
|
||||||
curr_line = card->li_line = new_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 inp_add_series_resistor(struct line *deck);
|
||||||
static void subckt_params_to_param(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_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);
|
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);
|
rv . line_number = inp_split_multi_param_lines(working, rv . line_number);
|
||||||
|
|
||||||
inp_fix_macro_param_func_paren_io(working);
|
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);
|
inp_fix_temper_in_param(working);
|
||||||
|
|
||||||
|
|
@ -6131,8 +6135,9 @@ inp_fix_temper_in_param(struct line *deck)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Convert .param lines containing function 'agauss' into .func lines:
|
/* Convert .param lines containing function 'agauss' and others
|
||||||
* .param xxx1 = 'agauss()' ---> .func xxx1() 'agauss()'
|
* (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
|
* Add info about the functions (name, subcircuit depth, number of
|
||||||
* subckt) to linked list new_func.
|
* subckt) to linked list new_func.
|
||||||
* Then scan new_func, for each xxx1 scan all lines of deck,
|
* Then scan new_func, for each xxx1 scan all lines of deck,
|
||||||
|
|
@ -6145,7 +6150,7 @@ inp_fix_temper_in_param(struct line *deck)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
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;
|
int skip_control = 0, subckt_depth = 0, j, *sub_count;
|
||||||
char *funcbody, *funcname;
|
char *funcbody, *funcname;
|
||||||
|
|
@ -6199,7 +6204,7 @@ inp_fix_agauss_in_param(struct line *deck)
|
||||||
|
|
||||||
char *p, *temper, *equal_ptr, *lhs_b, *lhs_e;
|
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)
|
if (!temper)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -6232,9 +6237,9 @@ inp_fix_agauss_in_param(struct line *deck)
|
||||||
|
|
||||||
if (temper < equal_ptr) {
|
if (temper < equal_ptr) {
|
||||||
fprintf(stderr,
|
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",
|
" Line no. %d, %s\n",
|
||||||
card->li_linenum, curr_line);
|
fcn, card->li_linenum, curr_line);
|
||||||
controlled_exit(EXIT_BAD);
|
controlled_exit(EXIT_BAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue