IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 6977


Ignore:
Timestamp:
Apr 24, 2006, 5:30:29 PM (20 years ago)
Author:
Paul Price
Message:

Added special case for psVectorCopy (copying to the same type: use memcpy).
Changed psVectorCopy to use our own heapsort --- faster sorts by a factor of ~ 2.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/mathtypes/psVector.c

    r6886 r6977  
    99*  @author Robert DeSonia, MHPCC
    1010*
    11 *  @version $Revision: 1.67 $ $Name: not supported by cvs2svn $
    12 *  @date $Date: 2006-04-18 22:12:28 $
     11*  @version $Revision: 1.68 $ $Name: not supported by cvs2svn $
     12*  @date $Date: 2006-04-25 03:30:29 $
    1313*
    1414*  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
     
    207207    output = psVectorRecycle(output, nElements, type);
    208208    output->n = nElements;
     209
     210    if (input->type.type == type) {
     211        // Can simply copy the bytes if the types are the same
     212
     213        #define PSVECTOR_COPY_SAME_CASE(NAME) \
     214    case PS_TYPE_##NAME: \
     215        output->data.NAME = memcpy(output->data.NAME, input->data.NAME, \
     216                                   input->n * PSELEMTYPE_SIZEOF(PS_TYPE_##NAME)); \
     217        break;
     218
     219        switch (type) {
     220            PSVECTOR_COPY_SAME_CASE(U8);
     221            PSVECTOR_COPY_SAME_CASE(U16);
     222            PSVECTOR_COPY_SAME_CASE(U32);
     223            PSVECTOR_COPY_SAME_CASE(U64);
     224            PSVECTOR_COPY_SAME_CASE(S8);
     225            PSVECTOR_COPY_SAME_CASE(S16);
     226            PSVECTOR_COPY_SAME_CASE(S32);
     227            PSVECTOR_COPY_SAME_CASE(S64);
     228            PSVECTOR_COPY_SAME_CASE(F32);
     229            PSVECTOR_COPY_SAME_CASE(F64);
     230            PSVECTOR_COPY_SAME_CASE(C32);
     231            PSVECTOR_COPY_SAME_CASE(C64);
     232        default: {
     233                char* typeStr;
     234                PS_TYPE_NAME(typeStr,type);
     235                psError(PS_ERR_BAD_PARAMETER_TYPE, true, PS_ERRORTEXT_psVector_UNSUPPORTED_TYPE, typeStr);
     236                psFree(output);
     237                return NULL;
     238            }
     239        }
     240        return output;
     241    }
    209242
    210243    #define PSVECTOR_COPY(INTYPE,OUTTYPE) { \
     
    296329}
    297330
     331// Heap sort of the array
     332#define PSVECTOR_SORT_CASE(NAME) \
     333case PS_TYPE_##NAME: { \
     334    ps##NAME temp; \
     335    ps##NAME *value = out->data.NAME; \
     336    for (;;) { \
     337        if (l > 0) { \
     338            temp = value[--l]; \
     339        } else { \
     340            temp = value[ir]; \
     341            value[ir] = value[0]; \
     342            if (--ir == 0) { \
     343                value[0] = temp; \
     344                return out; \
     345            } \
     346        } \
     347        int i = l; \
     348        int j = (l << 1) + 1; \
     349        while (j <= ir) { \
     350            if (j < ir && value[j] < value[j+1]) \
     351                ++j; \
     352            if (temp < value[j]) { \
     353                value[i]=value[j]; \
     354                j += (i=j) + 1; \
     355            } else { \
     356                j = ir + 1; \
     357            } \
     358        } \
     359        value[i] = temp; \
     360    } \
     361} \
     362break;
     363
    298364psVector* psVectorSort(psVector* outVector,
    299365                       const psVector* inVector)
    300366{
    301     psS32 N = 0;
    302     psS32 elSize = 0;
    303     psPtr inVec = NULL;
    304     psPtr outVec = NULL;
    305     psElemType inType = 0;
    306 
     367    if (!inVector) {
     368        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     369                PS_ERRORTEXT_psVector_SORT_NULL);
     370        psFree(outVector);
     371        return NULL;
     372    }
     373
     374    psVector *out = psVectorCopy(outVector, inVector, inVector->type.type); // Copy to sort in place
     375    long N = out->n;                    // Number of elements
     376    if (N < 2) {
     377        return out;
     378    }
     379    long l = N >> 1;
     380    long ir = N - 1;
     381    switch (out->type.type) {
     382        PSVECTOR_SORT_CASE(U8);
     383        PSVECTOR_SORT_CASE(U16);
     384        PSVECTOR_SORT_CASE(U32);
     385        PSVECTOR_SORT_CASE(U64);
     386        PSVECTOR_SORT_CASE(S8);
     387        PSVECTOR_SORT_CASE(S16);
     388        PSVECTOR_SORT_CASE(S32);
     389        PSVECTOR_SORT_CASE(S64);
     390        PSVECTOR_SORT_CASE(F32);
     391        PSVECTOR_SORT_CASE(F64);
     392    default:
     393        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
     394                PS_ERRORTEXT_psVector_UNSUPPORTED_TYPE,
     395                inVector->type.type);
     396        psFree(outVector);
     397        return NULL;
     398    }
     399    return out;
     400}
     401
     402// Heap sort of the index array
     403#define PSVECTOR_SORT_INDEX_CASE(NAME) \
     404case PS_TYPE_##NAME: { \
     405    psU32 temp; \
     406    psU32 *index = out->data.U32; \
     407    ps##NAME *value = inVector->data.NAME; \
     408    for (;;) { \
     409        if (l > 0) { \
     410            temp = index[--l]; \
     411        } else { \
     412            temp = index[ir]; \
     413            index[ir] = index[0]; \
     414            if (--ir == 0) { \
     415                index[0] = temp; \
     416                return out; \
     417            } \
     418        } \
     419        int i = l; \
     420        int j = (l << 1) + 1; \
     421        while (j <= ir) { \
     422            if (j < ir && value[index[j]] < value[index[j+1]]) \
     423                ++j; \
     424            if (value[temp] < value[index[j]]) { \
     425                index[i]=index[j]; \
     426                j += (i=j) + 1; \
     427            } else { \
     428                j = ir + 1; \
     429            } \
     430        } \
     431        index[i] = temp; \
     432    } \
     433} \
     434break;
     435
     436psVector* psVectorSortIndex(psVector* outVector,
     437                            const psVector* inVector)
     438{
    307439    if (inVector == NULL) {
    308440        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     
    312444    }
    313445
    314     inType = inVector->type.type;
    315     N = inVector->n;
    316     inVec = (psPtr)inVector->data.U8;
    317     elSize = PSELEMTYPE_SIZEOF(inType);
    318 
    319     if (outVector == NULL) {
    320         outVector = psVectorAlloc(N, inType);
    321     }
    322 
    323     // check to see if output vector needs to be resized/retyped
    324     if ( (N > outVector->nalloc) ||
    325             (inType != outVector->type.type) ) {
    326         // reshape the output vector to match the input vector's size/type.
    327         outVector = psVectorRecycle(outVector,N,inType);
    328     }
    329     outVector->n = N;
    330     outVec = outVector->data.U8;
    331 
    332     if (N == 0) {
    333         // no need to sort anything, as there are no elements in input vector.
    334         return outVector;
    335     }
    336 
    337     // Copy input vector values into output vector if not in-place sorting
    338     if (inVector != outVector) {
    339         memcpy(outVec, inVec, elSize * N);
    340     }
    341 
    342     // Sort output vector
    343     switch (inType) {
    344     case PS_TYPE_U8:
    345         qsort(outVec, N, elSize, psCompareU8);
    346         break;
    347     case PS_TYPE_U16:
    348         qsort(outVec, N, elSize, psCompareU16);
    349         break;
    350     case PS_TYPE_U32:
    351         qsort(outVec, N, elSize, psCompareU32);
    352         break;
    353     case PS_TYPE_U64:
    354         qsort(outVec, N, elSize, psCompareU64);
    355         break;
    356     case PS_TYPE_S8:
    357         qsort(outVec, N, elSize, psCompareS8);
    358         break;
    359     case PS_TYPE_S16:
    360         qsort(outVec, N, elSize, psCompareS16);
    361         break;
    362     case PS_TYPE_S32:
    363         qsort(outVec, N, elSize, psCompareS32);
    364         break;
    365     case PS_TYPE_S64:
    366         qsort(outVec, N, elSize, psCompareS64);
    367         break;
    368     case PS_TYPE_F32:
    369         qsort(outVec, N, elSize, psCompareF32);
    370         break;
    371     case PS_TYPE_F64:
    372         qsort(outVec, N, elSize, psCompareF64);
    373         break;
     446    psVector *out = psVectorRecycle(outVector, inVector->n, PS_TYPE_U32); // Vector for output
     447    out = psVectorCreate(out, 0, inVector->n, 1, PS_TYPE_U32);
     448    long N = out->n;                    // Number of elements
     449    if (N < 2) {
     450        return out;
     451    }
     452    long l = N >> 1;
     453    long ir = N - 1;
     454    switch (out->type.type) {
     455        PSVECTOR_SORT_INDEX_CASE(U8);
     456        PSVECTOR_SORT_INDEX_CASE(U16);
     457        PSVECTOR_SORT_INDEX_CASE(U32);
     458        PSVECTOR_SORT_INDEX_CASE(U64);
     459        PSVECTOR_SORT_INDEX_CASE(S8);
     460        PSVECTOR_SORT_INDEX_CASE(S16);
     461        PSVECTOR_SORT_INDEX_CASE(S32);
     462        PSVECTOR_SORT_INDEX_CASE(S64);
     463        PSVECTOR_SORT_INDEX_CASE(F32);
     464        PSVECTOR_SORT_INDEX_CASE(F64);
    374465    default:
    375466        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
    376467                PS_ERRORTEXT_psVector_UNSUPPORTED_TYPE,
    377                 inType);
     468                inVector->type.type);
    378469        psFree(outVector);
    379470        return NULL;
    380471    }
    381 
    382     return outVector;
    383 }
    384 
    385 psVector* psVectorSortIndex(psVector* outVector,
    386                             const psVector* inVector)
    387 {
    388     psS32 N = 0;
    389     psElemType inType = 0;
    390 
    391     if (inVector == NULL) {
    392         psError(PS_ERR_BAD_PARAMETER_NULL, true,
    393                 PS_ERRORTEXT_psVector_SORT_NULL);
    394         psFree(outVector);
    395         return NULL;
    396     }
    397 
    398     inType = inVector->type.type;
    399     N = inVector->n;
    400 
    401     if (N == 0) {
    402         // no need to sort anything, as there are no elements in input vector.
    403         return outVector;
    404     }
    405 
    406     // ok, let's create a temporary indexed vector
    407     indexedVector* idxVector = psAlloc(sizeof(indexedVector)*N);
    408     int elSize = PSELEMTYPE_SIZEOF(inType);
    409     for (int i = 0; i < N; i++) {
    410         idxVector[i].data.U8 = inVector->data.U8+i*elSize;
    411         idxVector[i].index = i;
    412     }
    413 
    414     // Sort indexed vector
    415     // n.b., since first element in indexedVector is a pointer to the data,
    416     // we can use the 'Ptr' version of the standard compare functions
    417     switch (inType) {
    418     case PS_TYPE_U8:
    419         qsort(idxVector, N, sizeof(indexedVector), (psCompareFcn)psCompareU8Ptr);
    420         break;
    421     case PS_TYPE_U16:
    422         qsort(idxVector, N, sizeof(indexedVector), (psCompareFcn)psCompareU16Ptr);
    423         break;
    424     case PS_TYPE_U32:
    425         qsort(idxVector, N, sizeof(indexedVector), (psCompareFcn)psCompareU32Ptr);
    426         break;
    427     case PS_TYPE_U64:
    428         qsort(idxVector, N, sizeof(indexedVector), (psCompareFcn)psCompareU64Ptr);
    429         break;
    430     case PS_TYPE_S8:
    431         qsort(idxVector, N, sizeof(indexedVector), (psCompareFcn)psCompareS8Ptr);
    432         break;
    433     case PS_TYPE_S16:
    434         qsort(idxVector, N, sizeof(indexedVector), (psCompareFcn)psCompareS16Ptr);
    435         break;
    436     case PS_TYPE_S32:
    437         qsort(idxVector, N, sizeof(indexedVector), (psCompareFcn)psCompareS32Ptr);
    438         break;
    439     case PS_TYPE_S64:
    440         qsort(idxVector, N, sizeof(indexedVector), (psCompareFcn)psCompareS64Ptr);
    441         break;
    442     case PS_TYPE_F32:
    443         qsort(idxVector, N, sizeof(indexedVector), (psCompareFcn)psCompareF32Ptr);
    444         break;
    445     case PS_TYPE_F64:
    446         qsort(idxVector, N, sizeof(indexedVector), (psCompareFcn)psCompareF64Ptr);
    447         break;
    448     default:
    449         psError(PS_ERR_BAD_PARAMETER_TYPE, true,
    450                 PS_ERRORTEXT_psVector_UNSUPPORTED_TYPE,
    451                 inType);
    452         psFree(idxVector);
    453         psFree(outVector);
    454         return NULL;
    455     }
    456 
    457     // extract the indices to the output vector
    458     outVector = psVectorRecycle(outVector, N, PS_TYPE_U32);
    459     outVector->n = N;
    460     psU32* outData = outVector->data.U32;
    461     for (int i = 0; i < N; i++) {
    462         outData[i] = idxVector[i].index;
    463     }
    464 
    465     // Free temp memory
    466     psFree(idxVector);
    467 
    468     return outVector;
     472    return out;
    469473}
    470474
Note: See TracChangeset for help on using the changeset viewer.