here it goes.
class LinearRegression
{
public:
// Constructor using an array of Point2D objects
// This is also the default constructor
LinearRegression(Point2D *p = 0, long size = 0);
// Constructor using arrays of x values and y values
LinearRegression(double *x, double *y, long size = 0);
virtual void addXY(const double& x, const double& y);
void clear() { sumX = sumY = sumXsquared = sumYsquared = sumXY = n = 0; }
void addPoint(const Point2D& p) { addXY(p.getX(), p.getY()); }
// Must have at least 3 points to calculate
// standard error of estimate. Do we have enough data?
int haveData() const { return (n > 2 ? 1 : 0); }
long items() const { return n; }
virtual double getA() const { return a; }
virtual double getB() const { return b; }
double getCoefDeterm() const { return coefD; }
double getCoefCorrel() const { return coefC; }
double getStdErrorEst() const { return stdError; }
virtual double estimateY(double x) const { return (a + b * x); }
protected:
long n; // number of data points input so far
double sumX, sumY; // sums of x and y
double sumXsquared, // sum of x squares
sumYsquared; // sum y squares
double sumXY; // sum of x*y
double a, b; // coefficients of f(x) = a + b*x
double coefD, // coefficient of determination
coefC, // coefficient of correlation
stdError; // standard error of estimate
void Calculate(); // calculate coefficients
};
LinearRegression::LinearRegression(Point2D *p, long size)
{
long i;
a = b = sumX = sumY = sumXsquared = sumYsquared = sumXY = 0.0;
n = 0L;
if (size > 0L) // if size greater than zero there are data arrays
for (n = 0, i = 0L; i < size; i++)
addPoint(p[i]);
}
LinearRegression::LinearRegression(double *x, double *y, long size)
{
long i;
a = b = sumX = sumY = sumXsquared = sumYsquared = sumXY = 0.0;
n = 0L;
if (size > 0L) // if size greater than zero there are data arrays
for (n = 0, i = 0L; i < size; i++)
addXY(x[i], y[i]);
}
void LinearRegression::addXY(const double& x, const double& y)
{
n++;
sumX += x;
sumY += y;
sumXsquared += x * x;
sumYsquared += y * y;
sumXY += x * y;
Calculate();
}
void LinearRegression::Calculate()
{
if (haveData())
{
if (fabs( double(n) * sumXsquared - sumX * sumX) > DBL_EPSILON)
{
b = ( double(n) * sumXY - sumY * sumX) /
( double(n) * sumXsquared - sumX * sumX);
a = (sumY - b * sumX) / double(n);
double sx = b * ( sumXY - sumX * sumY / double(n) );
double sy2 = sumYsquared - sumY * sumY / double(n);
double sy = sy2 - sx;
coefD = sx / sy2;
coefC = sqrt(coefD);
stdError = sqrt(sy / double(n - 2));
}
else
{
a = b = coefD = coefC = stdError = 0.0;
}
}
}
simple examples of how to
Showing posts with label source code. Show all posts
Showing posts with label source code. Show all posts
Thursday, October 20, 2011
[C++] Post-fix Calculator Source Code (String-calculator)
Here goes the c++ source code of post-fix calculator, which appears a lot in data structure class.
here it goes
#include stdio.h>
#include stdlib.h>
#include string.h>
#include ctype.h>
#define T_EOL ';'
#define T_CONST 'C'
#define T_SYMBOL 'S'
#define T_LPAR '('
#define T_RPAR ')'
#define T_COMMA ','
#define T_ASSIGN '='
#define T_POINT '$'
#define T_MUL '*'
#define T_DIV '/'
#define T_MOD '%'
#define T_ADD '+'
#define T_SUB '-'
#define T_NEG '_'
#define T_NOT '~'
#define T_SHL 'L'
#define T_SHR 'R'
#define T_AND '&'
class StringCalculator {
// I don't know why defining another class makes all messages of redefinitions...,
// just put postfix calcualtor here
public:
StringCalculator();
double push_eval( double val );
double push( double val );
double pop_eval();
double pop();
char getoken(int* v = NULL);
int isbinop( char** cpp );
int expression();
double evaluate();
int primary();
int binop( char op );
int op_prim( int precedence, int lvalue );
void generate( char tkn, double val, int index=-1 );
double calc( char* line );
void setup_symbol(int index, double value);
#define STAKSZ 128
struct OPSTK {
char o_token;
double o_value;
int symbol_index;
} Opstk[ STAKSZ ];
int Opbase;
int Opsp;
double Valstk[ STAKSZ ];
int Valbase;
int Valsp;
double Valstk_eval[ STAKSZ ];
int Valbase_eval;
int Valsp_eval;
double Symbols[26];
double Value;
char buff[128];
#define MAXLEVEL 32
char Level; /* current recursion level in calc() */
char Token; /* current input token */
char Eol; /* set when end of line encountered */
char *Lineptr; /* points to next character in input line */
char *Ofmt; /* current output format (set by "base" command) */
int Error; /* set if parsing error occurred */
char Nohelp; /* set if help was given already */
int symbol_index;
};
StringCalculator::StringCalculator()
{
Nohelp = 1;
Level = 0;
Token = 0;
Eol = 0;
Lineptr = NULL;
Ofmt = NULL;
Error = 0;
Nohelp = 0;
Opbase=0;
Opsp=0;
Valbase=0;
Valsp=0;
push( 10 );
for( int i=0; i<26; i++ )
{
Symbols[i]=0;
}
}
void StringCalculator::setup_symbol(int index, double value)
{
Symbols[index] = value;
}
double StringCalculator::calc( char* line )
{
char *savLineptr;
int savValbase, savValsp, savOpbase, savOpsp;
/* save in my buff */
strncpy(buff, line, 128);
line = buff;
if ( ++Level > MAXLEVEL )
{
printf("recursion\n");
}
else
{
savLineptr = Lineptr;
savValbase = Valbase;
savValsp = Valsp;
savOpbase = Opbase;
savOpsp = Opsp;
Valbase = Valsp;
Opbase = Opsp;
Lineptr = line;
Eol = 0;
if ( getoken() != T_EOL )
{
expression();
if ( Error <= 0 )
{
}
else {
printf("parse error: %s\n", buff);
}
}
}
return 0.0;
}
double StringCalculator::evaluate()
{
int opsp;
double val;
char op;
Valsp_eval = Valsp;
Valbase_eval = Valbase;
memcpy(Valstk_eval, Valstk, sizeof(Valstk));
#define TOS (Valstk_eval[Valsp_eval-1]) /* top of stack macro */
for ( opsp=Opbase; opsp {
op = Opstk[ opsp ].o_token;
if ( op == T_CONST )
{
push_eval( Opstk[ opsp ].o_value );
}
else if ( op == T_SYMBOL )
{
push_eval( Symbols[Opstk[ opsp ].symbol_index] );
}
else if ( op == T_ADD )
{
val = pop_eval();
TOS += val;
}
else if ( op == T_SUB )
{
val = pop_eval();
TOS -= val;
}
else if ( op == T_NEG )
TOS = -TOS;
else if ( op == T_MUL )
{
val = pop_eval();
TOS *= val;
}
else if ( op == T_DIV )
{
val = pop_eval();
TOS /= val;
}
else
printf( "bad operator in stack: 0x%x (%c)\n", op, op );
}
return Valstk_eval[ Valbase_eval ];
}
double StringCalculator::push( double val )
{
if ( Valsp >= STAKSZ )
printf( "stack overflow" );
return Valstk[ Valsp++ ] = val;
}
double StringCalculator::pop()
{
if ( --Valsp < 0 )
Valsp = 0;
return Valstk[ Valsp ];
}
double StringCalculator::push_eval( double val )
{
if ( Valsp_eval >= STAKSZ )
printf( "stack overflow" );
return Valstk_eval[ Valsp_eval++ ] = val;
}
double StringCalculator::pop_eval()
{
if ( --Valsp_eval < 0 )
Valsp_eval = 0;
return Valstk_eval[ Valsp_eval ];
}
int StringCalculator::expression()
{
int lvalue;
if ( !(lvalue = primary()) )
{
printf( "bad expression" );
}
else if ( Eol )
{
if ( lvalue < 0 )
generate( T_POINT, 0 );
}
else
{
op_prim( 0, lvalue );
}
return 1;
}
int StringCalculator::op_prim( int precedence, int lvalue )
{
char tkn;
int pr, lv;
while ( ! Eol )
{
pr = binop( Token );
if (
(pr>precedence && pr>0) ||
(Token==T_ASSIGN && pr>=precedence)
)
{
if ( Token == T_ASSIGN )
{
if ( lvalue > 0 )
printf( "= needs and lvalue" );
}
else if ( lvalue < 0 )
generate( T_POINT, 0 );
tkn = Token;
getoken();
if ( ! (lv = primary()) )
printf( "missing an operand" );
lvalue = op_prim( pr, lv );
if ( Token != T_ASSIGN && lvalue < 0 )
{
generate( T_POINT, 0 );
lvalue = 1;
}
else if ( tkn!=T_ASSIGN && Token==T_ASSIGN )
{
printf( "= needs an lvalue" );
}
generate( tkn, 0 );
}
else
break;
}
return lvalue;
}
int StringCalculator::primary()
{
int rtn;
if ( Eol )
return 0;
rtn = 1;
switch ( Token )
{
case T_SYMBOL: /* a symbol */
generate( Token, Value, symbol_index );
getoken();
break;
case T_CONST: /* a constant */
generate( Token, Value );
getoken();
break;
case T_LPAR: /* a parenthesized expression */
getoken();
expression();
if ( Token != T_RPAR )
{
printf( "missing ')'" );
rtn = 0;
}
else
getoken();
break;
case T_SUB: /* unary - */
getoken();
expression();
generate( T_NEG, 0 );
break;
case T_NOT: /* unary ~ */
getoken();
expression();
generate( T_NOT, 0 );
break;
case T_ADD: /* unary + */
getoken();
expression();
break;
default:
rtn = 0;
}
return rtn;
}
int StringCalculator::binop( char op )
{
switch ( op )
{
case T_ADD:
case T_SUB:
return 7;
case T_MUL:
case T_DIV:
case T_MOD:
return 8;
case T_NOT:
return 9;
}
return 0;
}
void StringCalculator::generate( char tkn, double val, int index )
{
if ( Opsp < STAKSZ )
{
Opstk[ Opsp ].o_token = tkn;
Opstk[ Opsp ].o_value = val;
Opstk[ Opsp ].symbol_index = index;
++Opsp;
}
else
printf( "expression too complex" );
}
char StringCalculator::getoken(int* )
{
char *cp, buf[ 128 ];
if ( ! *Lineptr )
{
Eol = 1;
Token = T_EOL;
}
else if ( isdigit( *Lineptr ) )
{
Token = T_CONST;
for ( cp = buf; isdigit( *Lineptr ) || *Lineptr == '.'; )
*cp++ = *Lineptr++;
*cp = 0;
Value = atof(buf);
}
else if ( (Token = isbinop( &Lineptr )) )
{
;
}
else if ( isalpha( *Lineptr ) )
{
Token = T_SYMBOL;
symbol_index = toupper( *Lineptr ) - 'A';
++Lineptr;
}
else
{
printf( "bad syntax: %s", Lineptr );
++Lineptr;
}
return Token;
}
int StringCalculator::isbinop( char** cpp )
{
int tkn=1;
char c;
c = **cpp;
if ( c == ',' )
tkn = T_COMMA;
else if ( c == '=' )
tkn = T_ASSIGN;
else if ( c == '<' )
{
if ( *(++(*cpp)) == '<' )
tkn = T_SHL;
}
else if ( c == '>' )
{
if ( *(++(*cpp)) == '>' )
tkn = T_SHR;
}
else if ( c == '(' )
tkn = T_LPAR;
else if ( c == ')' )
tkn = T_RPAR;
else if ( c == '*' )
tkn = T_MUL;
else if ( c == '/' )
tkn = T_DIV;
else if ( c == '+' )
tkn = T_ADD;
else if ( c == '-' )
tkn = T_SUB;
else
tkn = 0;
if ( tkn )
++(*cpp);
return tkn;
}
here it goes
#include stdio.h>
#include stdlib.h>
#include string.h>
#include ctype.h>
#define T_EOL ';'
#define T_CONST 'C'
#define T_SYMBOL 'S'
#define T_LPAR '('
#define T_RPAR ')'
#define T_COMMA ','
#define T_ASSIGN '='
#define T_POINT '$'
#define T_MUL '*'
#define T_DIV '/'
#define T_MOD '%'
#define T_ADD '+'
#define T_SUB '-'
#define T_NEG '_'
#define T_NOT '~'
#define T_SHL 'L'
#define T_SHR 'R'
#define T_AND '&'
class StringCalculator {
// I don't know why defining another class makes all messages of redefinitions...,
// just put postfix calcualtor here
public:
StringCalculator();
double push_eval( double val );
double push( double val );
double pop_eval();
double pop();
char getoken(int* v = NULL);
int isbinop( char** cpp );
int expression();
double evaluate();
int primary();
int binop( char op );
int op_prim( int precedence, int lvalue );
void generate( char tkn, double val, int index=-1 );
double calc( char* line );
void setup_symbol(int index, double value);
#define STAKSZ 128
struct OPSTK {
char o_token;
double o_value;
int symbol_index;
} Opstk[ STAKSZ ];
int Opbase;
int Opsp;
double Valstk[ STAKSZ ];
int Valbase;
int Valsp;
double Valstk_eval[ STAKSZ ];
int Valbase_eval;
int Valsp_eval;
double Symbols[26];
double Value;
char buff[128];
#define MAXLEVEL 32
char Level; /* current recursion level in calc() */
char Token; /* current input token */
char Eol; /* set when end of line encountered */
char *Lineptr; /* points to next character in input line */
char *Ofmt; /* current output format (set by "base" command) */
int Error; /* set if parsing error occurred */
char Nohelp; /* set if help was given already */
int symbol_index;
};
StringCalculator::StringCalculator()
{
Nohelp = 1;
Level = 0;
Token = 0;
Eol = 0;
Lineptr = NULL;
Ofmt = NULL;
Error = 0;
Nohelp = 0;
Opbase=0;
Opsp=0;
Valbase=0;
Valsp=0;
push( 10 );
for( int i=0; i<26; i++ )
{
Symbols[i]=0;
}
}
void StringCalculator::setup_symbol(int index, double value)
{
Symbols[index] = value;
}
double StringCalculator::calc( char* line )
{
char *savLineptr;
int savValbase, savValsp, savOpbase, savOpsp;
/* save in my buff */
strncpy(buff, line, 128);
line = buff;
if ( ++Level > MAXLEVEL )
{
printf("recursion\n");
}
else
{
savLineptr = Lineptr;
savValbase = Valbase;
savValsp = Valsp;
savOpbase = Opbase;
savOpsp = Opsp;
Valbase = Valsp;
Opbase = Opsp;
Lineptr = line;
Eol = 0;
if ( getoken() != T_EOL )
{
expression();
if ( Error <= 0 )
{
}
else {
printf("parse error: %s\n", buff);
}
}
}
return 0.0;
}
double StringCalculator::evaluate()
{
int opsp;
double val;
char op;
Valsp_eval = Valsp;
Valbase_eval = Valbase;
memcpy(Valstk_eval, Valstk, sizeof(Valstk));
#define TOS (Valstk_eval[Valsp_eval-1]) /* top of stack macro */
for ( opsp=Opbase; opsp
op = Opstk[ opsp ].o_token;
if ( op == T_CONST )
{
push_eval( Opstk[ opsp ].o_value );
}
else if ( op == T_SYMBOL )
{
push_eval( Symbols[Opstk[ opsp ].symbol_index] );
}
else if ( op == T_ADD )
{
val = pop_eval();
TOS += val;
}
else if ( op == T_SUB )
{
val = pop_eval();
TOS -= val;
}
else if ( op == T_NEG )
TOS = -TOS;
else if ( op == T_MUL )
{
val = pop_eval();
TOS *= val;
}
else if ( op == T_DIV )
{
val = pop_eval();
TOS /= val;
}
else
printf( "bad operator in stack: 0x%x (%c)\n", op, op );
}
return Valstk_eval[ Valbase_eval ];
}
double StringCalculator::push( double val )
{
if ( Valsp >= STAKSZ )
printf( "stack overflow" );
return Valstk[ Valsp++ ] = val;
}
double StringCalculator::pop()
{
if ( --Valsp < 0 )
Valsp = 0;
return Valstk[ Valsp ];
}
double StringCalculator::push_eval( double val )
{
if ( Valsp_eval >= STAKSZ )
printf( "stack overflow" );
return Valstk_eval[ Valsp_eval++ ] = val;
}
double StringCalculator::pop_eval()
{
if ( --Valsp_eval < 0 )
Valsp_eval = 0;
return Valstk_eval[ Valsp_eval ];
}
int StringCalculator::expression()
{
int lvalue;
if ( !(lvalue = primary()) )
{
printf( "bad expression" );
}
else if ( Eol )
{
if ( lvalue < 0 )
generate( T_POINT, 0 );
}
else
{
op_prim( 0, lvalue );
}
return 1;
}
int StringCalculator::op_prim( int precedence, int lvalue )
{
char tkn;
int pr, lv;
while ( ! Eol )
{
pr = binop( Token );
if (
(pr>precedence && pr>0) ||
(Token==T_ASSIGN && pr>=precedence)
)
{
if ( Token == T_ASSIGN )
{
if ( lvalue > 0 )
printf( "= needs and lvalue" );
}
else if ( lvalue < 0 )
generate( T_POINT, 0 );
tkn = Token;
getoken();
if ( ! (lv = primary()) )
printf( "missing an operand" );
lvalue = op_prim( pr, lv );
if ( Token != T_ASSIGN && lvalue < 0 )
{
generate( T_POINT, 0 );
lvalue = 1;
}
else if ( tkn!=T_ASSIGN && Token==T_ASSIGN )
{
printf( "= needs an lvalue" );
}
generate( tkn, 0 );
}
else
break;
}
return lvalue;
}
int StringCalculator::primary()
{
int rtn;
if ( Eol )
return 0;
rtn = 1;
switch ( Token )
{
case T_SYMBOL: /* a symbol */
generate( Token, Value, symbol_index );
getoken();
break;
case T_CONST: /* a constant */
generate( Token, Value );
getoken();
break;
case T_LPAR: /* a parenthesized expression */
getoken();
expression();
if ( Token != T_RPAR )
{
printf( "missing ')'" );
rtn = 0;
}
else
getoken();
break;
case T_SUB: /* unary - */
getoken();
expression();
generate( T_NEG, 0 );
break;
case T_NOT: /* unary ~ */
getoken();
expression();
generate( T_NOT, 0 );
break;
case T_ADD: /* unary + */
getoken();
expression();
break;
default:
rtn = 0;
}
return rtn;
}
int StringCalculator::binop( char op )
{
switch ( op )
{
case T_ADD:
case T_SUB:
return 7;
case T_MUL:
case T_DIV:
case T_MOD:
return 8;
case T_NOT:
return 9;
}
return 0;
}
void StringCalculator::generate( char tkn, double val, int index )
{
if ( Opsp < STAKSZ )
{
Opstk[ Opsp ].o_token = tkn;
Opstk[ Opsp ].o_value = val;
Opstk[ Opsp ].symbol_index = index;
++Opsp;
}
else
printf( "expression too complex" );
}
char StringCalculator::getoken(int* )
{
char *cp, buf[ 128 ];
if ( ! *Lineptr )
{
Eol = 1;
Token = T_EOL;
}
else if ( isdigit( *Lineptr ) )
{
Token = T_CONST;
for ( cp = buf; isdigit( *Lineptr ) || *Lineptr == '.'; )
*cp++ = *Lineptr++;
*cp = 0;
Value = atof(buf);
}
else if ( (Token = isbinop( &Lineptr )) )
{
;
}
else if ( isalpha( *Lineptr ) )
{
Token = T_SYMBOL;
symbol_index = toupper( *Lineptr ) - 'A';
++Lineptr;
}
else
{
printf( "bad syntax: %s", Lineptr );
++Lineptr;
}
return Token;
}
int StringCalculator::isbinop( char** cpp )
{
int tkn=1;
char c;
c = **cpp;
if ( c == ',' )
tkn = T_COMMA;
else if ( c == '=' )
tkn = T_ASSIGN;
else if ( c == '<' )
{
if ( *(++(*cpp)) == '<' )
tkn = T_SHL;
}
else if ( c == '>' )
{
if ( *(++(*cpp)) == '>' )
tkn = T_SHR;
}
else if ( c == '(' )
tkn = T_LPAR;
else if ( c == ')' )
tkn = T_RPAR;
else if ( c == '*' )
tkn = T_MUL;
else if ( c == '/' )
tkn = T_DIV;
else if ( c == '+' )
tkn = T_ADD;
else if ( c == '-' )
tkn = T_SUB;
else
tkn = 0;
if ( tkn )
++(*cpp);
return tkn;
}
Subscribe to:
Posts (Atom)