diff options
author | joye <joye> | 2014-07-08 17:13:47 (GMT) |
---|---|---|
committer | joye <joye> | 2014-07-08 17:13:47 (GMT) |
commit | ce9561bee4d1cd04214541cce65c3a93fe605ad5 (patch) | |
tree | dd64cca971f11d68e2542fc17d108d4bd5e68393 /src/bltVecMath.C | |
parent | f6affbcfef4841070559bd95d40f5a2c26581f7e (diff) | |
download | blt-ce9561bee4d1cd04214541cce65c3a93fe605ad5.zip blt-ce9561bee4d1cd04214541cce65c3a93fe605ad5.tar.gz blt-ce9561bee4d1cd04214541cce65c3a93fe605ad5.tar.bz2 |
*** empty log message ***
Diffstat (limited to 'src/bltVecMath.C')
-rw-r--r-- | src/bltVecMath.C | 2553 |
1 files changed, 1275 insertions, 1278 deletions
diff --git a/src/bltVecMath.C b/src/bltVecMath.C index efe6a27..cdcb5e8 100644 --- a/src/bltVecMath.C +++ b/src/bltVecMath.C @@ -58,7 +58,7 @@ typedef double (ScalarProc)(Vector *vPtr); /* * Built-in math functions: */ -typedef int (GenericMathProc) (); +typedef int (GenericMathProc) (void*, Tcl_Interp*, Vector*); /* * MathFunction -- @@ -69,16 +69,16 @@ typedef int (GenericMathProc) (); * functions. */ typedef struct { - const char *name; /* Name of built-in math function. If + const char *name; /* Name of built-in math function. If * NULL, indicates that the function * was user-defined and dynamically * allocated. Function names are * global across all interpreters. */ - void *proc; /* Procedure that implements this math + void *proc; /* Procedure that implements this math * function. */ - ClientData clientData; /* Argument to pass when invoking the + ClientData clientData; /* Argument to pass when invoking the * function. */ } MathFunction; @@ -97,18 +97,18 @@ typedef struct { * of types is important. Consult the code before changing it. */ enum Tokens { - VALUE, OPEN_PAREN, CLOSE_PAREN, COMMA, END, UNKNOWN, - MULT = 8, DIVIDE, MOD, PLUS, MINUS, - LEFT_SHIFT, RIGHT_SHIFT, - LESS, GREATER, LEQ, GEQ, EQUAL, NEQ, - OLD_BIT_AND, EXPONENT, OLD_BIT_OR, OLD_QUESTY, OLD_COLON, - AND, OR, UNARY_MINUS, OLD_UNARY_PLUS, NOT, OLD_BIT_NOT + VALUE, OPEN_PAREN, CLOSE_PAREN, COMMA, END, UNKNOWN, + MULT = 8, DIVIDE, MOD, PLUS, MINUS, + LEFT_SHIFT, RIGHT_SHIFT, + LESS, GREATER, LEQ, GEQ, EQUAL, NEQ, + OLD_BIT_AND, EXPONENT, OLD_BIT_OR, OLD_QUESTY, OLD_COLON, + AND, OR, UNARY_MINUS, OLD_UNARY_PLUS, NOT, OLD_BIT_NOT }; typedef struct { - Vector *vPtr; - char staticSpace[STATIC_STRING_SPACE]; - ParseValue pv; /* Used to hold a string value, if any. */ + Vector *vPtr; + char staticSpace[STATIC_STRING_SPACE]; + ParseValue pv; /* Used to hold a string value, if any. */ } Value; /* @@ -118,15 +118,15 @@ typedef struct { * expression. It's passed among the routines in this module. */ typedef struct { - const char *expr; /* The entire right-hand side of the + const char *expr; /* The entire right-hand side of the * expression, as originally passed to * Blt_ExprVector. */ - const char *nextPtr; /* Position of the next character to - * be scanned from the expression - * string. */ + const char *nextPtr; /* Position of the next character to + * be scanned from the expression + * string. */ - enum Tokens token; /* Type of the last token to be parsed + enum Tokens token; /* Type of the last token to be parsed * from nextPtr. See below for * definitions. Corresponds to the * characters just before nextPtr. */ @@ -137,7 +137,7 @@ typedef struct { * Precedence table. The values for non-operator token types are ignored. */ static int precTable[] = -{ + { 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 12, /* MULT, DIVIDE, MOD */ 11, 11, /* PLUS, MINUS */ @@ -153,7 +153,7 @@ static int precTable[] = 1, /* OLD_COLON */ 14, 14, 14, 14 /* UNARY_MINUS, OLD_UNARY_PLUS, NOT, * OLD_BIT_NOT */ -}; + }; /* @@ -161,7 +161,7 @@ static int precTable[] = */ static int NextValue(Tcl_Interp* interp, ParseInfo *piPtr, int prec, - Value *valuePtr); + Value *valuePtr); /* *--------------------------------------------------------------------------- @@ -182,100 +182,100 @@ static int NextValue(Tcl_Interp* interp, ParseInfo *piPtr, int prec, static int Sort(Vector *vPtr) { - size_t *map; - double *values; - int i; - - map = Blt_Vec_SortMap(&vPtr, 1); - values = malloc(sizeof(double) * vPtr->length); - for(i = vPtr->first; i <= vPtr->last; i++) { - values[i] = vPtr->valueArr[map[i]]; - } - free(map); - for (i = vPtr->first; i <= vPtr->last; i++) { - vPtr->valueArr[i] = values[i]; - } - free(values); - return TCL_OK; + size_t *map; + double *values; + int i; + + map = Blt_Vec_SortMap(&vPtr, 1); + values = (double*)malloc(sizeof(double) * vPtr->length); + for(i = vPtr->first; i <= vPtr->last; i++) { + values[i] = vPtr->valueArr[map[i]]; + } + free(map); + for (i = vPtr->first; i <= vPtr->last; i++) { + vPtr->valueArr[i] = values[i]; + } + free(values); + return TCL_OK; } static double Length(Blt_Vector *vectorPtr) { - Vector *vPtr = (Vector *)vectorPtr; + Vector *vPtr = (Vector *)vectorPtr; - return (double)(vPtr->last - vPtr->first + 1); + return (double)(vPtr->last - vPtr->first + 1); } double Blt_VecMax(Blt_Vector *vectorPtr) { - Vector *vPtr = (Vector *)vectorPtr; + Vector *vPtr = (Vector *)vectorPtr; - return Blt_Vec_Max(vPtr); + return Blt_Vec_Max(vPtr); } double Blt_VecMin(Blt_Vector *vectorPtr) { - Vector *vPtr = (Vector *)vectorPtr; + Vector *vPtr = (Vector *)vectorPtr; - return Blt_Vec_Min(vPtr); + return Blt_Vec_Min(vPtr); } static double Product(Blt_Vector *vectorPtr) { - Vector *vPtr = (Vector *)vectorPtr; - double prod; - double *vp, *vend; + Vector *vPtr = (Vector *)vectorPtr; + double prod; + double *vp, *vend; - prod = 1.0; - for(vp = vPtr->valueArr + vPtr->first, - vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) { - prod *= *vp; - } - return prod; + prod = 1.0; + for(vp = vPtr->valueArr + vPtr->first, + vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) { + prod *= *vp; + } + return prod; } static double Sum(Blt_Vector *vectorPtr) { - Vector *vPtr = (Vector *)vectorPtr; - double sum, c; - double *vp, *vend; + Vector *vPtr = (Vector *)vectorPtr; + double sum, c; + double *vp, *vend; - /* Kahan summation algorithm */ + /* Kahan summation algorithm */ - vp = vPtr->valueArr + vPtr->first; - sum = *vp++; - c = 0.0; /* A running compensation for lost + vp = vPtr->valueArr + vPtr->first; + sum = *vp++; + c = 0.0; /* A running compensation for lost * low-order bits.*/ - for (vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) { - double y, t; + for (vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) { + double y, t; - y = *vp - c; /* So far, so good: c is zero.*/ - t = sum + y; /* Alas, sum is big, y small, so + y = *vp - c; /* So far, so good: c is zero.*/ + t = sum + y; /* Alas, sum is big, y small, so * low-order digits of y are lost.*/ - c = (t - sum) - y; /* (t - sum) recovers the high-order - * part of y; subtracting y recovers - * -(low part of y) */ - sum = t; - } - return sum; + c = (t - sum) - y; /* (t - sum) recovers the high-order + * part of y; subtracting y recovers + * -(low part of y) */ + sum = t; + } + return sum; } static double Mean(Blt_Vector *vectorPtr) { - Vector *vPtr = (Vector *)vectorPtr; - double sum; - int n; + Vector *vPtr = (Vector *)vectorPtr; + double sum; + int n; - sum = Sum(vectorPtr); - n = vPtr->last - vPtr->first + 1; - return sum / (double)n; + sum = Sum(vectorPtr); + n = vPtr->last - vPtr->first + 1; + return sum / (double)n; } /* @@ -284,27 +284,27 @@ Mean(Blt_Vector *vectorPtr) static double Variance(Blt_Vector *vectorPtr) { - Vector *vPtr = (Vector *)vectorPtr; - double var, mean; - double *vp, *vend; - int count; - - mean = Mean(vectorPtr); - var = 0.0; - count = 0; - for(vp = vPtr->valueArr + vPtr->first, + Vector *vPtr = (Vector *)vectorPtr; + double var, mean; + double *vp, *vend; + int count; + + mean = Mean(vectorPtr); + var = 0.0; + count = 0; + for(vp = vPtr->valueArr + vPtr->first, vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) { - double dx; + double dx; - dx = *vp - mean; - var += dx * dx; - count++; - } - if (count < 2) { - return 0.0; - } - var /= (double)(count - 1); - return var; + dx = *vp - mean; + var += dx * dx; + count++; + } + if (count < 2) { + return 0.0; + } + var /= (double)(count - 1); + return var; } /* @@ -313,264 +313,264 @@ Variance(Blt_Vector *vectorPtr) static double Skew(Blt_Vector *vectorPtr) { - Vector *vPtr = (Vector *)vectorPtr; - double diff, var, skew, mean, diffsq; - double *vp, *vend; - int count; - - mean = Mean(vectorPtr); - var = skew = 0.0; - count = 0; - for(vp = vPtr->valueArr + vPtr->first, - vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) { - diff = *vp - mean; - diff = fabs(diff); - diffsq = diff * diff; - var += diffsq; - skew += diffsq * diff; - count++; - } - if (count < 2) { - return 0.0; - } - var /= (double)(count - 1); - skew /= count * var * sqrt(var); - return skew; + Vector *vPtr = (Vector *)vectorPtr; + double diff, var, skew, mean, diffsq; + double *vp, *vend; + int count; + + mean = Mean(vectorPtr); + var = skew = 0.0; + count = 0; + for(vp = vPtr->valueArr + vPtr->first, + vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) { + diff = *vp - mean; + diff = fabs(diff); + diffsq = diff * diff; + var += diffsq; + skew += diffsq * diff; + count++; + } + if (count < 2) { + return 0.0; + } + var /= (double)(count - 1); + skew /= count * var * sqrt(var); + return skew; } static double StdDeviation(Blt_Vector *vectorPtr) { - double var; + double var; - var = Variance(vectorPtr); - if (var > 0.0) { - return sqrt(var); - } - return 0.0; + var = Variance(vectorPtr); + if (var > 0.0) { + return sqrt(var); + } + return 0.0; } static double AvgDeviation(Blt_Vector *vectorPtr) { - Vector *vPtr = (Vector *)vectorPtr; - double diff, avg, mean; - double *vp, *vend; - int count; - - mean = Mean(vectorPtr); - avg = 0.0; - count = 0; - for(vp = vPtr->valueArr + vPtr->first, - vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) { - diff = *vp - mean; - avg += fabs(diff); - count++; - } - if (count < 2) { - return 0.0; - } - avg /= (double)count; - return avg; + Vector *vPtr = (Vector *)vectorPtr; + double diff, avg, mean; + double *vp, *vend; + int count; + + mean = Mean(vectorPtr); + avg = 0.0; + count = 0; + for(vp = vPtr->valueArr + vPtr->first, + vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) { + diff = *vp - mean; + avg += fabs(diff); + count++; + } + if (count < 2) { + return 0.0; + } + avg /= (double)count; + return avg; } static double Kurtosis(Blt_Vector *vectorPtr) { - Vector *vPtr = (Vector *)vectorPtr; - double diff, diffsq, kurt, var, mean; - double *vp, *vend; - int count; - - mean = Mean(vectorPtr); - var = kurt = 0.0; - count = 0; - for(vp = vPtr->valueArr + vPtr->first, - vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) { - diff = *vp - mean; - diffsq = diff * diff; - var += diffsq; - kurt += diffsq * diffsq; - count++; - } - if (count < 2) { - return 0.0; - } - var /= (double)(count - 1); - if (var == 0.0) { - return 0.0; - } - kurt /= (count * var * var); - return kurt - 3.0; /* Fisher Kurtosis */ + Vector *vPtr = (Vector *)vectorPtr; + double diff, diffsq, kurt, var, mean; + double *vp, *vend; + int count; + + mean = Mean(vectorPtr); + var = kurt = 0.0; + count = 0; + for(vp = vPtr->valueArr + vPtr->first, + vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) { + diff = *vp - mean; + diffsq = diff * diff; + var += diffsq; + kurt += diffsq * diffsq; + count++; + } + if (count < 2) { + return 0.0; + } + var /= (double)(count - 1); + if (var == 0.0) { + return 0.0; + } + kurt /= (count * var * var); + return kurt - 3.0; /* Fisher Kurtosis */ } static double Median(Blt_Vector *vectorPtr) { - Vector *vPtr = (Vector *)vectorPtr; - size_t *map; - double q2; - int mid; - - if (vPtr->length == 0) { - return -DBL_MAX; - } - map = Blt_Vec_SortMap(&vPtr, 1); - mid = (vPtr->length - 1) / 2; - - /* - * Determine Q2 by checking if the number of elements [0..n-1] is - * odd or even. If even, we must take the average of the two - * middle values. - */ - if (vPtr->length & 1) { /* Odd */ - q2 = vPtr->valueArr[map[mid]]; - } else { /* Even */ - q2 = (vPtr->valueArr[map[mid]] + - vPtr->valueArr[map[mid + 1]]) * 0.5; - } - free(map); - return q2; + Vector *vPtr = (Vector *)vectorPtr; + size_t *map; + double q2; + int mid; + + if (vPtr->length == 0) { + return -DBL_MAX; + } + map = Blt_Vec_SortMap(&vPtr, 1); + mid = (vPtr->length - 1) / 2; + + /* + * Determine Q2 by checking if the number of elements [0..n-1] is + * odd or even. If even, we must take the average of the two + * middle values. + */ + if (vPtr->length & 1) { /* Odd */ + q2 = vPtr->valueArr[map[mid]]; + } else { /* Even */ + q2 = (vPtr->valueArr[map[mid]] + + vPtr->valueArr[map[mid + 1]]) * 0.5; + } + free(map); + return q2; } static double Q1(Blt_Vector *vectorPtr) { - Vector *vPtr = (Vector *)vectorPtr; - double q1; - size_t *map; + Vector *vPtr = (Vector *)vectorPtr; + double q1; + size_t *map; - if (vPtr->length == 0) { - return -DBL_MAX; - } - map = Blt_Vec_SortMap(&vPtr, 1); + if (vPtr->length == 0) { + return -DBL_MAX; + } + map = Blt_Vec_SortMap(&vPtr, 1); - if (vPtr->length < 4) { - q1 = vPtr->valueArr[map[0]]; - } else { - int mid, q; - - mid = (vPtr->length - 1) / 2; - q = mid / 2; - - /* - * Determine Q1 by checking if the number of elements in the - * bottom half [0..mid) is odd or even. If even, we must - * take the average of the two middle values. - */ - if (mid & 1) { /* Odd */ - q1 = vPtr->valueArr[map[q]]; - } else { /* Even */ - q1 = (vPtr->valueArr[map[q]] + - vPtr->valueArr[map[q + 1]]) * 0.5; - } + if (vPtr->length < 4) { + q1 = vPtr->valueArr[map[0]]; + } else { + int mid, q; + + mid = (vPtr->length - 1) / 2; + q = mid / 2; + + /* + * Determine Q1 by checking if the number of elements in the + * bottom half [0..mid) is odd or even. If even, we must + * take the average of the two middle values. + */ + if (mid & 1) { /* Odd */ + q1 = vPtr->valueArr[map[q]]; + } else { /* Even */ + q1 = (vPtr->valueArr[map[q]] + + vPtr->valueArr[map[q + 1]]) * 0.5; } - free(map); - return q1; + } + free(map); + return q1; } static double Q3(Blt_Vector *vectorPtr) { - Vector *vPtr = (Vector *)vectorPtr; - double q3; - size_t *map; + Vector *vPtr = (Vector *)vectorPtr; + double q3; + size_t *map; - if (vPtr->length == 0) { - return -DBL_MAX; - } + if (vPtr->length == 0) { + return -DBL_MAX; + } - map = Blt_Vec_SortMap(&vPtr, 1); + map = Blt_Vec_SortMap(&vPtr, 1); - if (vPtr->length < 4) { - q3 = vPtr->valueArr[map[vPtr->length - 1]]; - } else { - int mid, q; - - mid = (vPtr->length - 1) / 2; - q = (vPtr->length + mid) / 2; - - /* - * Determine Q3 by checking if the number of elements in the - * upper half (mid..n-1] is odd or even. If even, we must - * take the average of the two middle values. - */ - if (mid & 1) { /* Odd */ - q3 = vPtr->valueArr[map[q]]; - } else { /* Even */ - q3 = (vPtr->valueArr[map[q]] + - vPtr->valueArr[map[q + 1]]) * 0.5; - } + if (vPtr->length < 4) { + q3 = vPtr->valueArr[map[vPtr->length - 1]]; + } else { + int mid, q; + + mid = (vPtr->length - 1) / 2; + q = (vPtr->length + mid) / 2; + + /* + * Determine Q3 by checking if the number of elements in the + * upper half (mid..n-1] is odd or even. If even, we must + * take the average of the two middle values. + */ + if (mid & 1) { /* Odd */ + q3 = vPtr->valueArr[map[q]]; + } else { /* Even */ + q3 = (vPtr->valueArr[map[q]] + + vPtr->valueArr[map[q + 1]]) * 0.5; } - free(map); - return q3; + } + free(map); + return q3; } static int Norm(Blt_Vector *vector) { - Vector *vPtr = (Vector *)vector; - double norm, range, min, max; - int i; - - min = Blt_Vec_Min(vPtr); - max = Blt_Vec_Max(vPtr); - range = max - min; - for (i = 0; i < vPtr->length; i++) { - norm = (vPtr->valueArr[i] - min) / range; - vPtr->valueArr[i] = norm; - } - return TCL_OK; + Vector *vPtr = (Vector *)vector; + double norm, range, min, max; + int i; + + min = Blt_Vec_Min(vPtr); + max = Blt_Vec_Max(vPtr); + range = max - min; + for (i = 0; i < vPtr->length; i++) { + norm = (vPtr->valueArr[i] - min) / range; + vPtr->valueArr[i] = norm; + } + return TCL_OK; } static double Nonzeros(Blt_Vector *vector) { - Vector *vPtr = (Vector *)vector; - int count; - double *vp, *vend; + Vector *vPtr = (Vector *)vector; + int count; + double *vp, *vend; - count = 0; - for(vp = vPtr->valueArr + vPtr->first, - vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) { - if (*vp == 0.0) { - count++; - } + count = 0; + for(vp = vPtr->valueArr + vPtr->first, + vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) { + if (*vp == 0.0) { + count++; } - return (double) count; + } + return (double) count; } static double Fabs(double value) { - if (value < 0.0) { - return -value; - } - return value; + if (value < 0.0) { + return -value; + } + return value; } static double Round(double value) { - if (value < 0.0) { - return ceil(value - 0.5); - } else { - return floor(value + 0.5); - } + if (value < 0.0) { + return ceil(value - 0.5); + } else { + return floor(value + 0.5); + } } static double Fmod(double x, double y) { - if (y == 0.0) { - return 0.0; - } - return x - (floor(x / y) * y); + if (y == 0.0) { + return 0.0; + } + return x - (floor(x / y) * y); } /* @@ -592,36 +592,36 @@ Fmod(double x, double y) */ static void MathError( - Tcl_Interp* interp, /* Where to store error message. */ - double value) /* Value returned after error; used to + Tcl_Interp* interp, /* Where to store error message. */ + double value) /* Value returned after error; used to * distinguish underflows from * overflows. */ { - if ((errno == EDOM) || (value != value)) { - Tcl_AppendResult(interp, "domain error: argument not in valid range", - (char *)NULL); - Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", - Tcl_GetStringResult(interp), (char *)NULL); - } else if ((errno == ERANGE) || isinf(value)) { - if (value == 0.0) { - Tcl_AppendResult(interp, - "floating-point value too small to represent", - (char *)NULL); - Tcl_SetErrorCode(interp, "ARITH", "UNDERFLOW", - Tcl_GetStringResult(interp), (char *)NULL); - } else { - Tcl_AppendResult(interp, - "floating-point value too large to represent", - (char *)NULL); - Tcl_SetErrorCode(interp, "ARITH", "OVERFLOW", - Tcl_GetStringResult(interp), (char *)NULL); - } + if ((errno == EDOM) || (value != value)) { + Tcl_AppendResult(interp, "domain error: argument not in valid range", + (char *)NULL); + Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", + Tcl_GetStringResult(interp), (char *)NULL); + } else if ((errno == ERANGE) || isinf(value)) { + if (value == 0.0) { + Tcl_AppendResult(interp, + "floating-point value too small to represent", + (char *)NULL); + Tcl_SetErrorCode(interp, "ARITH", "UNDERFLOW", + Tcl_GetStringResult(interp), (char *)NULL); } else { - Tcl_AppendResult(interp, "unknown floating-point error, ", - "errno = ", Blt_Itoa(errno), (char *)NULL); - Tcl_SetErrorCode(interp, "ARITH", "UNKNOWN", - Tcl_GetStringResult(interp), (char *)NULL); + Tcl_AppendResult(interp, + "floating-point value too large to represent", + (char *)NULL); + Tcl_SetErrorCode(interp, "ARITH", "OVERFLOW", + Tcl_GetStringResult(interp), (char *)NULL); } + } else { + Tcl_AppendResult(interp, "unknown floating-point error, ", + "errno = ", Blt_Itoa(errno), (char *)NULL); + Tcl_SetErrorCode(interp, "ARITH", "UNKNOWN", + Tcl_GetStringResult(interp), (char *)NULL); + } } /* @@ -648,55 +648,55 @@ MathError( static int ParseString( - Tcl_Interp* interp, /* Where to store error message. */ - const char *string, /* String to turn into value. */ - Value *valuePtr) /* Where to store value information. - * Caller must have initialized pv field. */ + Tcl_Interp* interp, /* Where to store error message. */ + const char *string, /* String to turn into value. */ + Value *valuePtr) /* Where to store value information. + * Caller must have initialized pv field. */ { - const char *endPtr; - double value; - - errno = 0; + const char *endPtr; + double value; - /* - * The string can be either a number or a vector. First try to - * convert the string to a number. If that fails then see if - * we can find a vector by that name. - */ + errno = 0; - value = strtod(string, (char **)&endPtr); - if ((endPtr != string) && (*endPtr == '\0')) { - if (errno != 0) { - Tcl_ResetResult(interp); - MathError(interp, value); - return TCL_ERROR; - } - /* Numbers are stored as single element vectors. */ - if (Blt_Vec_ChangeLength(interp, valuePtr->vPtr, 1) != TCL_OK) { - return TCL_ERROR; - } - valuePtr->vPtr->valueArr[0] = value; - return TCL_OK; - } else { - Vector *vPtr; + /* + * The string can be either a number or a vector. First try to + * convert the string to a number. If that fails then see if + * we can find a vector by that name. + */ - while (isspace((unsigned char)(*string))) { - string++; /* Skip spaces leading the vector name. */ - } - vPtr = Blt_Vec_ParseElement(interp, valuePtr->vPtr->dataPtr, - string, &endPtr, NS_SEARCH_BOTH); - if (vPtr == NULL) { - return TCL_ERROR; - } - if (*endPtr != '\0') { - Tcl_AppendResult(interp, "extra characters after vector", - (char *)NULL); - return TCL_ERROR; - } - /* Copy the designated vector to our temporary. */ - Blt_Vec_Duplicate(valuePtr->vPtr, vPtr); + value = strtod(string, (char **)&endPtr); + if ((endPtr != string) && (*endPtr == '\0')) { + if (errno != 0) { + Tcl_ResetResult(interp); + MathError(interp, value); + return TCL_ERROR; + } + /* Numbers are stored as single element vectors. */ + if (Blt_Vec_ChangeLength(interp, valuePtr->vPtr, 1) != TCL_OK) { + return TCL_ERROR; } + valuePtr->vPtr->valueArr[0] = value; return TCL_OK; + } else { + Vector *vPtr; + + while (isspace((unsigned char)(*string))) { + string++; /* Skip spaces leading the vector name. */ + } + vPtr = Blt_Vec_ParseElement(interp, valuePtr->vPtr->dataPtr, + string, &endPtr, NS_SEARCH_BOTH); + if (vPtr == NULL) { + return TCL_ERROR; + } + if (*endPtr != '\0') { + Tcl_AppendResult(interp, "extra characters after vector", + (char *)NULL); + return TCL_ERROR; + } + /* Copy the designated vector to our temporary. */ + Blt_Vec_Duplicate(valuePtr->vPtr, vPtr); + } + return TCL_OK; } /* @@ -726,64 +726,64 @@ ParseString( */ static int ParseMathFunction( - Tcl_Interp* interp, /* Interpreter to use for error reporting. */ - const char *start, /* Start of string to parse */ - ParseInfo *piPtr, /* Describes the state of the parse. - * piPtr->nextPtr must point to the - * first character of the function's - * name. */ - Value *valuePtr) /* Where to store value, if that is - * what's parsed from string. Caller - * must have initialized pv field - * correctly. */ + Tcl_Interp* interp, /* Interpreter to use for error reporting. */ + const char *start, /* Start of string to parse */ + ParseInfo *piPtr, /* Describes the state of the parse. + * piPtr->nextPtr must point to the + * first character of the function's + * name. */ + Value *valuePtr) /* Where to store value, if that is + * what's parsed from string. Caller + * must have initialized pv field + * correctly. */ { - Tcl_HashEntry *hPtr; - MathFunction *mathPtr; /* Info about math function. */ - char *p; - VectorInterpData *dataPtr; /* Interpreter-specific data. */ - GenericMathProc *proc; - - /* - * Find the end of the math function's name and lookup the - * record for the function. - */ - p = (char *)start; - while (isspace((unsigned char)(*p))) { - p++; - } - piPtr->nextPtr = p; - while (isalnum((unsigned char)(*p)) || (*p == '_')) { - p++; - } - if (*p != '(') { - return TCL_RETURN; /* Must start with open parenthesis */ - } - dataPtr = valuePtr->vPtr->dataPtr; - *p = '\0'; - hPtr = Tcl_FindHashEntry(&dataPtr->mathProcTable, piPtr->nextPtr); - *p = '('; - if (hPtr == NULL) { - return TCL_RETURN; /* Name doesn't match any known function */ - } - /* Pick up the single value as the argument to the function */ - piPtr->token = OPEN_PAREN; - piPtr->nextPtr = p + 1; - valuePtr->pv.next = valuePtr->pv.buffer; - if (NextValue(interp, piPtr, -1, valuePtr) != TCL_OK) { - return TCL_ERROR; /* Parse error */ - } - if (piPtr->token != CLOSE_PAREN) { - Tcl_AppendResult(interp, "unmatched parentheses in expression \"", - piPtr->expr, "\"", (char *)NULL); - return TCL_ERROR; /* Missing right parenthesis */ - } - mathPtr = Tcl_GetHashValue(hPtr); - proc = mathPtr->proc; - if ((*proc) (mathPtr->clientData, interp, valuePtr->vPtr) != TCL_OK) { - return TCL_ERROR; /* Function invocation error */ - } - piPtr->token = VALUE; - return TCL_OK; + Tcl_HashEntry *hPtr; + MathFunction *mathPtr; /* Info about math function. */ + char *p; + VectorInterpData *dataPtr; /* Interpreter-specific data. */ + GenericMathProc *proc; + + /* + * Find the end of the math function's name and lookup the + * record for the function. + */ + p = (char *)start; + while (isspace((unsigned char)(*p))) { + p++; + } + piPtr->nextPtr = p; + while (isalnum((unsigned char)(*p)) || (*p == '_')) { + p++; + } + if (*p != '(') { + return TCL_RETURN; /* Must start with open parenthesis */ + } + dataPtr = valuePtr->vPtr->dataPtr; + *p = '\0'; + hPtr = Tcl_FindHashEntry(&dataPtr->mathProcTable, piPtr->nextPtr); + *p = '('; + if (hPtr == NULL) { + return TCL_RETURN; /* Name doesn't match any known function */ + } + /* Pick up the single value as the argument to the function */ + piPtr->token = OPEN_PAREN; + piPtr->nextPtr = p + 1; + valuePtr->pv.next = valuePtr->pv.buffer; + if (NextValue(interp, piPtr, -1, valuePtr) != TCL_OK) { + return TCL_ERROR; /* Parse error */ + } + if (piPtr->token != CLOSE_PAREN) { + Tcl_AppendResult(interp, "unmatched parentheses in expression \"", + piPtr->expr, "\"", (char *)NULL); + return TCL_ERROR; /* Missing right parenthesis */ + } + mathPtr = (MathFunction*)Tcl_GetHashValue(hPtr); + proc = (GenericMathProc*)mathPtr->proc; + if ((*proc) (mathPtr->clientData, interp, valuePtr->vPtr) != TCL_OK) { + return TCL_ERROR; /* Function invocation error */ + } + piPtr->token = VALUE; + return TCL_OK; } /* @@ -811,228 +811,228 @@ ParseMathFunction( */ static int NextToken( - Tcl_Interp* interp, /* Interpreter to use for error reporting. */ - ParseInfo *piPtr, /* Describes the state of the parse. */ - Value *valuePtr) /* Where to store value, if that is - * what's parsed from string. Caller - * must have initialized pv field - * correctly. */ + Tcl_Interp* interp, /* Interpreter to use for error reporting. */ + ParseInfo *piPtr, /* Describes the state of the parse. */ + Value *valuePtr) /* Where to store value, if that is + * what's parsed from string. Caller + * must have initialized pv field + * correctly. */ { - const char *p; - const char *endPtr; - const char *var; - int result; - - p = piPtr->nextPtr; - while (isspace((unsigned char)(*p))) { - p++; + const char *p; + const char *endPtr; + const char *var; + int result; + + p = piPtr->nextPtr; + while (isspace((unsigned char)(*p))) { + p++; + } + if (*p == '\0') { + piPtr->token = END; + piPtr->nextPtr = p; + return TCL_OK; + } + /* + * Try to parse the token as a floating-point number. But check + * that the first character isn't a "-" or "+", which "strtod" + * will happily accept as an unary operator. Otherwise, we might + * accidently treat a binary operator as unary by mistake, which + * will eventually cause a syntax error. + */ + if ((*p != '-') && (*p != '+')) { + double value; + + errno = 0; + value = strtod(p, (char **)&endPtr); + if (endPtr != p) { + if (errno != 0) { + MathError(interp, value); + return TCL_ERROR; + } + piPtr->token = VALUE; + piPtr->nextPtr = endPtr; + + /* + * Save the single floating-point value as an 1-component vector. + */ + if (Blt_Vec_ChangeLength(interp, valuePtr->vPtr, 1) != TCL_OK) { + return TCL_ERROR; + } + valuePtr->vPtr->valueArr[0] = value; + return TCL_OK; } - if (*p == '\0') { - piPtr->token = END; - piPtr->nextPtr = p; - return TCL_OK; + } + piPtr->nextPtr = p + 1; + switch (*p) { + case '$': + piPtr->token = VALUE; + var = Tcl_ParseVar(interp, p, &endPtr); + if (var == NULL) { + return TCL_ERROR; } - /* - * Try to parse the token as a floating-point number. But check - * that the first character isn't a "-" or "+", which "strtod" - * will happily accept as an unary operator. Otherwise, we might - * accidently treat a binary operator as unary by mistake, which - * will eventually cause a syntax error. - */ - if ((*p != '-') && (*p != '+')) { - double value; - - errno = 0; - value = strtod(p, (char **)&endPtr); - if (endPtr != p) { - if (errno != 0) { - MathError(interp, value); - return TCL_ERROR; - } - piPtr->token = VALUE; - piPtr->nextPtr = endPtr; - - /* - * Save the single floating-point value as an 1-component vector. - */ - if (Blt_Vec_ChangeLength(interp, valuePtr->vPtr, 1) != TCL_OK) { - return TCL_ERROR; - } - valuePtr->vPtr->valueArr[0] = value; - return TCL_OK; - } + piPtr->nextPtr = endPtr; + Tcl_ResetResult(interp); + result = ParseString(interp, var, valuePtr); + return result; + + case '[': + piPtr->token = VALUE; + result = Blt_ParseNestedCmd(interp, p + 1, 0, &endPtr, &valuePtr->pv); + if (result != TCL_OK) { + return result; } - piPtr->nextPtr = p + 1; - switch (*p) { - case '$': - piPtr->token = VALUE; - var = Tcl_ParseVar(interp, p, &endPtr); - if (var == NULL) { - return TCL_ERROR; - } - piPtr->nextPtr = endPtr; - Tcl_ResetResult(interp); - result = ParseString(interp, var, valuePtr); - return result; - - case '[': - piPtr->token = VALUE; - result = Blt_ParseNestedCmd(interp, p + 1, 0, &endPtr, &valuePtr->pv); - if (result != TCL_OK) { - return result; - } - piPtr->nextPtr = endPtr; - Tcl_ResetResult(interp); - result = ParseString(interp, valuePtr->pv.buffer, valuePtr); - return result; - - case '"': - piPtr->token = VALUE; - result = Blt_ParseQuotes(interp, p + 1, '"', 0, &endPtr, &valuePtr->pv); - if (result != TCL_OK) { - return result; - } - piPtr->nextPtr = endPtr; - Tcl_ResetResult(interp); - result = ParseString(interp, valuePtr->pv.buffer, valuePtr); - return result; - - case '{': - piPtr->token = VALUE; - result = Blt_ParseBraces(interp, p + 1, &endPtr, &valuePtr->pv); - if (result != TCL_OK) { - return result; - } - piPtr->nextPtr = endPtr; - Tcl_ResetResult(interp); - result = ParseString(interp, valuePtr->pv.buffer, valuePtr); - return result; + piPtr->nextPtr = endPtr; + Tcl_ResetResult(interp); + result = ParseString(interp, valuePtr->pv.buffer, valuePtr); + return result; - case '(': - piPtr->token = OPEN_PAREN; - break; + case '"': + piPtr->token = VALUE; + result = Blt_ParseQuotes(interp, p + 1, '"', 0, &endPtr, &valuePtr->pv); + if (result != TCL_OK) { + return result; + } + piPtr->nextPtr = endPtr; + Tcl_ResetResult(interp); + result = ParseString(interp, valuePtr->pv.buffer, valuePtr); + return result; - case ')': - piPtr->token = CLOSE_PAREN; - break; + case '{': + piPtr->token = VALUE; + result = Blt_ParseBraces(interp, p + 1, &endPtr, &valuePtr->pv); + if (result != TCL_OK) { + return result; + } + piPtr->nextPtr = endPtr; + Tcl_ResetResult(interp); + result = ParseString(interp, valuePtr->pv.buffer, valuePtr); + return result; - case ',': - piPtr->token = COMMA; - break; + case '(': + piPtr->token = OPEN_PAREN; + break; - case '*': - piPtr->token = MULT; - break; + case ')': + piPtr->token = CLOSE_PAREN; + break; - case '/': - piPtr->token = DIVIDE; - break; + case ',': + piPtr->token = COMMA; + break; - case '%': - piPtr->token = MOD; - break; + case '*': + piPtr->token = MULT; + break; - case '+': - piPtr->token = PLUS; - break; + case '/': + piPtr->token = DIVIDE; + break; - case '-': - piPtr->token = MINUS; - break; + case '%': + piPtr->token = MOD; + break; - case '^': - piPtr->token = EXPONENT; - break; + case '+': + piPtr->token = PLUS; + break; + + case '-': + piPtr->token = MINUS; + break; + case '^': + piPtr->token = EXPONENT; + break; + + case '<': + switch (*(p + 1)) { case '<': - switch (*(p + 1)) { - case '<': - piPtr->nextPtr = p + 2; - piPtr->token = LEFT_SHIFT; - break; - case '=': - piPtr->nextPtr = p + 2; - piPtr->token = LEQ; - break; - default: - piPtr->token = LESS; - break; - } - break; + piPtr->nextPtr = p + 2; + piPtr->token = LEFT_SHIFT; + break; + case '=': + piPtr->nextPtr = p + 2; + piPtr->token = LEQ; + break; + default: + piPtr->token = LESS; + break; + } + break; + case '>': + switch (*(p + 1)) { case '>': - switch (*(p + 1)) { - case '>': - piPtr->nextPtr = p + 2; - piPtr->token = RIGHT_SHIFT; - break; - case '=': - piPtr->nextPtr = p + 2; - piPtr->token = GEQ; - break; - default: - piPtr->token = GREATER; - break; - } - break; - + piPtr->nextPtr = p + 2; + piPtr->token = RIGHT_SHIFT; + break; case '=': - if (*(p + 1) == '=') { - piPtr->nextPtr = p + 2; - piPtr->token = EQUAL; - } else { - piPtr->token = UNKNOWN; - } - break; + piPtr->nextPtr = p + 2; + piPtr->token = GEQ; + break; + default: + piPtr->token = GREATER; + break; + } + break; - case '&': - if (*(p + 1) == '&') { - piPtr->nextPtr = p + 2; - piPtr->token = AND; - } else { - piPtr->token = UNKNOWN; - } - break; + case '=': + if (*(p + 1) == '=') { + piPtr->nextPtr = p + 2; + piPtr->token = EQUAL; + } else { + piPtr->token = UNKNOWN; + } + break; - case '|': - if (*(p + 1) == '|') { - piPtr->nextPtr = p + 2; - piPtr->token = OR; - } else { - piPtr->token = UNKNOWN; - } - break; + case '&': + if (*(p + 1) == '&') { + piPtr->nextPtr = p + 2; + piPtr->token = AND; + } else { + piPtr->token = UNKNOWN; + } + break; - case '!': - if (*(p + 1) == '=') { - piPtr->nextPtr = p + 2; - piPtr->token = NEQ; - } else { - piPtr->token = NOT; - } - break; + case '|': + if (*(p + 1) == '|') { + piPtr->nextPtr = p + 2; + piPtr->token = OR; + } else { + piPtr->token = UNKNOWN; + } + break; - default: - piPtr->token = VALUE; - result = ParseMathFunction(interp, p, piPtr, valuePtr); - if ((result == TCL_OK) || (result == TCL_ERROR)) { - return result; - } else { - Vector *vPtr; - - while (isspace((unsigned char)(*p))) { - p++; /* Skip spaces leading the vector name. */ - } - vPtr = Blt_Vec_ParseElement(interp, valuePtr->vPtr->dataPtr, - p, &endPtr, NS_SEARCH_BOTH); - if (vPtr == NULL) { - return TCL_ERROR; - } - Blt_Vec_Duplicate(valuePtr->vPtr, vPtr); - piPtr->nextPtr = endPtr; - } + case '!': + if (*(p + 1) == '=') { + piPtr->nextPtr = p + 2; + piPtr->token = NEQ; + } else { + piPtr->token = NOT; } - return TCL_OK; + break; + + default: + piPtr->token = VALUE; + result = ParseMathFunction(interp, p, piPtr, valuePtr); + if ((result == TCL_OK) || (result == TCL_ERROR)) { + return result; + } else { + Vector *vPtr; + + while (isspace((unsigned char)(*p))) { + p++; /* Skip spaces leading the vector name. */ + } + vPtr = Blt_Vec_ParseElement(interp, valuePtr->vPtr->dataPtr, + p, &endPtr, NS_SEARCH_BOTH); + if (vPtr == NULL) { + return TCL_ERROR; + } + Blt_Vec_Duplicate(valuePtr->vPtr, vPtr); + piPtr->nextPtr = endPtr; + } + } + return TCL_OK; } /* @@ -1057,526 +1057,526 @@ NextToken( */ static int NextValue( - Tcl_Interp* interp, /* Interpreter to use for error reporting. */ - ParseInfo *piPtr, /* Describes the state of the parse + Tcl_Interp* interp, /* Interpreter to use for error reporting. */ + ParseInfo *piPtr, /* Describes the state of the parse * just before the value (i.e. NextToken will * be called to get first token of value). */ - int prec, /* Treat any un-parenthesized operator - * with precedence <= this as the end - * of the expression. */ - Value *valuePtr) /* Where to store the value of the expression. - * Caller must have initialized pv field. */ + int prec, /* Treat any un-parenthesized operator + * with precedence <= this as the end + * of the expression. */ + Value *valuePtr) /* Where to store the value of the expression. + * Caller must have initialized pv field. */ { - Value value2; /* Second operand for current operator. */ - int operator; /* Current operator (either unary or binary). */ - int gotOp; /* Non-zero means already lexed the operator + Value value2; /* Second operand for current operator. */ + int oper; /* Current operator (either unary or binary). */ + int gotOp; /* Non-zero means already lexed the operator * (while picking up value for unary operator). * Don't lex again. */ - int result; - Vector *vPtr, *v2Ptr; - int i; + int result; + Vector *vPtr, *v2Ptr; + int i; + + /* + * There are two phases to this procedure. First, pick off an initial + * value. Then, parse (binary operator, value) pairs until done. + */ + + vPtr = valuePtr->vPtr; + v2Ptr = Blt_Vec_New(vPtr->dataPtr); + gotOp = 0; + value2.vPtr = v2Ptr; + value2.pv.buffer = value2.pv.next = value2.staticSpace; + value2.pv.end = value2.pv.buffer + STATIC_STRING_SPACE - 1; + value2.pv.expandProc = Blt_ExpandParseValue; + value2.pv.clientData = NULL; + + result = NextToken(interp, piPtr, valuePtr); + if (result != TCL_OK) { + goto done; + } + if (piPtr->token == OPEN_PAREN) { + + /* Parenthesized sub-expression. */ + + result = NextValue(interp, piPtr, -1, valuePtr); + if (result != TCL_OK) { + goto done; + } + if (piPtr->token != CLOSE_PAREN) { + Tcl_AppendResult(interp, "unmatched parentheses in expression \"", + piPtr->expr, "\"", (char *)NULL); + result = TCL_ERROR; + goto done; + } + } else { + if (piPtr->token == MINUS) { + piPtr->token = UNARY_MINUS; + } + if (piPtr->token >= UNARY_MINUS) { + oper = piPtr->token; + result = NextValue(interp, piPtr, precTable[oper], valuePtr); + if (result != TCL_OK) { + goto done; + } + gotOp = 1; + /* Process unary operators. */ + switch (oper) { + case UNARY_MINUS: + for(i = 0; i < vPtr->length; i++) { + vPtr->valueArr[i] = -(vPtr->valueArr[i]); + } + break; + case NOT: + for(i = 0; i < vPtr->length; i++) { + vPtr->valueArr[i] = (double)(!vPtr->valueArr[i]); + } + break; + default: + Tcl_AppendResult(interp, "unknown operator", (char *)NULL); + goto error; + } + } else if (piPtr->token != VALUE) { + Tcl_AppendResult(interp, "missing operand", (char *)NULL); + goto error; + } + } + if (!gotOp) { + result = NextToken(interp, piPtr, &value2); + if (result != TCL_OK) { + goto done; + } + } + /* + * Got the first operand. Now fetch (operator, operand) pairs. + */ + for (;;) { + oper = piPtr->token; + + value2.pv.next = value2.pv.buffer; + if ((oper < MULT) || (oper >= UNARY_MINUS)) { + if ((oper == END) || (oper == CLOSE_PAREN) || + (oper == COMMA)) { + result = TCL_OK; + goto done; + } else { + Tcl_AppendResult(interp, "bad operator", (char *)NULL); + goto error; + } + } + if (precTable[oper] <= prec) { + result = TCL_OK; + goto done; + } + result = NextValue(interp, piPtr, precTable[oper], &value2); + if (result != TCL_OK) { + goto done; + } + if ((piPtr->token < MULT) && (piPtr->token != VALUE) && + (piPtr->token != END) && (piPtr->token != CLOSE_PAREN) && + (piPtr->token != COMMA)) { + Tcl_AppendResult(interp, "unexpected token in expression", + (char *)NULL); + goto error; + } /* - * There are two phases to this procedure. First, pick off an initial - * value. Then, parse (binary operator, value) pairs until done. + * At this point we have two vectors and an operator. */ - vPtr = valuePtr->vPtr; - v2Ptr = Blt_Vec_New(vPtr->dataPtr); - gotOp = 0; - value2.vPtr = v2Ptr; - value2.pv.buffer = value2.pv.next = value2.staticSpace; - value2.pv.end = value2.pv.buffer + STATIC_STRING_SPACE - 1; - value2.pv.expandProc = Blt_ExpandParseValue; - value2.pv.clientData = NULL; + if (v2Ptr->length == 1) { + double *opnd; + double scalar; + + /* + * 2nd operand is a scalar. + */ + scalar = v2Ptr->valueArr[0]; + opnd = vPtr->valueArr; + switch (oper) { + case MULT: + for(i = 0; i < vPtr->length; i++) { + opnd[i] *= scalar; + } + break; - result = NextToken(interp, piPtr, valuePtr); - if (result != TCL_OK) { - goto done; - } - if (piPtr->token == OPEN_PAREN) { + case DIVIDE: + if (scalar == 0.0) { + Tcl_AppendResult(interp, "divide by zero", (char *)NULL); + goto error; + } + for(i = 0; i < vPtr->length; i++) { + opnd[i] /= scalar; + } + break; - /* Parenthesized sub-expression. */ + case PLUS: + for(i = 0; i < vPtr->length; i++) { + opnd[i] += scalar; + } + break; - result = NextValue(interp, piPtr, -1, valuePtr); - if (result != TCL_OK) { - goto done; + case MINUS: + for(i = 0; i < vPtr->length; i++) { + opnd[i] -= scalar; } - if (piPtr->token != CLOSE_PAREN) { - Tcl_AppendResult(interp, "unmatched parentheses in expression \"", - piPtr->expr, "\"", (char *)NULL); - result = TCL_ERROR; - goto done; + break; + + case EXPONENT: + for(i = 0; i < vPtr->length; i++) { + opnd[i] = pow(opnd[i], scalar); } - } else { - if (piPtr->token == MINUS) { - piPtr->token = UNARY_MINUS; + break; + + case MOD: + for(i = 0; i < vPtr->length; i++) { + opnd[i] = Fmod(opnd[i], scalar); } - if (piPtr->token >= UNARY_MINUS) { - operator = piPtr->token; - result = NextValue(interp, piPtr, precTable[operator], valuePtr); - if (result != TCL_OK) { - goto done; - } - gotOp = 1; - /* Process unary operators. */ - switch (operator) { - case UNARY_MINUS: - for(i = 0; i < vPtr->length; i++) { - vPtr->valueArr[i] = -(vPtr->valueArr[i]); - } - break; - - case NOT: - for(i = 0; i < vPtr->length; i++) { - vPtr->valueArr[i] = (double)(!vPtr->valueArr[i]); - } - break; - default: - Tcl_AppendResult(interp, "unknown operator", (char *)NULL); - goto error; - } - } else if (piPtr->token != VALUE) { - Tcl_AppendResult(interp, "missing operand", (char *)NULL); - goto error; + break; + + case LESS: + for(i = 0; i < vPtr->length; i++) { + opnd[i] = (double)(opnd[i] < scalar); } - } - if (!gotOp) { - result = NextToken(interp, piPtr, &value2); - if (result != TCL_OK) { - goto done; + break; + + case GREATER: + for(i = 0; i < vPtr->length; i++) { + opnd[i] = (double)(opnd[i] > scalar); } - } - /* - * Got the first operand. Now fetch (operator, operand) pairs. - */ - for (;;) { - operator = piPtr->token; - - value2.pv.next = value2.pv.buffer; - if ((operator < MULT) || (operator >= UNARY_MINUS)) { - if ((operator == END) || (operator == CLOSE_PAREN) || - (operator == COMMA)) { - result = TCL_OK; - goto done; - } else { - Tcl_AppendResult(interp, "bad operator", (char *)NULL); - goto error; - } + break; + + case LEQ: + for(i = 0; i < vPtr->length; i++) { + opnd[i] = (double)(opnd[i] <= scalar); } - if (precTable[operator] <= prec) { - result = TCL_OK; - goto done; + break; + + case GEQ: + for(i = 0; i < vPtr->length; i++) { + opnd[i] = (double)(opnd[i] >= scalar); } - result = NextValue(interp, piPtr, precTable[operator], &value2); - if (result != TCL_OK) { - goto done; + break; + + case EQUAL: + for(i = 0; i < vPtr->length; i++) { + opnd[i] = (double)(opnd[i] == scalar); } - if ((piPtr->token < MULT) && (piPtr->token != VALUE) && - (piPtr->token != END) && (piPtr->token != CLOSE_PAREN) && - (piPtr->token != COMMA)) { - Tcl_AppendResult(interp, "unexpected token in expression", - (char *)NULL); - goto error; + break; + + case NEQ: + for(i = 0; i < vPtr->length; i++) { + opnd[i] = (double)(opnd[i] != scalar); } - /* - * At this point we have two vectors and an operator. - */ - - if (v2Ptr->length == 1) { - double *opnd; - double scalar; - - /* - * 2nd operand is a scalar. - */ - scalar = v2Ptr->valueArr[0]; - opnd = vPtr->valueArr; - switch (operator) { - case MULT: - for(i = 0; i < vPtr->length; i++) { - opnd[i] *= scalar; - } - break; - - case DIVIDE: - if (scalar == 0.0) { - Tcl_AppendResult(interp, "divide by zero", (char *)NULL); - goto error; - } - for(i = 0; i < vPtr->length; i++) { - opnd[i] /= scalar; - } - break; - - case PLUS: - for(i = 0; i < vPtr->length; i++) { - opnd[i] += scalar; - } - break; - - case MINUS: - for(i = 0; i < vPtr->length; i++) { - opnd[i] -= scalar; - } - break; - - case EXPONENT: - for(i = 0; i < vPtr->length; i++) { - opnd[i] = pow(opnd[i], scalar); - } - break; - - case MOD: - for(i = 0; i < vPtr->length; i++) { - opnd[i] = Fmod(opnd[i], scalar); - } - break; - - case LESS: - for(i = 0; i < vPtr->length; i++) { - opnd[i] = (double)(opnd[i] < scalar); - } - break; - - case GREATER: - for(i = 0; i < vPtr->length; i++) { - opnd[i] = (double)(opnd[i] > scalar); - } - break; - - case LEQ: - for(i = 0; i < vPtr->length; i++) { - opnd[i] = (double)(opnd[i] <= scalar); - } - break; - - case GEQ: - for(i = 0; i < vPtr->length; i++) { - opnd[i] = (double)(opnd[i] >= scalar); - } - break; - - case EQUAL: - for(i = 0; i < vPtr->length; i++) { - opnd[i] = (double)(opnd[i] == scalar); - } - break; - - case NEQ: - for(i = 0; i < vPtr->length; i++) { - opnd[i] = (double)(opnd[i] != scalar); - } - break; - - case AND: - for(i = 0; i < vPtr->length; i++) { - opnd[i] = (double)(opnd[i] && scalar); - } - break; - - case OR: - for(i = 0; i < vPtr->length; i++) { - opnd[i] = (double)(opnd[i] || scalar); - } - break; - - case LEFT_SHIFT: - { - int offset; - - offset = (int)scalar % vPtr->length; - if (offset > 0) { - double *hold; - int j; - - hold = malloc(sizeof(double) * offset); - for (i = 0; i < offset; i++) { - hold[i] = opnd[i]; - } - for (i = offset, j = 0; i < vPtr->length; i++, j++) { - opnd[j] = opnd[i]; - } - for (i = 0, j = vPtr->length - offset; - j < vPtr->length; i++, j++) { - opnd[j] = hold[i]; - } - free(hold); - } - } - break; - - case RIGHT_SHIFT: - { - int offset; - - offset = (int)scalar % vPtr->length; - if (offset > 0) { - double *hold; - int j; - - hold = malloc(sizeof(double) * offset); - for (i = vPtr->length - offset, j = 0; - i < vPtr->length; i++, j++) { - hold[j] = opnd[i]; - } - for (i = vPtr->length - offset - 1, - j = vPtr->length - 1; i >= 0; i--, j--) { - opnd[j] = opnd[i]; - } - for (i = 0; i < offset; i++) { - opnd[i] = hold[i]; - } - free(hold); - } - } - break; - - default: - Tcl_AppendResult(interp, "unknown operator in expression", - (char *)NULL); - goto error; + break; + + case AND: + for(i = 0; i < vPtr->length; i++) { + opnd[i] = (double)(opnd[i] && scalar); + } + break; + + case OR: + for(i = 0; i < vPtr->length; i++) { + opnd[i] = (double)(opnd[i] || scalar); + } + break; + + case LEFT_SHIFT: + { + int offset; + + offset = (int)scalar % vPtr->length; + if (offset > 0) { + double *hold; + int j; + + hold = (double*)malloc(sizeof(double) * offset); + for (i = 0; i < offset; i++) { + hold[i] = opnd[i]; } + for (i = offset, j = 0; i < vPtr->length; i++, j++) { + opnd[j] = opnd[i]; + } + for (i = 0, j = vPtr->length - offset; + j < vPtr->length; i++, j++) { + opnd[j] = hold[i]; + } + free(hold); + } + } + break; + + case RIGHT_SHIFT: + { + int offset; - } else if (vPtr->length == 1) { - double *opnd; - double scalar; - - /* - * 1st operand is a scalar. - */ - scalar = vPtr->valueArr[0]; - Blt_Vec_Duplicate(vPtr, v2Ptr); - opnd = vPtr->valueArr; - switch (operator) { - case MULT: - for(i = 0; i < vPtr->length; i++) { - opnd[i] *= scalar; - } - break; - - case PLUS: - for(i = 0; i < vPtr->length; i++) { - opnd[i] += scalar; - } - break; - - case DIVIDE: - for(i = 0; i < vPtr->length; i++) { - if (opnd[i] == 0.0) { - Tcl_AppendResult(interp, "divide by zero", - (char *)NULL); - goto error; - } - opnd[i] = (scalar / opnd[i]); - } - break; - - case MINUS: - for(i = 0; i < vPtr->length; i++) { - opnd[i] = scalar - opnd[i]; - } - break; - - case EXPONENT: - for(i = 0; i < vPtr->length; i++) { - opnd[i] = pow(scalar, opnd[i]); - } - break; - - case MOD: - for(i = 0; i < vPtr->length; i++) { - opnd[i] = Fmod(scalar, opnd[i]); - } - break; - - case LESS: - for(i = 0; i < vPtr->length; i++) { - opnd[i] = (double)(scalar < opnd[i]); - } - break; - - case GREATER: - for(i = 0; i < vPtr->length; i++) { - opnd[i] = (double)(scalar > opnd[i]); - } - break; - - case LEQ: - for(i = 0; i < vPtr->length; i++) { - opnd[i] = (double)(scalar >= opnd[i]); - } - break; - - case GEQ: - for(i = 0; i < vPtr->length; i++) { - opnd[i] = (double)(scalar <= opnd[i]); - } - break; - - case EQUAL: - for(i = 0; i < vPtr->length; i++) { - opnd[i] = (double)(opnd[i] == scalar); - } - break; - - case NEQ: - for(i = 0; i < vPtr->length; i++) { - opnd[i] = (double)(opnd[i] != scalar); - } - break; - - case AND: - for(i = 0; i < vPtr->length; i++) { - opnd[i] = (double)(opnd[i] && scalar); - } - break; - - case OR: - for(i = 0; i < vPtr->length; i++) { - opnd[i] = (double)(opnd[i] || scalar); - } - break; - - case LEFT_SHIFT: - case RIGHT_SHIFT: - Tcl_AppendResult(interp, "second shift operand must be scalar", - (char *)NULL); - goto error; - - default: - Tcl_AppendResult(interp, "unknown operator in expression", - (char *)NULL); - goto error; + offset = (int)scalar % vPtr->length; + if (offset > 0) { + double *hold; + int j; + + hold = (double*)malloc(sizeof(double) * offset); + for (i = vPtr->length - offset, j = 0; + i < vPtr->length; i++, j++) { + hold[j] = opnd[i]; } - } else { - double *opnd1, *opnd2; - /* - * Carry out the function of the specified operator. - */ - if (vPtr->length != v2Ptr->length) { - Tcl_AppendResult(interp, "vectors are different lengths", - (char *)NULL); - goto error; + for (i = vPtr->length - offset - 1, + j = vPtr->length - 1; i >= 0; i--, j--) { + opnd[j] = opnd[i]; } - opnd1 = vPtr->valueArr, opnd2 = v2Ptr->valueArr; - switch (operator) { - case MULT: - for (i = 0; i < vPtr->length; i++) { - opnd1[i] *= opnd2[i]; - } - break; - - case DIVIDE: - for (i = 0; i < vPtr->length; i++) { - if (opnd2[i] == 0.0) { - Tcl_AppendResult(interp, - "can't divide by 0.0 vector component", - (char *)NULL); - goto error; - } - opnd1[i] /= opnd2[i]; - } - break; - - case PLUS: - for (i = 0; i < vPtr->length; i++) { - opnd1[i] += opnd2[i]; - } - break; - - case MINUS: - for (i = 0; i < vPtr->length; i++) { - opnd1[i] -= opnd2[i]; - } - break; - - case MOD: - for (i = 0; i < vPtr->length; i++) { - opnd1[i] = Fmod(opnd1[i], opnd2[i]); - } - break; - - case EXPONENT: - for (i = 0; i < vPtr->length; i++) { - opnd1[i] = pow(opnd1[i], opnd2[i]); - } - break; - - case LESS: - for (i = 0; i < vPtr->length; i++) { - opnd1[i] = (double)(opnd1[i] < opnd2[i]); - } - break; - - case GREATER: - for (i = 0; i < vPtr->length; i++) { - opnd1[i] = (double)(opnd1[i] > opnd2[i]); - } - break; - - case LEQ: - for (i = 0; i < vPtr->length; i++) { - opnd1[i] = (double)(opnd1[i] <= opnd2[i]); - } - break; - - case GEQ: - for (i = 0; i < vPtr->length; i++) { - opnd1[i] = (double)(opnd1[i] >= opnd2[i]); - } - break; - - case EQUAL: - for (i = 0; i < vPtr->length; i++) { - opnd1[i] = (double)(opnd1[i] == opnd2[i]); - } - break; - - case NEQ: - for (i = 0; i < vPtr->length; i++) { - opnd1[i] = (double)(opnd1[i] != opnd2[i]); - } - break; - - case AND: - for (i = 0; i < vPtr->length; i++) { - opnd1[i] = (double)(opnd1[i] && opnd2[i]); - } - break; - - case OR: - for (i = 0; i < vPtr->length; i++) { - opnd1[i] = (double)(opnd1[i] || opnd2[i]); - } - break; - - case LEFT_SHIFT: - case RIGHT_SHIFT: - Tcl_AppendResult(interp, "second shift operand must be scalar", - (char *)NULL); - goto error; - - default: - Tcl_AppendResult(interp, "unknown operator in expression", - (char *)NULL); - goto error; + for (i = 0; i < offset; i++) { + opnd[i] = hold[i]; } + free(hold); + } } - } - done: - if (value2.pv.buffer != value2.staticSpace) { - free(value2.pv.buffer); - } - Blt_Vec_Free(v2Ptr); - return result; + break; + + default: + Tcl_AppendResult(interp, "unknown operator in expression", + (char *)NULL); + goto error; + } + + } else if (vPtr->length == 1) { + double *opnd; + double scalar; + + /* + * 1st operand is a scalar. + */ + scalar = vPtr->valueArr[0]; + Blt_Vec_Duplicate(vPtr, v2Ptr); + opnd = vPtr->valueArr; + switch (oper) { + case MULT: + for(i = 0; i < vPtr->length; i++) { + opnd[i] *= scalar; + } + break; + + case PLUS: + for(i = 0; i < vPtr->length; i++) { + opnd[i] += scalar; + } + break; + + case DIVIDE: + for(i = 0; i < vPtr->length; i++) { + if (opnd[i] == 0.0) { + Tcl_AppendResult(interp, "divide by zero", + (char *)NULL); + goto error; + } + opnd[i] = (scalar / opnd[i]); + } + break; + + case MINUS: + for(i = 0; i < vPtr->length; i++) { + opnd[i] = scalar - opnd[i]; + } + break; + + case EXPONENT: + for(i = 0; i < vPtr->length; i++) { + opnd[i] = pow(scalar, opnd[i]); + } + break; + + case MOD: + for(i = 0; i < vPtr->length; i++) { + opnd[i] = Fmod(scalar, opnd[i]); + } + break; + + case LESS: + for(i = 0; i < vPtr->length; i++) { + opnd[i] = (double)(scalar < opnd[i]); + } + break; + + case GREATER: + for(i = 0; i < vPtr->length; i++) { + opnd[i] = (double)(scalar > opnd[i]); + } + break; + + case LEQ: + for(i = 0; i < vPtr->length; i++) { + opnd[i] = (double)(scalar >= opnd[i]); + } + break; + + case GEQ: + for(i = 0; i < vPtr->length; i++) { + opnd[i] = (double)(scalar <= opnd[i]); + } + break; + + case EQUAL: + for(i = 0; i < vPtr->length; i++) { + opnd[i] = (double)(opnd[i] == scalar); + } + break; + + case NEQ: + for(i = 0; i < vPtr->length; i++) { + opnd[i] = (double)(opnd[i] != scalar); + } + break; + + case AND: + for(i = 0; i < vPtr->length; i++) { + opnd[i] = (double)(opnd[i] && scalar); + } + break; + + case OR: + for(i = 0; i < vPtr->length; i++) { + opnd[i] = (double)(opnd[i] || scalar); + } + break; + + case LEFT_SHIFT: + case RIGHT_SHIFT: + Tcl_AppendResult(interp, "second shift operand must be scalar", + (char *)NULL); + goto error; + + default: + Tcl_AppendResult(interp, "unknown operator in expression", + (char *)NULL); + goto error; + } + } else { + double *opnd1, *opnd2; + /* + * Carry out the function of the specified operator. + */ + if (vPtr->length != v2Ptr->length) { + Tcl_AppendResult(interp, "vectors are different lengths", + (char *)NULL); + goto error; + } + opnd1 = vPtr->valueArr, opnd2 = v2Ptr->valueArr; + switch (oper) { + case MULT: + for (i = 0; i < vPtr->length; i++) { + opnd1[i] *= opnd2[i]; + } + break; + + case DIVIDE: + for (i = 0; i < vPtr->length; i++) { + if (opnd2[i] == 0.0) { + Tcl_AppendResult(interp, + "can't divide by 0.0 vector component", + (char *)NULL); + goto error; + } + opnd1[i] /= opnd2[i]; + } + break; + + case PLUS: + for (i = 0; i < vPtr->length; i++) { + opnd1[i] += opnd2[i]; + } + break; + + case MINUS: + for (i = 0; i < vPtr->length; i++) { + opnd1[i] -= opnd2[i]; + } + break; + + case MOD: + for (i = 0; i < vPtr->length; i++) { + opnd1[i] = Fmod(opnd1[i], opnd2[i]); + } + break; + + case EXPONENT: + for (i = 0; i < vPtr->length; i++) { + opnd1[i] = pow(opnd1[i], opnd2[i]); + } + break; + + case LESS: + for (i = 0; i < vPtr->length; i++) { + opnd1[i] = (double)(opnd1[i] < opnd2[i]); + } + break; + + case GREATER: + for (i = 0; i < vPtr->length; i++) { + opnd1[i] = (double)(opnd1[i] > opnd2[i]); + } + break; + + case LEQ: + for (i = 0; i < vPtr->length; i++) { + opnd1[i] = (double)(opnd1[i] <= opnd2[i]); + } + break; + + case GEQ: + for (i = 0; i < vPtr->length; i++) { + opnd1[i] = (double)(opnd1[i] >= opnd2[i]); + } + break; + + case EQUAL: + for (i = 0; i < vPtr->length; i++) { + opnd1[i] = (double)(opnd1[i] == opnd2[i]); + } + break; + + case NEQ: + for (i = 0; i < vPtr->length; i++) { + opnd1[i] = (double)(opnd1[i] != opnd2[i]); + } + break; - error: - if (value2.pv.buffer != value2.staticSpace) { - free(value2.pv.buffer); + case AND: + for (i = 0; i < vPtr->length; i++) { + opnd1[i] = (double)(opnd1[i] && opnd2[i]); + } + break; + + case OR: + for (i = 0; i < vPtr->length; i++) { + opnd1[i] = (double)(opnd1[i] || opnd2[i]); + } + break; + + case LEFT_SHIFT: + case RIGHT_SHIFT: + Tcl_AppendResult(interp, "second shift operand must be scalar", + (char *)NULL); + goto error; + + default: + Tcl_AppendResult(interp, "unknown operator in expression", + (char *)NULL); + goto error; + } } - Blt_Vec_Free(v2Ptr); - return TCL_ERROR; + } + done: + if (value2.pv.buffer != value2.staticSpace) { + free(value2.pv.buffer); + } + Blt_Vec_Free(v2Ptr); + return result; + + error: + if (value2.pv.buffer != value2.staticSpace) { + free(value2.pv.buffer); + } + Blt_Vec_Free(v2Ptr); + return TCL_ERROR; } /* @@ -1603,45 +1603,45 @@ NextValue( */ static int EvaluateExpression( - Tcl_Interp* interp, /* Context in which to evaluate the - * expression. */ - char *string, /* Expression to evaluate. */ - Value *valuePtr) /* Where to store result. Should - * not be initialized by caller. */ + Tcl_Interp* interp, /* Context in which to evaluate the + * expression. */ + char *string, /* Expression to evaluate. */ + Value *valuePtr) /* Where to store result. Should + * not be initialized by caller. */ { - ParseInfo info; - int result; - Vector *vPtr; - double *vp, *vend; - - info.expr = info.nextPtr = string; - valuePtr->pv.buffer = valuePtr->pv.next = valuePtr->staticSpace; - valuePtr->pv.end = valuePtr->pv.buffer + STATIC_STRING_SPACE - 1; - valuePtr->pv.expandProc = Blt_ExpandParseValue; - valuePtr->pv.clientData = NULL; - - result = NextValue(interp, &info, -1, valuePtr); - if (result != TCL_OK) { - return result; - } - if (info.token != END) { - Tcl_AppendResult(interp, ": syntax error in expression \"", - string, "\"", (char *)NULL); - return TCL_ERROR; - } - vPtr = valuePtr->vPtr; - - /* Check for NaN's and overflows. */ - for (vp = vPtr->valueArr, vend = vp + vPtr->length; vp < vend; vp++) { - if (!isfinite(*vp)) { - /* - * IEEE floating-point error. - */ - MathError(interp, *vp); - return TCL_ERROR; - } + ParseInfo info; + int result; + Vector *vPtr; + double *vp, *vend; + + info.expr = info.nextPtr = string; + valuePtr->pv.buffer = valuePtr->pv.next = valuePtr->staticSpace; + valuePtr->pv.end = valuePtr->pv.buffer + STATIC_STRING_SPACE - 1; + valuePtr->pv.expandProc = Blt_ExpandParseValue; + valuePtr->pv.clientData = NULL; + + result = NextValue(interp, &info, -1, valuePtr); + if (result != TCL_OK) { + return result; + } + if (info.token != END) { + Tcl_AppendResult(interp, ": syntax error in expression \"", + string, "\"", (char *)NULL); + return TCL_ERROR; + } + vPtr = valuePtr->vPtr; + + /* Check for NaN's and overflows. */ + for (vp = vPtr->valueArr, vend = vp + vPtr->length; vp < vend; vp++) { + if (!isfinite(*vp)) { + /* + * IEEE floating-point error. + */ + MathError(interp, *vp); + return TCL_ERROR; } - return TCL_OK; + } + return TCL_OK; } /* @@ -1664,164 +1664,161 @@ EvaluateExpression( */ static int ComponentFunc( - ClientData clientData, /* Contains address of procedure that - * takes one double argument and - * returns a double result. */ - Tcl_Interp* interp, - Vector *vPtr) + ClientData clientData, /* Contains address of procedure that + * takes one double argument and + * returns a double result. */ + Tcl_Interp* interp, + Vector *vPtr) { - ComponentProc *procPtr = (ComponentProc *) clientData; - double *vp, *vend; + ComponentProc *procPtr = (ComponentProc *) clientData; + double *vp, *vend; - errno = 0; - for(vp = vPtr->valueArr + vPtr->first, - vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) { - *vp = (*procPtr) (*vp); - if (errno != 0) { - MathError(interp, *vp); - return TCL_ERROR; - } - if (!isfinite(*vp)) { - /* - * IEEE floating-point error. - */ - MathError(interp, *vp); - return TCL_ERROR; - } + errno = 0; + for(vp = vPtr->valueArr + vPtr->first, + vend = vPtr->valueArr + vPtr->last; vp <= vend; vp++) { + *vp = (*procPtr) (*vp); + if (errno != 0) { + MathError(interp, *vp); + return TCL_ERROR; } - return TCL_OK; + if (!isfinite(*vp)) { + /* + * IEEE floating-point error. + */ + MathError(interp, *vp); + return TCL_ERROR; + } + } + return TCL_OK; } static int ScalarFunc(ClientData clientData, Tcl_Interp* interp, Vector *vPtr) { - double value; - ScalarProc *procPtr = (ScalarProc *) clientData; + double value; + ScalarProc *procPtr = (ScalarProc *) clientData; - errno = 0; - value = (*procPtr) (vPtr); - if (errno != 0) { - MathError(interp, value); - return TCL_ERROR; - } - if (Blt_Vec_ChangeLength(interp, vPtr, 1) != TCL_OK) { - return TCL_ERROR; - } - vPtr->valueArr[0] = value; - return TCL_OK; + errno = 0; + value = (*procPtr) (vPtr); + if (errno != 0) { + MathError(interp, value); + return TCL_ERROR; + } + if (Blt_Vec_ChangeLength(interp, vPtr, 1) != TCL_OK) { + return TCL_ERROR; + } + vPtr->valueArr[0] = value; + return TCL_OK; } /*ARGSUSED*/ static int VectorFunc(ClientData clientData, Tcl_Interp* interp, Vector *vPtr) { - VectorProc *procPtr = (VectorProc *) clientData; + VectorProc *procPtr = (VectorProc *) clientData; - return (*procPtr) (vPtr); + return (*procPtr) (vPtr); } static MathFunction mathFunctions[] = -{ - {"abs", ComponentFunc, Fabs}, - {"acos", ComponentFunc, acos}, - {"asin", ComponentFunc, asin}, - {"atan", ComponentFunc, atan}, - {"adev", ScalarFunc, AvgDeviation}, - {"ceil", ComponentFunc, ceil}, - {"cos", ComponentFunc, cos}, - {"cosh", ComponentFunc, cosh}, - {"exp", ComponentFunc, exp}, - {"floor", ComponentFunc, floor}, - {"kurtosis",ScalarFunc, Kurtosis}, - {"length", ScalarFunc, Length}, - {"log", ComponentFunc, log}, - {"log10", ComponentFunc, log10}, - {"max", ScalarFunc, Blt_VecMax}, - {"mean", ScalarFunc, Mean}, - {"median", ScalarFunc, Median}, - {"min", ScalarFunc, Blt_VecMin}, - {"norm", VectorFunc, Norm}, - {"nz", ScalarFunc, Nonzeros}, - {"q1", ScalarFunc, Q1}, - {"q3", ScalarFunc, Q3}, - {"prod", ScalarFunc, Product}, - {"random", ComponentFunc, drand48}, - {"round", ComponentFunc, Round}, - {"sdev", ScalarFunc, StdDeviation}, - {"sin", ComponentFunc, sin}, - {"sinh", ComponentFunc, sinh}, - {"skew", ScalarFunc, Skew}, - {"sort", VectorFunc, Sort}, - {"sqrt", ComponentFunc, sqrt}, - {"sum", ScalarFunc, Sum}, - {"tan", ComponentFunc, tan}, - {"tanh", ComponentFunc, tanh}, - {"var", ScalarFunc, Variance}, + { + {"abs", (void*)ComponentFunc, (ClientData)Fabs}, + {"acos", (void*)ComponentFunc, (ClientData)acos}, + {"asin", (void*)ComponentFunc, (ClientData)asin}, + {"atan", (void*)ComponentFunc, (ClientData)atan}, + {"adev", (void*)ScalarFunc, (ClientData)AvgDeviation}, + {"ceil", (void*)ComponentFunc, (ClientData)ceil}, + {"cos", (void*)ComponentFunc, (ClientData)cos}, + {"cosh", (void*)ComponentFunc, (ClientData)cosh}, + {"exp", (void*)ComponentFunc, (ClientData)exp}, + {"floor", (void*)ComponentFunc, (ClientData)floor}, + {"kurtosis",(void*)ScalarFunc, (ClientData)Kurtosis}, + {"length", (void*)ScalarFunc, (ClientData)Length}, + {"log", (void*)ComponentFunc, (ClientData)log}, + {"log10", (void*)ComponentFunc, (ClientData)log10}, + {"max", (void*)ScalarFunc, (ClientData)Blt_VecMax}, + {"mean", (void*)ScalarFunc, (ClientData)Mean}, + {"median", (void*)ScalarFunc, (ClientData)Median}, + {"min", (void*)ScalarFunc, (ClientData)Blt_VecMin}, + {"norm", (void*)VectorFunc, (ClientData)Norm}, + {"nz", (void*)ScalarFunc, (ClientData)Nonzeros}, + {"q1", (void*)ScalarFunc, (ClientData)Q1}, + {"q3", (void*)ScalarFunc, (ClientData)Q3}, + {"prod", (void*)ScalarFunc, (ClientData)Product}, + {"random", (void*)ComponentFunc, (ClientData)drand48}, + {"round", (void*)ComponentFunc, (ClientData)Round}, + {"sdev", (void*)ScalarFunc, (ClientData)StdDeviation}, + {"sin", (void*)ComponentFunc, (ClientData)sin}, + {"sinh", (void*)ComponentFunc, (ClientData)sinh}, + {"skew", (void*)ScalarFunc, (ClientData)Skew}, + {"sort", (void*)VectorFunc, (ClientData)Sort}, + {"sqrt", (void*)ComponentFunc, (ClientData)sqrt}, + {"sum", (void*)ScalarFunc, (ClientData)Sum}, + {"tan", (void*)ComponentFunc, (ClientData)tan}, + {"tanh", (void*)ComponentFunc, (ClientData)tanh}, + {"var", (void*)ScalarFunc, (ClientData)Variance}, {(char *)NULL,}, -}; + }; void Blt_Vec_InstallMathFunctions(Tcl_HashTable *tablePtr) { - MathFunction *mathPtr; + MathFunction *mathPtr; - for (mathPtr = mathFunctions; mathPtr->name != NULL; mathPtr++) { - Tcl_HashEntry *hPtr; - int isNew; + for (mathPtr = mathFunctions; mathPtr->name != NULL; mathPtr++) { + Tcl_HashEntry *hPtr; + int isNew; - hPtr = Tcl_CreateHashEntry(tablePtr, mathPtr->name, &isNew); - Tcl_SetHashValue(hPtr, (ClientData)mathPtr); - } + hPtr = Tcl_CreateHashEntry(tablePtr, mathPtr->name, &isNew); + Tcl_SetHashValue(hPtr, (ClientData)mathPtr); + } } void Blt_Vec_UninstallMathFunctions(Tcl_HashTable *tablePtr) { - Tcl_HashEntry *hPtr; - Tcl_HashSearch cursor; - - for (hPtr = Tcl_FirstHashEntry(tablePtr, &cursor); hPtr != NULL; - hPtr = Tcl_NextHashEntry(&cursor)) { - MathFunction *mathPtr; - - mathPtr = Tcl_GetHashValue(hPtr); - if (mathPtr->name == NULL) { - free(mathPtr); - } - } + Tcl_HashEntry *hPtr; + Tcl_HashSearch cursor; + + for (hPtr = Tcl_FirstHashEntry(tablePtr, &cursor); hPtr != NULL; + hPtr = Tcl_NextHashEntry(&cursor)) { + MathFunction *mathPtr = (MathFunction*)Tcl_GetHashValue(hPtr); + if (mathPtr->name == NULL) + free(mathPtr); + } } static void InstallIndexProc( - Tcl_HashTable *tablePtr, - const char *string, - Blt_VectorIndexProc *procPtr) /* Pointer to function to be called - * when the vector finds the named index. - * If NULL, this indicates to remove - * the index from the table. - */ + Tcl_HashTable *tablePtr, + const char *string, + Blt_VectorIndexProc *procPtr) /* Pointer to function to be called + * when the vector finds the named index. + * If NULL, this indicates to remove + * the index from the table. + */ { - Tcl_HashEntry *hPtr; - int dummy; - - hPtr = Tcl_CreateHashEntry(tablePtr, string, &dummy); - if (procPtr == NULL) { - Tcl_DeleteHashEntry(hPtr); - } else { - Tcl_SetHashValue(hPtr, (ClientData)procPtr); - } + Tcl_HashEntry *hPtr; + int dummy; + + hPtr = Tcl_CreateHashEntry(tablePtr, string, &dummy); + if (procPtr == NULL) { + Tcl_DeleteHashEntry(hPtr); + } else { + Tcl_SetHashValue(hPtr, (ClientData)procPtr); + } } void Blt_Vec_InstallSpecialIndices(Tcl_HashTable *tablePtr) { - InstallIndexProc(tablePtr, "min", Blt_VecMin); - InstallIndexProc(tablePtr, "max", Blt_VecMax); - InstallIndexProc(tablePtr, "mean", Mean); - InstallIndexProc(tablePtr, "sum", Sum); - InstallIndexProc(tablePtr, "prod", Product); + InstallIndexProc(tablePtr, "min", Blt_VecMin); + InstallIndexProc(tablePtr, "max", Blt_VecMax); + InstallIndexProc(tablePtr, "mean", Mean); + InstallIndexProc(tablePtr, "sum", Sum); + InstallIndexProc(tablePtr, "prod", Product); } @@ -1847,36 +1844,36 @@ Blt_Vec_InstallSpecialIndices(Tcl_HashTable *tablePtr) */ int Blt_ExprVector( - Tcl_Interp* interp, /* Context in which to evaluate the - * expression. */ - char *string, /* Expression to evaluate. */ - Blt_Vector *vector) /* Where to store result. */ + Tcl_Interp* interp, /* Context in which to evaluate the + * expression. */ + char *string, /* Expression to evaluate. */ + Blt_Vector *vector) /* Where to store result. */ { - VectorInterpData *dataPtr; /* Interpreter-specific data. */ - Vector *vPtr = (Vector *)vector; - Value value; - - dataPtr = (vector != NULL) - ? vPtr->dataPtr : Blt_Vec_GetInterpData(interp); - value.vPtr = Blt_Vec_New(dataPtr); - if (EvaluateExpression(interp, string, &value) != TCL_OK) { - Blt_Vec_Free(value.vPtr); - return TCL_ERROR; - } - if (vPtr != NULL) { - Blt_Vec_Duplicate(vPtr, value.vPtr); - } else { - Tcl_Obj *listObjPtr; - double *vp, *vend; - - /* No result vector. Put values in interp->result. */ - listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); - for (vp = value.vPtr->valueArr, vend = vp + value.vPtr->length; - vp < vend; vp++) { - Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(*vp)); - } - Tcl_SetObjResult(interp, listObjPtr); - } + VectorInterpData *dataPtr; /* Interpreter-specific data. */ + Vector *vPtr = (Vector *)vector; + Value value; + + dataPtr = (vector != NULL) + ? vPtr->dataPtr : Blt_Vec_GetInterpData(interp); + value.vPtr = Blt_Vec_New(dataPtr); + if (EvaluateExpression(interp, string, &value) != TCL_OK) { Blt_Vec_Free(value.vPtr); - return TCL_OK; + return TCL_ERROR; + } + if (vPtr != NULL) { + Blt_Vec_Duplicate(vPtr, value.vPtr); + } else { + Tcl_Obj *listObjPtr; + double *vp, *vend; + + /* No result vector. Put values in interp->result. */ + listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); + for (vp = value.vPtr->valueArr, vend = vp + value.vPtr->length; + vp < vend; vp++) { + Tcl_ListObjAppendElement(interp, listObjPtr, Tcl_NewDoubleObj(*vp)); + } + Tcl_SetObjResult(interp, listObjPtr); + } + Blt_Vec_Free(value.vPtr); + return TCL_OK; } |