Changeset 12287
- Timestamp:
- Mar 6, 2007, 4:42:22 PM (19 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/types/psLookupTable.c (modified) (31 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/types/psLookupTable.c
r11710 r12287 7 7 * @author Ross Harman, MHPCC 8 8 * 9 * @version $Revision: 1.4 8$ $Name: not supported by cvs2svn $10 * @date $Date: 2007-0 2-08 21:57:02 $9 * @version $Revision: 1.49 $ $Name: not supported by cvs2svn $ 10 * @date $Date: 2007-03-07 02:42:22 $ 11 11 * 12 12 * Copyright 2004-2005 Maui High Performance Computing Center, Univ. of Hawaii … … 27 27 #include <inttypes.h> 28 28 29 #include "psAbort.h" 29 30 #include "psMemory.h" 30 31 #include "psString.h" … … 67 68 static char *cleanString(char *inString, int sLen); 68 69 static char* getToken(char **inString, char *delimiter, psParseErrorType *status); 69 static psS32 parseS32(char *inString, psParseErrorType *status);70 static psS64 parseS64(char *inString, psParseErrorType *status);71 static psF32 parseF32(char *inString, psParseErrorType *status);72 static psF64 parseF64(char *inString, psParseErrorType *status);73 70 static void parseValue(psVector *vec, psU64 index, char* strValue, psParseErrorType *status); 74 71 static void lookupTableFree(psLookupTable* table); … … 78 75 static bool ignoreLine(char *inString) 79 76 { 80 while (*inString!='\0' && *inString!='#') {81 if (!isspace(*inString)) {77 while (*inString!='\0' && *inString!='#') { 78 if (!isspace(*inString)) { 82 79 return false; 83 80 } … … 106 103 // Skip over trailing whitespace, null terminators, and # characters 107 104 ptrE = inString + sLen; 108 while (isspace(*ptrE) || *ptrE=='\0' || *ptrE=='#') {105 while (isspace(*ptrE) || *ptrE=='\0' || *ptrE=='#') { 109 106 ptrE--; 110 107 } … … 131 128 132 129 // Skip over leading whitespace 133 while (isspace(**inString)) {130 while (isspace(**inString)) { 134 131 (*inString)++; 135 132 } … … 137 134 // Length of token, not including delimiter 138 135 sLen = strcspn(*inString, delimiter); 139 if (sLen) {136 if (sLen) { 140 137 141 138 // Create new, cleaned, and null terminated token … … 145 142 (*inString) += sLen; 146 143 } 147 /* else if (**inString!='\0' && sLen==0) {144 /* else if (**inString!='\0' && sLen==0) { 148 145 *status = PS_PARSE_ERROR_GENERAL; 149 146 } … … 152 149 } 153 150 154 /* Returns single parsed value as a psS32. The input string must be cleaned and 155 null terminated. */ 156 static psS32 parseS32(char *inString, 157 psParseErrorType *status) 158 { 159 char *end = NULL; 160 psS32 value = 0.0; 161 162 163 value = (psS32)strtol(inString, &end, 0); 164 if(*end != '\0' && !isspace(*end)) { 165 *status = PS_PARSE_ERROR_VALUE; 166 } 167 /* else if(inString==end) { 168 *status = PS_PARSE_ERROR_VALUE; 169 } 170 */ 171 return value; 172 } 173 174 /* Returns single parsed value as a psS64. The input string must be cleaned and 175 null terminated. */ 176 static psS64 parseS64(char *inString, 177 psParseErrorType *status) 178 { 179 char *end = NULL; 180 psS64 value = 0.0; 181 182 value = (psS64)strtoll(inString, &end, 0); 183 if(*end != '\0' && !isspace(*end)) { 184 *status = PS_PARSE_ERROR_VALUE; 185 } 186 /* else if(inString==end) { 187 *status = PS_PARSE_ERROR_VALUE; 188 } 189 */ 190 return value; 191 } 192 193 /* Returns single parsed value as a psF32. The input string must be cleaned and 194 null terminated. */ 195 static psF32 parseF32(char *inString, 196 psParseErrorType *status) 197 { 198 char *end = NULL; 199 psF32 value = 0.0; 200 201 value = (psF32)strtof(inString, &end); 202 if(*end != '\0' && !isspace(*end)) { 203 *status = PS_PARSE_ERROR_VALUE; 204 } 205 /* else if(inString==end) { 206 *status = PS_PARSE_ERROR_VALUE; 207 } 208 */ 209 return value; 210 } 211 212 /* Returns single parsed value as a psF64. The input string must be cleaned and 213 null terminated. */ 214 static psF64 parseF64(char *inString, 215 psParseErrorType *status) 216 { 217 char *end = NULL; 218 psF64 value = 0.0; 219 220 value = (psF64)strtod(inString, &end); 221 if(*end != '\0' && !isspace(*end)) { 222 *status = PS_PARSE_ERROR_VALUE; 223 } 224 /* else if(inString==end) { 225 *status = PS_PARSE_ERROR_VALUE; 226 } 227 */ 228 return value; 229 } 151 #define PARSE_VALUE_INT_CASE(TYPE, FUNC) \ 152 case PS_TYPE_##TYPE: { \ 153 char *end = NULL; \ 154 ps##TYPE value = FUNC(strValue, &end, 0); \ 155 if (*end != '\0' && !isspace(*end)) { \ 156 *status = PS_PARSE_ERROR_VALUE; \ 157 } \ 158 vec->data.TYPE[index] = value; \ 159 return; \ 160 } 161 162 #define PARSE_VALUE_FLOAT_CASE(TYPE, FUNC) \ 163 case PS_TYPE_##TYPE: { \ 164 char *end = NULL; \ 165 ps##TYPE value = FUNC(strValue, &end); \ 166 if (*end != '\0' && !isspace(*end)) { \ 167 *status = PS_PARSE_ERROR_VALUE; \ 168 } \ 169 vec->data.TYPE[index] = value; \ 170 return; \ 171 } 172 230 173 231 174 /* Returns single parsed value as a double precision number. The input string must be … … 236 179 psParseErrorType *status) 237 180 { 238 psElemType type; 239 240 241 /* if(vec == NULL) { 242 *status = 1; 243 return; 244 } 245 */ 246 type = vec->type.type; 247 248 switch(type) { 249 case PS_TYPE_S32: 250 vec->data.S32[index] = parseS32(strValue, status); 251 break; 252 case PS_TYPE_S64: 253 vec->data.S64[index] = parseS64(strValue, status); 254 break; 255 case PS_TYPE_F32: 256 vec->data.F32[index] = parseF32(strValue, status); 257 break; 258 case PS_TYPE_F64: 259 default: 260 vec->data.F64[index] = parseF64(strValue, status); 261 break; 262 // default: 263 // *status = PS_PARSE_ERROR_TYPE; 264 } 265 181 switch (vec->type.type) { 182 PARSE_VALUE_INT_CASE(S32, strtol); 183 PARSE_VALUE_INT_CASE(S64, strtoll); 184 PARSE_VALUE_FLOAT_CASE(F32, strtof); 185 PARSE_VALUE_FLOAT_CASE(F64, strtod); 186 default: 187 psError(PS_ERR_BAD_PARAMETER_TYPE, true, "Bad type for vector: %x.\n", vec->type.type); 188 *status = PS_PARSE_ERROR_TYPE; 189 } 266 190 return; 267 191 } … … 269 193 static void lookupTableFree(psLookupTable* table) 270 194 { 195 assert(table); 271 196 psFree(table->values); 272 psFree( (void *)table->filename);273 psFree( (void *)table->format);197 psFree(table->filename); 198 psFree(table->format); 274 199 } 275 200 … … 292 217 long indexCol) 293 218 { 294 // Can't read table if you don't know its name 295 PS_ASSERT_PTR_NON_NULL(filename,NULL); 296 297 // Can't read table if you don't know its format 298 PS_ASSERT_PTR_NON_NULL(format,NULL); 299 300 psLookupTable *outTable = NULL; 301 302 // Allocate lookup table 303 outTable = (psLookupTable*)p_psAlloc(file, lineno, func, sizeof(psLookupTable)); 219 PS_ASSERT_STRING_NON_EMPTY(filename,NULL); 220 PS_ASSERT_STRING_NON_EMPTY(format,NULL); 221 222 psLookupTable *outTable = p_psAlloc(file, lineno, func, sizeof(psLookupTable)); 304 223 305 224 // Set deallocator … … 324 243 } 325 244 326 #define UPDATE_VALID_TO_FROM(TABLE) \327 switch (TABLE->index->type.type) { \328 case PS_TYPE_U8: \329 *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.U8[0]; \330 *(double *)&TABLE->validTo = (psF64)TABLE->index->data.U8[TABLE->index->n-1]; \331 break; \332 case PS_TYPE_S8: \333 *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.S8[0]; \334 *(double *)&TABLE->validTo = (psF64)TABLE->index->data.S8[TABLE->index->n-1]; \335 break; \336 case PS_TYPE_U16: \337 *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.U16[0]; \338 *(double *)&TABLE->validTo = (psF64)TABLE->index->data.U16[TABLE->index->n-1]; \339 break; \340 case PS_TYPE_S16: \341 *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.S16[0]; \342 *(double *)&TABLE->validTo = (psF64)TABLE->index->data.S16[TABLE->index->n-1]; \343 break; \344 case PS_TYPE_U32: \345 *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.U32[0]; \346 *(double *)&TABLE->validTo = (psF64)TABLE->index->data.U32[TABLE->index->n-1]; \347 break; \348 case PS_TYPE_S32: \349 *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.S32[0]; \350 *(double *)&TABLE->validTo = (psF64)TABLE->index->data.S32[TABLE->index->n-1]; \351 break; \352 case PS_TYPE_U64: \353 *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.U64[0]; \354 *(double *)&TABLE->validTo = (psF64)TABLE->index->data.U64[TABLE->index->n-1]; \355 break; \356 case PS_TYPE_S64: \357 *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.S64[0]; \358 *(double *)&TABLE->validTo = (psF64)TABLE->index->data.S64[TABLE->index->n-1]; \359 break; \360 case PS_TYPE_F32: \361 *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.F32[0]; \362 *(double *)&TABLE->validTo = (psF64)TABLE->index->data.F32[TABLE->index->n-1]; \363 break; \364 case PS_TYPE_F64: \365 *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.F64[0]; \366 *(double *)&TABLE->validTo = (psF64)TABLE->index->data.F64[TABLE->index->n-1]; \367 break; \368 default: \369 *(double *)&TABLE->validFrom = (psF64)0; \370 *(double *)&TABLE->validTo = (psF64)0; \371 break; \372 }373 374 #define COPY_VECTOR_VALUES(VEC_OUT,INDEX_OUT,VEC_IN,INDEX_IN) \375 switch(((psVector*)(VEC_IN))->type.type) { \376 case PS_TYPE_U8: \377 ((psVector*)VEC_OUT)->data.U8[INDEX_OUT] = ((psVector*)VEC_IN)->data.U8[INDEX_IN]; \378 break; \379 case PS_TYPE_U16: \380 ((psVector*)VEC_OUT)->data.U16[INDEX_OUT] = ((psVector*)VEC_IN)->data.U16[INDEX_IN]; \381 break; \382 case PS_TYPE_U32: \383 ((psVector*)VEC_OUT)->data.U32[INDEX_OUT] = ((psVector*)VEC_IN)->data.U32[INDEX_IN]; \384 break; \385 case PS_TYPE_U64: \386 ((psVector*)VEC_OUT)->data.U64[INDEX_OUT] = ((psVector*)VEC_IN)->data.U64[INDEX_IN]; \387 break; \388 case PS_TYPE_S8: \389 ((psVector*)VEC_OUT)->data.S8[INDEX_OUT] = ((psVector*)VEC_IN)->data.S8[INDEX_IN]; \390 break; \391 case PS_TYPE_S16: \392 ((psVector*)VEC_OUT)->data.S16[INDEX_OUT] = ((psVector*)VEC_IN)->data.S16[INDEX_IN]; \393 break; \394 case PS_TYPE_S32: \395 ((psVector*)VEC_OUT)->data.S32[INDEX_OUT] = ((psVector*)VEC_IN)->data.S32[INDEX_IN]; \396 if(INDEX_OUT == 0) { \397 validFrom = ((psVector*)VEC_OUT)->data.S32[INDEX_OUT]; \398 } \399 if(INDEX_OUT == ((psVector*)VEC_OUT)->n-1 ) { \400 validTo = ((psVector*)VEC_OUT)->data.S32[INDEX_OUT]; \401 } \402 break; \403 case PS_TYPE_S64: \404 ((psVector*)VEC_OUT)->data.S64[INDEX_OUT] = ((psVector*)VEC_IN)->data.S64[INDEX_IN]; \405 if(INDEX_OUT == 0) { \406 validFrom = ((psVector*)VEC_OUT)->data.S64[INDEX_OUT]; \407 } \408 if(INDEX_OUT == ((psVector*)VEC_OUT)->n-1 ) { \409 validTo = ((psVector*)VEC_OUT)->data.S64[INDEX_OUT]; \410 } \411 break; \412 case PS_TYPE_F32: \413 ((psVector*)VEC_OUT)->data.F32[INDEX_OUT] = ((psVector*)VEC_IN)->data.F32[INDEX_IN]; \414 if(INDEX_OUT == 0) { \415 validFrom = ((psVector*)VEC_OUT)->data.F32[INDEX_OUT]; \416 } \417 if(INDEX_OUT == ((psVector*)VEC_OUT)->n-1 ) { \418 validTo = ((psVector*)VEC_OUT)->data.F32[INDEX_OUT]; \419 } \420 break; \421 case PS_TYPE_F64: \422 ((psVector*)VEC_OUT)->data.F64[INDEX_OUT] = ((psVector*)VEC_IN)->data.F64[INDEX_IN]; \423 if(INDEX_OUT == 0) { \424 validFrom = ((psVector*)VEC_OUT)->data.F64[INDEX_OUT]; \425 } \426 if(INDEX_OUT == ((psVector*)VEC_OUT)->n-1 ) { \427 validTo = ((psVector*)VEC_OUT)->data.F64[INDEX_OUT]; \428 } \429 break; \430 default: \431 break; \432 }433 434 245 psArray *psVectorsReadFromFile(const char *filename, 435 246 const char *format) 436 247 { 248 PS_ASSERT_STRING_NON_EMPTY(filename, NULL); 249 PS_ASSERT_STRING_NON_EMPTY(format, NULL); 250 437 251 psArray* outputArray = NULL; 438 252 psVector* colVector = NULL; … … 447 261 psParseErrorType parseStatus = PS_PARSE_SUCCESS; 448 262 449 // Check for nul file name450 PS_ASSERT_PTR_NON_NULL(filename,NULL);451 452 // Parse format string for valid string453 PS_ASSERT_PTR_NON_NULL(format,NULL);454 455 263 // Create temp pointer which can then be used several times 456 264 tempFormat = format; … … 461 269 // Parse the format string to determine how many vectors 462 270 // and whether the format string is valid 463 while ((strValue=getToken((char**)&tempFormat," \t",&parseStatus))) {271 while ((strValue = getToken((char**)&tempFormat, " \t", &parseStatus))) { 464 272 465 273 // Check for %d format sub string 466 if (strcmp(strValue,"\%d") == 0 ) {274 if (strcmp(strValue,"\%d") == 0 ) { 467 275 numCols++; 468 276 colVector = psVectorAlloc(1,PS_TYPE_S32); … … 498 306 // If the format string was parsed successfully and return numCols the 499 307 // prepare to open file and read values 500 if (numCols > 0) {308 if (numCols > 0) { 501 309 502 310 // Open specified file 503 if ((fp=fopen(filename, "r")) == NULL) {311 if ((fp=fopen(filename, "r")) == NULL) { 504 312 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed to open file %s."), 505 313 filename); … … 514 322 515 323 // Loop through file to get numRows, numCols, and column data types 516 while ((fgets(line, MAX_STRING_LENGTH, fp) != NULL) &&324 while ((fgets(line, MAX_STRING_LENGTH, fp) != NULL) && 517 325 (parseStatus == PS_PARSE_SUCCESS)) { 518 326 … … 521 329 522 330 // If line is not a comment or blank, then extract data 523 if (!ignoreLine(linePtr)) {331 if (!ignoreLine(linePtr)) { 524 332 numRows++; 525 333 … … 530 338 531 339 // Loop through format and line strings to get values in text table file 532 while ((strValue=getToken((char**)&tempFormat," \t",&parseStatus))340 while ((strValue=getToken((char**)&tempFormat," \t",&parseStatus)) 533 341 && (strNum=getToken((char**)&linePtr," \t",&parseStatus)) ) { 534 342 // Set column vector … … 536 344 537 345 // Set column entries based on format string defining the type 538 if (strcmp(strValue,"\%d") == 0 ) {346 if (strcmp(strValue,"\%d") == 0 ) { 539 347 colVector = psVectorRecycle(colVector, numRows, 540 348 colVector->type.type); … … 564 372 // If the file line was not parsed successful report 565 373 // error and return NULL 566 if (parseStatus != PS_PARSE_SUCCESS) {374 if (parseStatus != PS_PARSE_SUCCESS) { 567 375 psError(PS_ERR_UNKNOWN, true, 568 376 "Parsing text file failed."); … … 615 423 const char *func, 616 424 psLookupTable *table, 617 constpsArray *vectors,425 psArray *vectors, 618 426 long indexCol) 619 427 { 620 psLookupTable* outputTable = NULL; 621 bool sortNeeded = false; 622 psF64 validTo = 0; 623 psF64 validFrom = 0; 624 625 // Check for NULL input table 626 // XXX table/outputtable should be allocated if NULL 627 PS_ASSERT_PTR_NON_NULL(table,NULL); 628 629 // Check for NULL vectors 630 PS_ASSERT_PTR_NON_NULL(vectors,NULL); 631 632 // Check for invalid index column 633 if(indexCol < 0 ) { 634 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 635 "Index column cannot be less than zero"); 636 return NULL; 637 } 638 428 PS_ASSERT_LOOKUPTABLE_NON_NULL(table, NULL); 429 PS_ASSERT_ARRAY_NON_NULL(vectors, NULL); 639 430 if (indexCol >= vectors->n) { 640 431 psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Index column, %ld, is larger" … … 643 434 } 644 435 645 psVector* indexColumnVector = vectors->data[indexCol]; 646 psS32 numRows = indexColumnVector->n; 647 psS32 numCols = vectors->n; 436 psVector *indexVector = vectors->data[indexCol]; // The vector that provides the index 437 long numRows = indexVector->n; // Number of rows in table 438 long numCols = vectors->n; // Number of columns in table 439 440 #define CHECK_SORT_CASE(TYPE) \ 441 case PS_TYPE_##TYPE: \ 442 for (long i = 1; i < numRows; i++) { \ 443 if (indexVector->data.TYPE[i] < indexVector->data.TYPE[i - 1]) { \ 444 sortNeeded = true; \ 445 break; \ 446 } \ 447 } \ 448 break; 648 449 649 450 // Check if array is sorted on the index column 650 psVector* sortedIndex = psVectorAlloc(numRows,PS_TYPE_U32); 651 sortedIndex = psVectorSortIndex(sortedIndex,indexColumnVector); 652 for(psS32 i = 0; i < numRows; i++ ) { 653 if(sortedIndex->data.U32[i] != i) { 654 sortNeeded = true; 655 break; 656 } 657 } 658 659 // Check if it is necessary to sort value vectors 660 if(sortNeeded) { 661 // Allocate new array to contain sorted vectors 662 psArray* newValueArray = psArrayAlloc(numCols); 663 for(psS32 j = 0; j < numCols; j++) { 664 psS32 type = ((psVector*)(vectors->data[j]))->type.type; 665 newValueArray->data[j] = psVectorAlloc(numRows,type); 666 } 667 668 // Populate new array/vectors with sorted values 669 for(psS32 i = 0; i < numRows; i++) { 670 // Populate new index vector 671 psU32 sortIndex = sortedIndex->data.U32[i]; 672 // For every column populate new value vectors 673 for(psS32 j=0; j < numCols; j++) { 674 COPY_VECTOR_VALUES(newValueArray->data[j],i,vectors->data[j], sortIndex) 451 bool sortNeeded = false; // Do we need to sort? 452 switch (indexVector->type.type) { 453 CHECK_SORT_CASE(U8); 454 CHECK_SORT_CASE(U16); 455 CHECK_SORT_CASE(U32); 456 CHECK_SORT_CASE(U64); 457 CHECK_SORT_CASE(S8); 458 CHECK_SORT_CASE(S16); 459 CHECK_SORT_CASE(S32); 460 CHECK_SORT_CASE(S64); 461 CHECK_SORT_CASE(F32); 462 CHECK_SORT_CASE(F64); 463 default: 464 psAbort("Should never get here: bad type."); 465 } 466 467 if (sortNeeded) { 468 psVector *sortedIndex = psVectorSortIndex(NULL, indexVector); // Indices for sorting 469 psArray *newValues = psArrayAlloc(numCols); 470 for (long i = 0; i < numCols; i++) { 471 psVector *oldVector = vectors->data[i]; // Vector of interest 472 psVector *newVector = psVectorAlloc(numRows, oldVector->type.type); 473 newValues->data[i] = newVector; 474 475 #define REARRANGE_CASE(TYPE) \ 476 case PS_TYPE_##TYPE: \ 477 for (long j = 0; j < numRows; j++) { \ 478 newVector->data.TYPE[j] = oldVector->data.TYPE[sortedIndex->data.S32[j]]; \ 479 } \ 480 break; 481 482 switch (oldVector->type.type) { 483 REARRANGE_CASE(U8); 484 REARRANGE_CASE(U16); 485 REARRANGE_CASE(U32); 486 REARRANGE_CASE(U64); 487 REARRANGE_CASE(S8); 488 REARRANGE_CASE(S16); 489 REARRANGE_CASE(S32); 490 REARRANGE_CASE(S64); 491 REARRANGE_CASE(F32); 492 REARRANGE_CASE(F64); 493 default: 494 psAbort("Should never get here: bad type."); 675 495 } 676 496 } 677 // Assign new vector value to table 678 table->index = newValueArray->data[indexCol]; 679 // Assign new value vectors to table array 680 table->values = newValueArray; 681 // Assign indexCol 682 table->indexCol = indexCol; 683 // Assign validTo and validFrom values 684 UPDATE_VALID_TO_FROM(table) 685 686 // Set return value 687 outputTable = table; 688 497 498 psFree(sortedIndex); 499 table->values = newValues; 689 500 } else { 690 // Index vector is already sorted 691 // Assign array vector specified by indexCol to table index vector 692 // and increment memory ref 693 table->index = vectors->data[indexCol]; 694 table->values = (psArray*)vectors; 695 psMemIncrRefCounter((psArray*)vectors); 696 697 // Assign indexCol 698 table->indexCol = indexCol; 699 // Assign validTo and validFrom values 700 UPDATE_VALID_TO_FROM(table); 701 702 // Set return value 703 outputTable = table; 704 } 705 706 // Free sort vector 707 psFree(sortedIndex); 708 709 return outputTable; 501 table->values = psMemIncrRefCounter(vectors); 502 } 503 504 table->index = psMemIncrRefCounter(table->values->data[indexCol]); 505 table->indexCol = indexCol; 506 507 #define SET_VALID_CASE(TYPE) \ 508 case PS_TYPE_##TYPE: \ 509 *(double*)&table->validFrom = table->index->data.TYPE[0]; \ 510 *(double*)&table->validTo = table->index->data.TYPE[numRows - 1]; \ 511 break; 512 513 switch (table->index->type.type) { 514 SET_VALID_CASE(U8); 515 SET_VALID_CASE(U16); 516 SET_VALID_CASE(U32); 517 SET_VALID_CASE(U64); 518 SET_VALID_CASE(S8); 519 SET_VALID_CASE(S16); 520 SET_VALID_CASE(S32); 521 SET_VALID_CASE(S64); 522 SET_VALID_CASE(F32); 523 SET_VALID_CASE(F64); 524 default: 525 psAbort("Should never get here: bad type."); 526 } 527 528 return table; 710 529 } 711 530 712 531 long psLookupTableRead(psLookupTable* table) 713 532 { 533 PS_ASSERT_LOOKUPTABLE_NON_NULL(table, 0); 534 714 535 long numRows = 0; 715 536 psArray* vectors = NULL; 716 537 psLookupTable* outTable = NULL; 717 538 718 // Check if the input table is NULL then return 0719 PS_ASSERT_PTR_NON_NULL(table,0);720 721 539 // Read vectors from file specified in table 722 540 vectors = psVectorsReadFromFile(table->filename, table->format); 723 541 724 542 // Check for valid array after reading from file 725 if (vectors != NULL) {543 if (vectors != NULL) { 726 544 727 545 // Import vector into table … … 731 549 732 550 // Update the number of rows read if outTable is not NULL 733 if (outTable != NULL) {551 if (outTable != NULL) { 734 552 numRows = table->index->n; 735 553 } … … 780 598 switch (TABLE->index->type.type) { \ 781 599 case PS_TYPE_S32: \ 782 if ( (psS32)index < TABLE->index->data.S32[0] ) { \600 if ( (psS32)index < TABLE->index->data.S32[0] ) { \ 783 601 return NAN; \ 784 602 } \ 785 if ( (psS32)index > TABLE->index->data.S32[numRows-1] ) { \603 if ( (psS32)index > TABLE->index->data.S32[numRows-1] ) { \ 786 604 return NAN; \ 787 605 } \ 788 606 break; \ 789 607 case PS_TYPE_S64: \ 790 if ( (psS64)index < TABLE->index->data.S64[0] ) { \608 if ( (psS64)index < TABLE->index->data.S64[0] ) { \ 791 609 return NAN; \ 792 610 } \ 793 if ( (psS64)index > TABLE->index->data.S64[numRows-1] ) { \611 if ( (psS64)index > TABLE->index->data.S64[numRows-1] ) { \ 794 612 return NAN; \ 795 613 } \ 796 614 break; \ 797 615 case PS_TYPE_F32: \ 798 if ( (psF32)index < TABLE->index->data.F32[0] ) { \616 if ( (psF32)index < TABLE->index->data.F32[0] ) { \ 799 617 return NAN; \ 800 618 } \ 801 if ( (psF32)index > TABLE->index->data.F32[numRows-1] ) { \619 if ( (psF32)index > TABLE->index->data.F32[numRows-1] ) { \ 802 620 return NAN; \ 803 621 } \ 804 622 break; \ 805 623 case PS_TYPE_F64: \ 806 if ( index < TABLE->index->data.F64[0] ) { \624 if ( index < TABLE->index->data.F64[0] ) { \ 807 625 return NAN; \ 808 626 } \ 809 if ( index > TABLE->index->data.F64[numRows-1] ) { \627 if ( index > TABLE->index->data.F64[numRows-1] ) { \ 810 628 return NAN; \ 811 629 } \ … … 820 638 long column) 821 639 { 640 PS_ASSERT_LOOKUPTABLE_NON_NULL(table, NAN); 641 // Ensuring information exists 642 PS_ASSERT_VECTOR_NON_NULL(table->index, NAN); 643 PS_ASSERT_ARRAY_NON_NULL(table->values, NAN); 644 PS_ASSERT_INT_WITHIN_RANGE(column, 0, (int)table->values->n - 1, NAN); 645 PS_ASSERT_VECTOR_NON_NULL((psVector*)table->values->data[column], NAN); 646 822 647 psU64 hiIdx = 0; 823 648 psU64 loIdx = 0; … … 832 657 psArray *values = NULL; 833 658 834 // Check for NULL table835 PS_ASSERT_PTR_NON_NULL(table,NAN);836 837 659 indexVec = table->index; 838 660 values = table->values; 839 661 numRows = table->index->n; 840 662 numCols = table->values->n; 841 PS_ASSERT_PTR_NON_NULL(indexVec,NAN);842 PS_ASSERT_PTR_NON_NULL(values,NAN);843 PS_ASSERT_INT_UNEQUAL(numRows, 0,NAN);844 PS_ASSERT_INT_UNEQUAL(numCols, 0,NAN);845 PS_ASSERT_INT_WITHIN_RANGE(column, 0, (int)(numCols-1), NAN);846 847 663 valuesVec = (psVector*)values->data[column]; 848 PS_ASSERT_PTR_NON_NULL(indexVec,NAN);849 664 850 665 // Verify the index is within the bounds of the table … … 853 668 // Find location in table where specified index is between to entries 854 669 CONVERT_VALUE_TO_F64(indexVec, 0, convertVal) 855 while (index > convertVal ) {670 while (index > convertVal ) { 856 671 hiIdx++; 857 672 /* XXX: following is unreachable. 858 if (hiIdx >= numRows) {673 if (hiIdx >= numRows) { 859 674 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 860 675 _("High index too big, %" PRIu64 "."), hiIdx); … … 867 682 // Check for negative low index and generate error 868 683 loIdx = hiIdx--; 869 if (loIdx < 0) {684 if (loIdx < 0) { 870 685 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 871 686 _("Low index too small, %" PRIu64 "."), loIdx); … … 877 692 CONVERT_VALUE_TO_F64(indexVec, loIdx, convertVal); 878 693 denom -= convertVal; 879 if (fabs(denom) < FLT_EPSILON) {694 if (fabs(denom) < FLT_EPSILON) { 880 695 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 881 696 _("Divide by zero error during interpolation.")); … … 897 712 double index) 898 713 { 899 long numCols = 0; 900 psVector *outVector = NULL; 901 902 // Error checks 903 PS_ASSERT_PTR_NON_NULL(table,NULL); 904 PS_ASSERT_PTR_NON_NULL(table->values,NULL); 905 numCols = table->values->n; 906 PS_ASSERT_INT_UNEQUAL(numCols, 0,NULL); 907 908 // Create output vector 909 outVector = psVectorAlloc(numCols, PS_TYPE_F64); 714 PS_ASSERT_LOOKUPTABLE_NON_NULL(table, NULL); 715 // Ensuring information exists 716 PS_ASSERT_VECTOR_NON_NULL(table->index, NULL); 717 PS_ASSERT_ARRAY_NON_NULL(table->values, NULL); 718 719 long numCols = table->values->n; 720 psVector *outVector = psVectorAlloc(numCols, PS_TYPE_F64); 910 721 911 722 // Fill vectors with results and status of results 912 for(psU64 i=0; i<numCols; i++) { 723 // XXX: This algorithm must be changed to something more efficient! 724 for (long i = 0; i < numCols; i++) { 913 725 outVector->data.F64[i] = psLookupTableInterpolate(table, index, i); 914 if (isnan(outVector->data.F64[i])) {726 if (isnan(outVector->data.F64[i])) { 915 727 // Free allocated vector 916 728 psFree(outVector);
Note:
See TracChangeset
for help on using the changeset viewer.
