Changeset 15711
- Timestamp:
- Nov 28, 2007, 4:56:01 PM (18 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/mathtypes/psVector.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/mathtypes/psVector.c
r15406 r15711 10 10 * @author Joshua Hoblitt, University of Hawaii 11 11 * 12 * @version $Revision: 1. 99$ $Name: not supported by cvs2svn $13 * @date $Date: 2007-1 0-29 20:35:31 $12 * @version $Revision: 1.100 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2007-11-29 02:56:01 $ 14 14 * 15 15 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 344 344 // XXX since the key size is fixed (same number of bits) a Radix sort could be 345 345 // a big win here -- someone should benchmark this -JH 346 #define PSVECTOR_SORT_CASE(NAME) \ 347 case PS_TYPE_##NAME: { \ 348 ps##NAME temp; \ 349 ps##NAME *value = vector->data.NAME; \ 350 for (;;) { \ 351 if (l > 0) { \ 352 temp = value[--l]; \ 346 347 // The following sort code is based on gsl_heapsort from GSL-1.8 (www.gnu.org/software/gsl), file 348 // gsl-1.8/sort/sort.c, which is distributed under the GNU General Public License, version 2. 349 // 350 // Implement Heap sort -- direct and indirect sorting 351 // Based on descriptions in Sedgewick "Algorithms in C" 352 // 353 // Copyright (C) 1999 Thomas Walter 354 // 355 // 18 February 2000: Modified for GSL by Brian Gough 356 357 // Comparison and swap functions for sorting values directly 358 #define PSVECTOR_SORT_COMPARE_DIRECT(A,B) (value[A] < value[B]) 359 #define PSVECTOR_SORT_SWAP_DIRECT(TYPE,A,B) { \ 360 if (A != B) { \ 361 ps##TYPE temp = value[A]; \ 362 value[A] = value[B]; \ 363 value[B] = temp; \ 364 } \ 365 } 366 367 // Comparison and swap functions for sorting vector indices 368 #define PSVECTOR_SORT_COMPARE_INDEX(A,B) (value[index[A]] < value[index[B]]) 369 #define PSVECTOR_SORT_SWAP_INDEX(TYPE,A,B) { \ 370 if (A != B) { \ 371 ps##TYPE temp = index[A]; \ 372 index[A] = index[B]; \ 373 index[B] = temp; \ 374 } \ 375 } 376 377 // Sort the heap 378 #define PSVECTOR_SORT_DOWNHEAP(SWAPTYPE, COMPAREFUNC, SWAPFUNC, K) { \ 379 unsigned long k = K; /* Local version of k --- so the higher-level version isn't modified */ \ 380 while (k <= N / 2) { \ 381 unsigned long j = 2 * k; \ 382 if (j < N && COMPAREFUNC(j, j + 1)) { \ 383 j++; \ 384 } \ 385 if (COMPAREFUNC(k, j)) { \ 386 SWAPFUNC(SWAPTYPE, j, k); \ 353 387 } else { \ 354 temp = value[ir]; \ 355 value[ir] = value[0]; \ 356 if (--ir == 0) { \ 357 value[0] = temp; \ 358 return true; \ 359 } \ 388 break; \ 360 389 } \ 361 int i = l; \ 362 int j = (l << 1) + 1; \ 363 while (j <= ir) { \ 364 if (j < ir && value[j] < value[j+1]) \ 365 ++j; \ 366 if (temp < value[j]) { \ 367 value[i]=value[j]; \ 368 j += (i=j) + 1; \ 369 } else { \ 370 j = ir + 1; \ 371 } \ 372 } \ 373 value[i] = temp; \ 390 k = j; \ 374 391 } \ 375 } \ 376 break; 392 } 393 394 // Driver for heap sort 395 #define PSVECTOR_SORT_CASE(ELEMTYPE, SWAPTYPE, COMPAREFUNC, SWAPFUNC) \ 396 case PS_TYPE_##ELEMTYPE: { \ 397 ps##ELEMTYPE *value = vector->data.ELEMTYPE; \ 398 unsigned long N = vector->n - 1; /* Index of last element */ \ 399 unsigned long i = N / 2 + 1; /* Adding one to compensate for i-- below */ \ 400 do { \ 401 i--; \ 402 PSVECTOR_SORT_DOWNHEAP(SWAPTYPE, COMPAREFUNC, SWAPFUNC, i); \ 403 } while (i > 0); \ 404 while (N > 0) { \ 405 SWAPFUNC(SWAPTYPE, 0, N); /* Swap elements */ \ 406 /* Process the heap */ \ 407 N--; \ 408 PSVECTOR_SORT_DOWNHEAP(SWAPTYPE, COMPAREFUNC, SWAPFUNC, 0); \ 409 } \ 410 break; \ 411 } 412 // END of heap sort code from GSL 377 413 378 414 bool psVectorSortInPlace(const psVector *vector) … … 380 416 PS_ASSERT_VECTOR_NON_NULL(vector, false); 381 417 382 long N = vector->n; // Number of elements383 if (N < 2) {418 if (vector->n < 2) { 419 // Already sorted! 384 420 return true; 385 421 } 386 long l = N >> 1; 387 long ir = N - 1; 422 388 423 switch (vector->type.type) { 389 PSVECTOR_SORT_CASE(U8 );390 PSVECTOR_SORT_CASE(U16 );391 PSVECTOR_SORT_CASE(U32 );392 PSVECTOR_SORT_CASE(U64 );393 PSVECTOR_SORT_CASE(S8 );394 PSVECTOR_SORT_CASE(S16 );395 PSVECTOR_SORT_CASE(S32 );396 PSVECTOR_SORT_CASE(S64 );397 PSVECTOR_SORT_CASE(F32 );398 PSVECTOR_SORT_CASE(F64 );424 PSVECTOR_SORT_CASE(U8 , U8 , PSVECTOR_SORT_COMPARE_DIRECT, PSVECTOR_SORT_SWAP_DIRECT); 425 PSVECTOR_SORT_CASE(U16, U16, PSVECTOR_SORT_COMPARE_DIRECT, PSVECTOR_SORT_SWAP_DIRECT); 426 PSVECTOR_SORT_CASE(U32, U32, PSVECTOR_SORT_COMPARE_DIRECT, PSVECTOR_SORT_SWAP_DIRECT); 427 PSVECTOR_SORT_CASE(U64, U64, PSVECTOR_SORT_COMPARE_DIRECT, PSVECTOR_SORT_SWAP_DIRECT); 428 PSVECTOR_SORT_CASE(S8 , S8 , PSVECTOR_SORT_COMPARE_DIRECT, PSVECTOR_SORT_SWAP_DIRECT); 429 PSVECTOR_SORT_CASE(S16, S16, PSVECTOR_SORT_COMPARE_DIRECT, PSVECTOR_SORT_SWAP_DIRECT); 430 PSVECTOR_SORT_CASE(S32, S32, PSVECTOR_SORT_COMPARE_DIRECT, PSVECTOR_SORT_SWAP_DIRECT); 431 PSVECTOR_SORT_CASE(S64, S64, PSVECTOR_SORT_COMPARE_DIRECT, PSVECTOR_SORT_SWAP_DIRECT); 432 PSVECTOR_SORT_CASE(F32, F32, PSVECTOR_SORT_COMPARE_DIRECT, PSVECTOR_SORT_SWAP_DIRECT); 433 PSVECTOR_SORT_CASE(F64, F64, PSVECTOR_SORT_COMPARE_DIRECT, PSVECTOR_SORT_SWAP_DIRECT); 399 434 default: 400 435 psError(PS_ERR_BAD_PARAMETER_TYPE, true, … … 436 471 } 437 472 438 // Heap sort of the index array 439 #define PSVECTOR_SORT_INDEX_CASE(NAME) \ 440 case PS_TYPE_##NAME: { \ 441 psS32 temp; \ 442 psS32 *index = out->data.S32; \ 443 ps##NAME *value = inVector->data.NAME; \ 444 for (;;) { \ 445 if (l > 0) { \ 446 temp = index[--l]; \ 447 } else { \ 448 temp = index[ir]; \ 449 index[ir] = index[0]; \ 450 if (--ir == 0) { \ 451 index[0] = temp; \ 452 return out; \ 453 } \ 454 } \ 455 long i = l; \ 456 long j = (l << 1) + 1; \ 457 while (j <= ir) { \ 458 if (j < ir && value[index[j]] < value[index[j+1]]) \ 459 ++j; \ 460 if (value[temp ] < value[index[j]]) { \ 461 index[i]=index[j]; \ 462 j += (i=j) + 1; \ 463 } else { \ 464 j = ir + 1; \ 465 } \ 466 } \ 467 index[i] = temp; \ 468 } \ 469 } \ 470 break; 471 472 psVector* psVectorSortIndex(psVector* outVector, 473 const psVector* inVector) 474 { 475 if (inVector == NULL) { 476 psError(PS_ERR_BAD_PARAMETER_NULL, true, 477 _("psVectorSort can not sort a NULL psVector.")); 478 psFree(outVector); 479 return NULL; 480 } 481 482 // XXX isn't this line a waste of space? 483 psVector *out = psVectorRecycle(outVector, inVector->n, PS_TYPE_S32); // Vector for output 484 out = psVectorCreate(out, 0, inVector->n, 1, PS_TYPE_S32); 485 long N = out->n; // Number of elements 486 if (N < 2) { 487 return out; 488 } 489 long l = N >> 1; 490 long ir = N - 1; 491 switch (inVector->type.type) { 492 PSVECTOR_SORT_INDEX_CASE(U8); 493 PSVECTOR_SORT_INDEX_CASE(U16); 494 PSVECTOR_SORT_INDEX_CASE(U32); 495 PSVECTOR_SORT_INDEX_CASE(U64); 496 PSVECTOR_SORT_INDEX_CASE(S8); 497 PSVECTOR_SORT_INDEX_CASE(S16); 498 PSVECTOR_SORT_INDEX_CASE(S32); 499 PSVECTOR_SORT_INDEX_CASE(S64); 500 PSVECTOR_SORT_INDEX_CASE(F32); 501 PSVECTOR_SORT_INDEX_CASE(F64); 473 psVector* psVectorSortIndex(psVector *out, 474 const psVector *vector) 475 { 476 PS_ASSERT_VECTOR_NON_NULL(vector, NULL); 477 478 psVector *indexVector = psVectorCreate(out, 0, vector->n, 1, PS_TYPE_S32); // Array of indices 479 psS32 *index = indexVector->data.S32; // Dereference for convenience 480 481 if (vector->n < 2) { 482 // Already sorted 483 return indexVector; 484 } 485 switch (vector->type.type) { 486 PSVECTOR_SORT_CASE(U8 , S32, PSVECTOR_SORT_COMPARE_INDEX, PSVECTOR_SORT_SWAP_INDEX); 487 PSVECTOR_SORT_CASE(U16, S32, PSVECTOR_SORT_COMPARE_INDEX, PSVECTOR_SORT_SWAP_INDEX); 488 PSVECTOR_SORT_CASE(U32, S32, PSVECTOR_SORT_COMPARE_INDEX, PSVECTOR_SORT_SWAP_INDEX); 489 PSVECTOR_SORT_CASE(U64, S32, PSVECTOR_SORT_COMPARE_INDEX, PSVECTOR_SORT_SWAP_INDEX); 490 PSVECTOR_SORT_CASE(S8 , S32, PSVECTOR_SORT_COMPARE_INDEX, PSVECTOR_SORT_SWAP_INDEX); 491 PSVECTOR_SORT_CASE(S16, S32, PSVECTOR_SORT_COMPARE_INDEX, PSVECTOR_SORT_SWAP_INDEX); 492 PSVECTOR_SORT_CASE(S32, S32, PSVECTOR_SORT_COMPARE_INDEX, PSVECTOR_SORT_SWAP_INDEX); 493 PSVECTOR_SORT_CASE(S64, S32, PSVECTOR_SORT_COMPARE_INDEX, PSVECTOR_SORT_SWAP_INDEX); 494 PSVECTOR_SORT_CASE(F32, S32, PSVECTOR_SORT_COMPARE_INDEX, PSVECTOR_SORT_SWAP_INDEX); 495 PSVECTOR_SORT_CASE(F64, S32, PSVECTOR_SORT_COMPARE_INDEX, PSVECTOR_SORT_SWAP_INDEX); 502 496 default: 503 497 psError(PS_ERR_BAD_PARAMETER_TYPE, true, 504 498 _("Input psVector is an unsupported type (0x%x)."), 505 inVector->type.type); 506 psFree(outVector); 507 return NULL; 508 } 509 return out; 499 vector->type.type); 500 psFree(indexVector); 501 return NULL; 502 } 503 504 return indexVector; 510 505 } 511 506
Note:
See TracChangeset
for help on using the changeset viewer.
