📄 mat_formula.cpp
字号:
scan>source && *(scan - 1) == 'E'))
{
numbers++;
scan++;
while (isin_real(*scan) ||((*scan == '+' || *scan == '-') &&
scan>source && *(scan - 1) == 'E'))
scan++;
}
else
scan++;
return (numbers*num_size + operators*op_size + functions*num_size
+ variables*var_size + end_size);
}
CSG_Formula::TMAT_Formula CSG_Formula::translate(const SG_Char *sourc, const SG_Char *args, int *leng, int *error)
{
SG_Char *result;
SG_Char *source;
const SG_Char *scan, *scarg;
SG_Char *function;
SG_Char *nfunc;
size_t size_estim;
double *ctable;
TMAT_Formula returned;
i_error = NULL;
source =(SG_Char *) SG_Malloc(SG_STR_LEN(sourc) + 1);
if (source == NULL)
{
fset_error(LNG("no memory"));
*leng = 0;
*error = 0;
returned.code = NULL;
returned.ctable = NULL;
return (returned);
}
SG_STR_CPY(source, sourc);
for (scan = source; *scan != '\0'; scan++)
{
if (islower(*scan) && !isalpha(*(scan + 1)) &&
(scan == source || !isalpha(*(scan - 1))))
{
for (scarg = args; *scarg != '\0' && *scarg != *scan; scarg++)
;
if (*scarg == '\0')
{
i_error = scan;
fset_error(LNG("undeclared parameter"));
*leng = 0;
*error = i_error - source;
returned.code = NULL;
returned.ctable = NULL;
SG_Free(source);
return (returned);
}
}
}
size_estim = max_size(source);
if (!(function =(SG_Char *) SG_Malloc(size_estim)) )
{
fset_error(LNG("no memory"));
*leng = 0;
*error = -1;
returned.code = NULL;
returned.ctable = NULL;
SG_Free(source);
return (returned);
}
i_pctable = 0;
if (!(i_ctable =(double *) SG_Malloc(Max_ctable * sizeof(double))))
{
fset_error(LNG("no memory"));
SG_Free(function);
*leng = 0;
*error = -1;
returned.code = NULL;
returned.ctable = NULL;
SG_Free(source);
return (returned);
}
ctable = i_ctable;
fset_error(NULL);
result = i_trans(function, (SG_Char *) source, (SG_Char *) source + SG_STR_LEN(source));
if (!result || fget_error())
{
SG_Free(function);
SG_Free(i_ctable);
*leng = 0;
if (i_error)
*error = i_error - source;
else
*error = -1;
returned.code = NULL;
returned.ctable = NULL;
SG_Free(source);
return (returned);
}
else
{
*result = '\0';
*error = -1;
*leng = result - function;
if (((*leng) + 1) * sizeof(SG_Char) > size_estim)
{
fset_error(LNG("I4: size estimate too small"));
returned.code = NULL;
returned.ctable = NULL;
SG_Free(source);
return (returned);
}
else if (((*leng) + 1) * sizeof(SG_Char) < size_estim)
{
nfunc =(SG_Char *) SG_Malloc(((*leng) + 1) * sizeof(SG_Char));
if (nfunc)
{
memcpy(nfunc, function, ((*leng) + 1) * sizeof(SG_Char));
SG_Free(function);
function = nfunc;
}
}
if (i_pctable < Max_ctable)
{
ctable =(double *) SG_Malloc(i_pctable * sizeof(double));
if (ctable)
{
memcpy(ctable, i_ctable, i_pctable * sizeof(double));
SG_Free(i_ctable);
}
else
ctable = i_ctable;
}
else
ctable = i_ctable;
returned.code = function;
returned.ctable = ctable;
fset_error(NULL);
SG_Free(source);
return (returned);
}
}
SG_Char *CSG_Formula::comp_time(SG_Char *function, SG_Char *fend, int npars)
{
SG_Char *scan;
SG_Char temp;
double tempd;
int i;
TMAT_Formula trans;
scan = function;
for (i = 0; i < npars; i++)
{
if (*scan++ != 'D')
return fend;
scan++;
}
if (!((scan == fend -(sizeof((SG_Char) 'F') + sizeof(SG_Char))
&& *(fend - 2) == 'F' && gSG_Functions[*(fend - 1)].varying == 0) ||
(scan == fend - sizeof(SG_Char)
&& is_code_oper(*(fend - 1))))
)
return fend;
temp = *fend;
*fend = '\0';
trans.code = function;
trans.ctable = i_ctable;
tempd = value(trans);
*fend = temp;
*function++ = 'D';
i_pctable -= npars;
*function++ =(SG_Char) i_pctable;
i_ctable[i_pctable++] = tempd;
return function;
}
SG_Char *CSG_Formula::my_strtok(SG_Char *s)
{
int pars;
static SG_Char *token = NULL;
SG_Char *next_token;
if (s != NULL)
token = s;
else if (token != NULL)
s = token;
else
return NULL;
for (pars = 0; *s != '\0' &&(*s != ',' || pars != 0); s++)
{
if (*s == '(') ++pars;
if (*s == ')')
--pars;
}
if (*s == '\0')
{
next_token = NULL;
s = token;
token = next_token;
return s;
}
else
{
*s = '\0';
next_token = s + 1;
s = token;
token = next_token;
return s;
}
}
SG_Char *CSG_Formula::i_trans(SG_Char *function, SG_Char *begin, SG_Char *end)
{
int pars;
SG_Char *scan;
SG_Char *tempu, *temp3;
SG_Char *temps = NULL;
SG_Char tempch;
double tempd;
SG_Char *endf;
int n_function;
int space;
int i;
SG_Char *paramstr[MAXPAR];
SG_Char *par_buf;
if (begin >= end)
{
fset_error(LNG("missing operand"));
i_error = begin;
return NULL;
}
for (pars = 0, scan = begin; scan < end && pars >= 0; scan++)
{
if (*scan == SG_T('(')) pars++;
else if (*scan == SG_T(')'))
pars--;
}
if (pars < 0 || pars > 0)
{
fset_error(LNG("unmatched parentheses"));
i_error = scan - 1;
return NULL;
}
for (pars = 0, scan = end - 1; scan >= begin; scan--)
{
if (*scan == SG_T('(')) pars++;
else if (*scan == ')')
pars--;
else if (!pars &&(*scan == SG_T('+') ||((*scan == SG_T('-')) && scan != begin))
&&(scan == begin || *(scan - 1) != SG_T('E')))
break;
}
if (scan >= begin)
{
if ((tempu = i_trans(function, begin, scan)) &&
(temp3 = i_trans(tempu, scan + 1, end)))
{
*temp3++ = *scan;
temp3 = comp_time(function, temp3, 2);
if (fget_error())
return NULL;
else
return temp3;
}
else
return NULL;
}
for (pars = 0, scan = end - 1; scan >= begin; scan--)
{
if (*scan == '(') pars++;
else if (*scan == ')')
pars--;
else if (!pars &&(*scan == '*' || *scan == '/'))
break;
}
if (scan >= begin)
{
if ((tempu = i_trans(function, begin, scan)) &&
(temp3 = i_trans(tempu, scan + 1, end)))
{
*temp3++ = *scan;
temp3 = comp_time(function, temp3, 2);
if (fget_error())
return NULL;
else
return temp3;
}
else
return NULL;
}
/* unary minus */
if (*begin == '-')
{
tempu = i_trans(function, begin + 1, end);
if (tempu)
{
*tempu++ = 'M';
tempu = comp_time(function, tempu, 1);
if (fget_error())
return NULL;
else
return tempu;
}
else
return NULL;
}
for (pars = 0, scan = end - 1; scan >= begin; scan--)
{
if (*scan == '(') pars++;
else if (*scan == ')')
pars--;
else if (!pars &&(*scan == '^'))
break;
}
if (scan >= begin)
{
if ((tempu = i_trans(function, begin, scan)) &&
(temp3 = i_trans(tempu, scan + 1, end)))
{
*temp3++ = *scan;
temp3 = comp_time(function, temp3, 2);
if (fget_error())
return NULL;
else
return temp3;
}
else
return NULL;
}
/* erase white space */
while (isspace(*begin))
begin++;
while (isspace(*(end - 1)))
end--;
if (*begin == '(' && *(end - 1) == ')')
return i_trans(function, begin + 1, end - 1);
if (end == begin + 1 && islower(*begin))
{
*function++ = 'V';
*function++ = *begin;
return function;
}
tempch = *end;
*end = '\0';
tempd = SG_STR_TOD(begin, (SG_Char**) &tempu);
*end = tempch;
if ((SG_Char*) tempu == end)
{
*function++ = 'D';
if (i_pctable < Max_ctable)
{
i_ctable[i_pctable] = tempd;
*function++ =(SG_Char) i_pctable++;
}
else
{
fset_error(LNG("too many constants"));
i_error = begin;
return NULL;
}
return function;
}
/*function*/
if (!isalpha(*begin) && *begin != '_')
{
fset_error(LNG("syntax error"));
i_error = begin;
return NULL;
}
for (endf = begin + 1; endf < end &&(isalnum(*endf) || *endf == '_');
endf++)
;
tempch = *endf;
*endf = '\0';
if ((n_function = where_table(begin)) == -1)
{
*endf = tempch;
i_error = begin;
return NULL;
}
*endf = tempch;
if (*endf != '(' || *(end - 1) != ')')
{
fset_error(LNG("improper function syntax"));
i_error = endf;
return NULL;
}
if (gSG_Functions[n_function].n_pars == 0)
{
/*function without parameters(e.g. pi()) */
space = 1;
for (scan = endf + 1; scan <(end - 1); scan++)
if (!isspace(*scan))
space = 0;
if (space)
{
*function++ = 'F';
*function++ = n_function;
function = comp_time(function - 2, function, 0);
if (fget_error())
return NULL; /* internal error in comp_time */
else
return function;
}
else
{
i_error = endf + 1;
fset_error(LNG("too many parameters"));
return NULL;
}
}
else
{ /*function with parameters*/
tempch = *(end - 1);
*(end - 1) = '\0';
par_buf =(SG_Char *) SG_Malloc(SG_STR_LEN(endf + 1) + 1);
if (!par_buf)
{
fset_error(LNG("no memory"));
i_error = NULL;
return NULL;
}
SG_STR_CPY(par_buf, endf + 1);
*(end - 1) = tempch;
for (i = 0; i < gSG_Functions[n_function].n_pars; i++)
{
if ((temps = my_strtok((i == 0) ? par_buf : NULL)) == NULL)
break;
paramstr[i] = temps;
}
if (temps == NULL)
{
SG_Free(par_buf);
i_error = end - 2;
fset_error(LNG("too few parameters"));
return NULL;
}
if ((temps = my_strtok(NULL)) != NULL)
{
SG_Free(par_buf);
i_error =(temps - par_buf) +(endf + 1);
fset_error(LNG("too many parameters"));
return NULL;
}
tempu = function;
for (i = 0; i < gSG_Functions[n_function].n_pars; i++)
if (!(tempu = i_trans(tempu, paramstr[i],
paramstr[i] + SG_STR_LEN(paramstr[i]))))
{
i_error =(i_error - par_buf) +(endf + 1);
SG_Free(par_buf);
return NULL;
}
/* OK */
SG_Free(par_buf);
*tempu++ = 'F';
*tempu++ = n_function;
tempu = comp_time(function, tempu, gSG_Functions[n_function].n_pars);
if (fget_error())
return NULL; /* internal error in comp_time */
else
return tempu;
}
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
#define eps 1e-9
//---------------------------------------------------------
static double f_pi(void)
{
return( M_PI );
}
//---------------------------------------------------------
static double f_atan2(double x, double val)
{
return( atan2(x, val) );
}
//---------------------------------------------------------
static double f_fmod(double x, double val)
{
return( fmod(x, val) );
}
//---------------------------------------------------------
static double f_gt(double x, double val)
{
return( x > val ? 1.0 : 0.0 );
}
//---------------------------------------------------------
static double f_lt(double x, double val)
{
return( x < val ? 1.0 : 0.0 );
}
//---------------------------------------------------------
static double f_eq(double x, double val)
{
return( fabs(x - val) < eps ? 1.0 : 0.0 );
}
//---------------------------------------------------------
static double f_int(double x)
{
return( (int)(x) );
}
//---------------------------------------------------------
static double f_ifelse(double condition, double x, double y)
{
return( fabs(condition - 1.0) < eps ? x : y );
}
//---------------------------------------------------------
static double f_N(double a, double x, double y)
{
/* int xpos, ypos;
xpos =(int)(_x_ + x);
ypos =(int)(_y_ + y);
if (_last_ < 0)
return a;
if (xpos >= 0 && ypos >= 0 && xpos <grid[_last_]->Get_NX() && ypos < grid[_last_]->Get_NY())
return grid[_last_]->asDouble(xpos, ypos);
else
{
double nix = 0.0;
return 1.0/nix;
}
*/
return 1.0;
}
/*class func
{
public:
virtual double operator()(double n);
};*/
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -