File: sortIdx.c

    1   /*
    2    * File: sortIdx.c
    3    *
    4    * MATLAB Coder version            : 3.1
    5    * C/C++ source code generated on  : 22-Apr-2021 15:58:03
    6    */
    7   
    8   /* Include Files */
    9   #include "rt_nonfinite.h"
   10   #include "matlabfindpeaks.h"
   11   #include "sortIdx.h"
   12   #include "matlabfindpeaks_emxutil.h"
   13   
   14   /* Function Declarations */
   15   static void b_merge(emxArray_int32_T *idx, emxArray_real_T *x, int offset, int
   16                       np, int nq, emxArray_int32_T *iwork, emxArray_real_T *xwork);
   17   static void b_merge_block(emxArray_int32_T *idx, emxArray_real_T *x, int offset,
   18     int n, int preSortLevel, emxArray_int32_T *iwork, emxArray_real_T *xwork);
   19   static void b_merge_pow2_block(emxArray_int32_T *idx, emxArray_real_T *x, int
   20     offset);
   21   static void merge(emxArray_int32_T *idx, emxArray_real_T *x, int offset, int np,
   22                     int nq, emxArray_int32_T *iwork, emxArray_real_T *xwork);
   23   static void merge_block(emxArray_int32_T *idx, emxArray_real_T *x, int offset,
   24     int n, int preSortLevel, emxArray_int32_T *iwork, emxArray_real_T *xwork);
   25   static void merge_pow2_block(emxArray_int32_T *idx, emxArray_real_T *x, int
   26     offset);
   27   
   28   /* Function Definitions */
   29   
   30   /*
   31    * Arguments    : emxArray_int32_T *idx
   32    *                emxArray_real_T *x
   33    *                int offset
   34    *                int np
   35    *                int nq
   36    *                emxArray_int32_T *iwork
   37    *                emxArray_real_T *xwork
   38    * Return Type  : void
   39    */
   40   static void b_merge(emxArray_int32_T *idx, emxArray_real_T *x, int offset, int
   41                       np, int nq, emxArray_int32_T *iwork, emxArray_real_T *xwork)
   42   {
   43     int n;
   44     int qend;
   45     int p;
   46     int iout;
   47     int exitg1;
   48     if (nq == 0) {
   49     } else {
   50       n = np + nq;
   51       for (qend = 0; qend + 1 <= n; qend++) {
   52         iwork->data[qend] = idx->data[offset + qend];
   53         xwork->data[qend] = x->data[offset + qend];
   54       }
   55   
   56       p = 0;
   57       n = np;
   58       qend = np + nq;
   59       iout = offset - 1;
   60       do {
   61         exitg1 = 0;
   62         iout++;
   63         if (xwork->data[p] <= xwork->data[n]) {
   64           idx->data[iout] = iwork->data[p];
   65           x->data[iout] = xwork->data[p];
   66           if (p + 1 < np) {
   67             p++;
   68           } else {
   69             exitg1 = 1;
   70           }
   71         } else {
   72           idx->data[iout] = iwork->data[n];
   73           x->data[iout] = xwork->data[n];
   74           if (n + 1 < qend) {
   75             n++;
   76           } else {
   77             n = (iout - p) + 1;
   78             while (p + 1 <= np) {
   79               idx->data[n + p] = iwork->data[p];
   80               x->data[n + p] = xwork->data[p];
   81               p++;
   82             }
   83   
   84             exitg1 = 1;
   85           }
   86         }
   87       } while (exitg1 == 0);
   88     }
   89   }
   90   
   91   /*
   92    * Arguments    : emxArray_int32_T *idx
   93    *                emxArray_real_T *x
   94    *                int offset
   95    *                int n
   96    *                int preSortLevel
   97    *                emxArray_int32_T *iwork
   98    *                emxArray_real_T *xwork
   99    * Return Type  : void
  100    */
  101   static void b_merge_block(emxArray_int32_T *idx, emxArray_real_T *x, int offset,
  102     int n, int preSortLevel, emxArray_int32_T *iwork, emxArray_real_T *xwork)
  103   {
  104     int nPairs;
  105     int bLen;
  106     int tailOffset;
  107     int nTail;
  108     nPairs = n >> preSortLevel;
  109     bLen = 1 << preSortLevel;
  110     while (nPairs > 1) {
  111       if ((nPairs & 1) != 0) {
  112         nPairs--;
  113         tailOffset = bLen * nPairs;
  114         nTail = n - tailOffset;
  115         if (nTail > bLen) {
  116           b_merge(idx, x, offset + tailOffset, bLen, nTail - bLen, iwork, xwork);
  117         }
  118       }
  119   
  120       tailOffset = bLen << 1;
  121       nPairs >>= 1;
  122       for (nTail = 1; nTail <= nPairs; nTail++) {
  123         b_merge(idx, x, offset + (nTail - 1) * tailOffset, bLen, bLen, iwork,
  124                 xwork);
  125       }
  126   
  127       bLen = tailOffset;
  128     }
  129   
  130     if (n > bLen) {
  131       b_merge(idx, x, offset, bLen, n - bLen, iwork, xwork);
  132     }
  133   }
  134   
  135   /*
  136    * Arguments    : emxArray_int32_T *idx
  137    *                emxArray_real_T *x
  138    *                int offset
  139    * Return Type  : void
  140    */
  141   static void b_merge_pow2_block(emxArray_int32_T *idx, emxArray_real_T *x, int
  142     offset)
  143   {
  144     int iwork[256];
  145     double xwork[256];
  146     int b;
  147     int bLen;
  148     int bLen2;
  149     int nPairs;
  150     int k;
  151     int blockOffset;
  152     int q;
  153     int p;
  154     int exitg1;
  155     for (b = 0; b < 6; b++) {
  156       bLen = 1 << (b + 2);
  157       bLen2 = bLen << 1;
  158       nPairs = 256 >> (b + 3);
  159       for (k = 1; k <= nPairs; k++) {
  160         blockOffset = (offset + (k - 1) * bLen2) - 1;
  161         for (q = 1; q <= bLen2; q++) {
  162           iwork[q - 1] = idx->data[blockOffset + q];
  163           xwork[q - 1] = x->data[blockOffset + q];
  164         }
  165   
  166         p = 0;
  167         q = bLen;
  168         do {
  169           exitg1 = 0;
  170           blockOffset++;
  171           if (xwork[p] <= xwork[q]) {
  172             idx->data[blockOffset] = iwork[p];
  173             x->data[blockOffset] = xwork[p];
  174             if (p + 1 < bLen) {
  175               p++;
  176             } else {
  177               exitg1 = 1;
  178             }
  179           } else {
  180             idx->data[blockOffset] = iwork[q];
  181             x->data[blockOffset] = xwork[q];
  182             if (q + 1 < bLen2) {
  183               q++;
  184             } else {
  185               q = blockOffset - p;
  186               while (p + 1 <= bLen) {
  187                 idx->data[(q + p) + 1] = iwork[p];
  188                 x->data[(q + p) + 1] = xwork[p];
  189                 p++;
  190               }
  191   
  192               exitg1 = 1;
  193             }
  194           }
  195         } while (exitg1 == 0);
  196       }
  197     }
  198   }
  199   
  200   /*
  201    * Arguments    : emxArray_int32_T *idx
  202    *                emxArray_real_T *x
  203    *                int offset
  204    *                int np
  205    *                int nq
  206    *                emxArray_int32_T *iwork
  207    *                emxArray_real_T *xwork
  208    * Return Type  : void
  209    */
  210   static void merge(emxArray_int32_T *idx, emxArray_real_T *x, int offset, int np,
  211                     int nq, emxArray_int32_T *iwork, emxArray_real_T *xwork)
  212   {
  213     int n;
  214     int qend;
  215     int p;
  216     int iout;
  217     int exitg1;
  218     if (nq == 0) {
  219     } else {
  220       n = np + nq;
  221       for (qend = 0; qend + 1 <= n; qend++) {
  222         iwork->data[qend] = idx->data[offset + qend];
  223         xwork->data[qend] = x->data[offset + qend];
  224       }
  225   
  226       p = 0;
  227       n = np;
  228       qend = np + nq;
  229       iout = offset - 1;
  230       do {
  231         exitg1 = 0;
  232         iout++;
  233         if (xwork->data[p] >= xwork->data[n]) {
  234           idx->data[iout] = iwork->data[p];
  235           x->data[iout] = xwork->data[p];
  236           if (p + 1 < np) {
  237             p++;
  238           } else {
  239             exitg1 = 1;
  240           }
  241         } else {
  242           idx->data[iout] = iwork->data[n];
  243           x->data[iout] = xwork->data[n];
  244           if (n + 1 < qend) {
  245             n++;
  246           } else {
  247             n = (iout - p) + 1;
  248             while (p + 1 <= np) {
  249               idx->data[n + p] = iwork->data[p];
  250               x->data[n + p] = xwork->data[p];
  251               p++;
  252             }
  253   
  254             exitg1 = 1;
  255           }
  256         }
  257       } while (exitg1 == 0);
  258     }
  259   }
  260   
  261   /*
  262    * Arguments    : emxArray_int32_T *idx
  263    *                emxArray_real_T *x
  264    *                int offset
  265    *                int n
  266    *                int preSortLevel
  267    *                emxArray_int32_T *iwork
  268    *                emxArray_real_T *xwork
  269    * Return Type  : void
  270    */
  271   static void merge_block(emxArray_int32_T *idx, emxArray_real_T *x, int offset,
  272     int n, int preSortLevel, emxArray_int32_T *iwork, emxArray_real_T *xwork)
  273   {
  274     int nPairs;
  275     int bLen;
  276     int tailOffset;
  277     int nTail;
  278     nPairs = n >> preSortLevel;
  279     bLen = 1 << preSortLevel;
  280     while (nPairs > 1) {
  281       if ((nPairs & 1) != 0) {
  282         nPairs--;
  283         tailOffset = bLen * nPairs;
  284         nTail = n - tailOffset;
  285         if (nTail > bLen) {
  286           merge(idx, x, offset + tailOffset, bLen, nTail - bLen, iwork, xwork);
  287         }
  288       }
  289   
  290       tailOffset = bLen << 1;
  291       nPairs >>= 1;
  292       for (nTail = 1; nTail <= nPairs; nTail++) {
  293         merge(idx, x, offset + (nTail - 1) * tailOffset, bLen, bLen, iwork, xwork);
  294       }
  295   
  296       bLen = tailOffset;
  297     }
  298   
  299     if (n > bLen) {
  300       merge(idx, x, offset, bLen, n - bLen, iwork, xwork);
  301     }
  302   }
  303   
  304   /*
  305    * Arguments    : emxArray_int32_T *idx
  306    *                emxArray_real_T *x
  307    *                int offset
  308    * Return Type  : void
  309    */
  310   static void merge_pow2_block(emxArray_int32_T *idx, emxArray_real_T *x, int
  311     offset)
  312   {
  313     int iwork[256];
  314     double xwork[256];
  315     int b;
  316     int bLen;
  317     int bLen2;
  318     int nPairs;
  319     int k;
  320     int blockOffset;
  321     int q;
  322     int p;
  323     int exitg1;
  324     for (b = 0; b < 6; b++) {
  325       bLen = 1 << (b + 2);
  326       bLen2 = bLen << 1;
  327       nPairs = 256 >> (b + 3);
  328       for (k = 1; k <= nPairs; k++) {
  329         blockOffset = (offset + (k - 1) * bLen2) - 1;
  330         for (q = 1; q <= bLen2; q++) {
  331           iwork[q - 1] = idx->data[blockOffset + q];
  332           xwork[q - 1] = x->data[blockOffset + q];
  333         }
  334   
  335         p = 0;
  336         q = bLen;
  337         do {
  338           exitg1 = 0;
  339           blockOffset++;
  340           if (xwork[p] >= xwork[q]) {
  341             idx->data[blockOffset] = iwork[p];
  342             x->data[blockOffset] = xwork[p];
  343             if (p + 1 < bLen) {
  344               p++;
  345             } else {
  346               exitg1 = 1;
  347             }
  348           } else {
  349             idx->data[blockOffset] = iwork[q];
  350             x->data[blockOffset] = xwork[q];
  351             if (q + 1 < bLen2) {
  352               q++;
  353             } else {
  354               q = blockOffset - p;
  355               while (p + 1 <= bLen) {
  356                 idx->data[(q + p) + 1] = iwork[p];
  357                 x->data[(q + p) + 1] = xwork[p];
  358                 p++;
  359               }
  360   
  361               exitg1 = 1;
  362             }
  363           }
  364         } while (exitg1 == 0);
  365       }
  366     }
  367   }
  368   
  369   /*
  370    * Arguments    : emxArray_real_T *x
  371    *                emxArray_int32_T *idx
  372    * Return Type  : void
  373    */
  374   void b_sortIdx(emxArray_real_T *x, emxArray_int32_T *idx)
  375   {
  376     emxArray_real_T *b_x;
  377     int ib;
  378     int wOffset;
  379     int m;
  380     int n;
  381     double x4[4];
  382     int idx4[4];
  383     emxArray_int32_T *iwork;
  384     emxArray_real_T *xwork;
  385     int nNaNs;
  386     int k;
  387     signed char perm[4];
  388     int i3;
  389     int i4;
  390     emxInit_real_T(&b_x, 1);
  391     ib = x->size[0];
  392     wOffset = b_x->size[0];
  393     b_x->size[0] = x->size[0];
  394     emxEnsureCapacity((emxArray__common *)b_x, wOffset, (int)sizeof(double));
  395     m = x->size[0];
  396     for (wOffset = 0; wOffset < m; wOffset++) {
  397       b_x->data[wOffset] = x->data[wOffset];
  398     }
  399   
  400     wOffset = idx->size[0];
  401     idx->size[0] = ib;
  402     emxEnsureCapacity((emxArray__common *)idx, wOffset, (int)sizeof(int));
  403     for (wOffset = 0; wOffset < ib; wOffset++) {
  404       idx->data[wOffset] = 0;
  405     }
  406   
  407     n = x->size[0];
  408     for (m = 0; m < 4; m++) {
  409       x4[m] = 0.0;
  410       idx4[m] = 0;
  411     }
  412   
  413     emxInit_int32_T(&iwork, 1);
  414     wOffset = iwork->size[0];
  415     iwork->size[0] = ib;
  416     emxEnsureCapacity((emxArray__common *)iwork, wOffset, (int)sizeof(int));
  417     m = iwork->size[0];
  418     wOffset = iwork->size[0];
  419     iwork->size[0] = m;
  420     emxEnsureCapacity((emxArray__common *)iwork, wOffset, (int)sizeof(int));
  421     for (wOffset = 0; wOffset < m; wOffset++) {
  422       iwork->data[wOffset] = 0;
  423     }
  424   
  425     emxInit_real_T(&xwork, 1);
  426     m = x->size[0];
  427     wOffset = xwork->size[0];
  428     xwork->size[0] = m;
  429     emxEnsureCapacity((emxArray__common *)xwork, wOffset, (int)sizeof(double));
  430     m = xwork->size[0];
  431     wOffset = xwork->size[0];
  432     xwork->size[0] = m;
  433     emxEnsureCapacity((emxArray__common *)xwork, wOffset, (int)sizeof(double));
  434     for (wOffset = 0; wOffset < m; wOffset++) {
  435       xwork->data[wOffset] = 0.0;
  436     }
  437   
  438     nNaNs = 1;
  439     ib = 0;
  440     for (k = 0; k + 1 <= n; k++) {
  441       if (rtIsNaN(b_x->data[k])) {
  442         idx->data[n - nNaNs] = k + 1;
  443         xwork->data[n - nNaNs] = b_x->data[k];
  444         nNaNs++;
  445       } else {
  446         ib++;
  447         idx4[ib - 1] = k + 1;
  448         x4[ib - 1] = b_x->data[k];
  449         if (ib == 4) {
  450           ib = k - nNaNs;
  451           if (x4[0] <= x4[1]) {
  452             m = 1;
  453             wOffset = 2;
  454           } else {
  455             m = 2;
  456             wOffset = 1;
  457           }
  458   
  459           if (x4[2] <= x4[3]) {
  460             i3 = 3;
  461             i4 = 4;
  462           } else {
  463             i3 = 4;
  464             i4 = 3;
  465           }
  466   
  467           if (x4[m - 1] <= x4[i3 - 1]) {
  468             if (x4[wOffset - 1] <= x4[i3 - 1]) {
  469               perm[0] = (signed char)m;
  470               perm[1] = (signed char)wOffset;
  471               perm[2] = (signed char)i3;
  472               perm[3] = (signed char)i4;
  473             } else if (x4[wOffset - 1] <= x4[i4 - 1]) {
  474               perm[0] = (signed char)m;
  475               perm[1] = (signed char)i3;
  476               perm[2] = (signed char)wOffset;
  477               perm[3] = (signed char)i4;
  478             } else {
  479               perm[0] = (signed char)m;
  480               perm[1] = (signed char)i3;
  481               perm[2] = (signed char)i4;
  482               perm[3] = (signed char)wOffset;
  483             }
  484           } else if (x4[m - 1] <= x4[i4 - 1]) {
  485             if (x4[wOffset - 1] <= x4[i4 - 1]) {
  486               perm[0] = (signed char)i3;
  487               perm[1] = (signed char)m;
  488               perm[2] = (signed char)wOffset;
  489               perm[3] = (signed char)i4;
  490             } else {
  491               perm[0] = (signed char)i3;
  492               perm[1] = (signed char)m;
  493               perm[2] = (signed char)i4;
  494               perm[3] = (signed char)wOffset;
  495             }
  496           } else {
  497             perm[0] = (signed char)i3;
  498             perm[1] = (signed char)i4;
  499             perm[2] = (signed char)m;
  500             perm[3] = (signed char)wOffset;
  501           }
  502   
  503           idx->data[ib - 2] = idx4[perm[0] - 1];
  504           idx->data[ib - 1] = idx4[perm[1] - 1];
  505           idx->data[ib] = idx4[perm[2] - 1];
  506           idx->data[ib + 1] = idx4[perm[3] - 1];
  507           b_x->data[ib - 2] = x4[perm[0] - 1];
  508           b_x->data[ib - 1] = x4[perm[1] - 1];
  509           b_x->data[ib] = x4[perm[2] - 1];
  510           b_x->data[ib + 1] = x4[perm[3] - 1];
  511           ib = 0;
  512         }
  513       }
  514     }
  515   
  516     wOffset = x->size[0] - nNaNs;
  517     if (ib > 0) {
  518       for (m = 0; m < 4; m++) {
  519         perm[m] = 0;
  520       }
  521   
  522       if (ib == 1) {
  523         perm[0] = 1;
  524       } else if (ib == 2) {
  525         if (x4[0] <= x4[1]) {
  526           perm[0] = 1;
  527           perm[1] = 2;
  528         } else {
  529           perm[0] = 2;
  530           perm[1] = 1;
  531         }
  532       } else if (x4[0] <= x4[1]) {
  533         if (x4[1] <= x4[2]) {
  534           perm[0] = 1;
  535           perm[1] = 2;
  536           perm[2] = 3;
  537         } else if (x4[0] <= x4[2]) {
  538           perm[0] = 1;
  539           perm[1] = 3;
  540           perm[2] = 2;
  541         } else {
  542           perm[0] = 3;
  543           perm[1] = 1;
  544           perm[2] = 2;
  545         }
  546       } else if (x4[0] <= x4[2]) {
  547         perm[0] = 2;
  548         perm[1] = 1;
  549         perm[2] = 3;
  550       } else if (x4[1] <= x4[2]) {
  551         perm[0] = 2;
  552         perm[1] = 3;
  553         perm[2] = 1;
  554       } else {
  555         perm[0] = 3;
  556         perm[1] = 2;
  557         perm[2] = 1;
  558       }
  559   
  560       for (k = 1; k <= ib; k++) {
  561         idx->data[(wOffset - ib) + k] = idx4[perm[k - 1] - 1];
  562         b_x->data[(wOffset - ib) + k] = x4[perm[k - 1] - 1];
  563       }
  564     }
  565   
  566     m = (nNaNs - 1) >> 1;
  567     for (k = 1; k <= m; k++) {
  568       ib = idx->data[wOffset + k];
  569       idx->data[wOffset + k] = idx->data[n - k];
  570       idx->data[n - k] = ib;
  571       b_x->data[wOffset + k] = xwork->data[n - k];
  572       b_x->data[n - k] = xwork->data[wOffset + k];
  573     }
  574   
  575     if (((nNaNs - 1) & 1) != 0) {
  576       b_x->data[(wOffset + m) + 1] = xwork->data[(wOffset + m) + 1];
  577     }
  578   
  579     wOffset = (x->size[0] - nNaNs) + 1;
  580     m = 2;
  581     if (wOffset > 1) {
  582       if (x->size[0] >= 256) {
  583         ib = wOffset >> 8;
  584         if (ib > 0) {
  585           for (m = 1; m <= ib; m++) {
  586             b_merge_pow2_block(idx, b_x, (m - 1) << 8);
  587           }
  588   
  589           m = ib << 8;
  590           ib = wOffset - m;
  591           if (ib > 0) {
  592             b_merge_block(idx, b_x, m, ib, 2, iwork, xwork);
  593           }
  594   
  595           m = 8;
  596         }
  597       }
  598   
  599       b_merge_block(idx, b_x, 0, wOffset, m, iwork, xwork);
  600     }
  601   
  602     emxFree_real_T(&xwork);
  603     emxFree_int32_T(&iwork);
  604     wOffset = x->size[0];
  605     x->size[0] = b_x->size[0];
  606     emxEnsureCapacity((emxArray__common *)x, wOffset, (int)sizeof(double));
  607     m = b_x->size[0];
  608     for (wOffset = 0; wOffset < m; wOffset++) {
  609       x->data[wOffset] = b_x->data[wOffset];
  610     }
  611   
  612     emxFree_real_T(&b_x);
  613   }
  614   
  615   /*
  616    * Arguments    : emxArray_real_T *x
  617    *                emxArray_int32_T *idx
  618    * Return Type  : void
  619    */
  620   void sortIdx(emxArray_real_T *x, emxArray_int32_T *idx)
  621   {
  622     emxArray_real_T *b_x;
  623     int ib;
  624     int wOffset;
  625     int m;
  626     int n;
  627     double x4[4];
  628     int idx4[4];
  629     emxArray_int32_T *iwork;
  630     emxArray_real_T *xwork;
  631     int nNaNs;
  632     int k;
  633     signed char perm[4];
  634     int i3;
  635     int i4;
  636     emxInit_real_T(&b_x, 1);
  637     ib = x->size[0];
  638     wOffset = b_x->size[0];
  639     b_x->size[0] = x->size[0];
  640     emxEnsureCapacity((emxArray__common *)b_x, wOffset, (int)sizeof(double));
  641     m = x->size[0];
  642     for (wOffset = 0; wOffset < m; wOffset++) {
  643       b_x->data[wOffset] = x->data[wOffset];
  644     }
  645   
  646     wOffset = idx->size[0];
  647     idx->size[0] = ib;
  648     emxEnsureCapacity((emxArray__common *)idx, wOffset, (int)sizeof(int));
  649     for (wOffset = 0; wOffset < ib; wOffset++) {
  650       idx->data[wOffset] = 0;
  651     }
  652   
  653     n = x->size[0];
  654     for (m = 0; m < 4; m++) {
  655       x4[m] = 0.0;
  656       idx4[m] = 0;
  657     }
  658   
  659     emxInit_int32_T(&iwork, 1);
  660     wOffset = iwork->size[0];
  661     iwork->size[0] = ib;
  662     emxEnsureCapacity((emxArray__common *)iwork, wOffset, (int)sizeof(int));
  663     m = iwork->size[0];
  664     wOffset = iwork->size[0];
  665     iwork->size[0] = m;
  666     emxEnsureCapacity((emxArray__common *)iwork, wOffset, (int)sizeof(int));
  667     for (wOffset = 0; wOffset < m; wOffset++) {
  668       iwork->data[wOffset] = 0;
  669     }
  670   
  671     emxInit_real_T(&xwork, 1);
  672     m = x->size[0];
  673     wOffset = xwork->size[0];
  674     xwork->size[0] = m;
  675     emxEnsureCapacity((emxArray__common *)xwork, wOffset, (int)sizeof(double));
  676     m = xwork->size[0];
  677     wOffset = xwork->size[0];
  678     xwork->size[0] = m;
  679     emxEnsureCapacity((emxArray__common *)xwork, wOffset, (int)sizeof(double));
  680     for (wOffset = 0; wOffset < m; wOffset++) {
  681       xwork->data[wOffset] = 0.0;
  682     }
  683   
  684     nNaNs = 0;
  685     ib = 0;
  686     for (k = 0; k + 1 <= n; k++) {
  687       if (rtIsNaN(b_x->data[k])) {
  688         idx->data[(n - nNaNs) - 1] = k + 1;
  689         xwork->data[(n - nNaNs) - 1] = b_x->data[k];
  690         nNaNs++;
  691       } else {
  692         ib++;
  693         idx4[ib - 1] = k + 1;
  694         x4[ib - 1] = b_x->data[k];
  695         if (ib == 4) {
  696           ib = k - nNaNs;
  697           if (x4[0] >= x4[1]) {
  698             m = 1;
  699             wOffset = 2;
  700           } else {
  701             m = 2;
  702             wOffset = 1;
  703           }
  704   
  705           if (x4[2] >= x4[3]) {
  706             i3 = 3;
  707             i4 = 4;
  708           } else {
  709             i3 = 4;
  710             i4 = 3;
  711           }
  712   
  713           if (x4[m - 1] >= x4[i3 - 1]) {
  714             if (x4[wOffset - 1] >= x4[i3 - 1]) {
  715               perm[0] = (signed char)m;
  716               perm[1] = (signed char)wOffset;
  717               perm[2] = (signed char)i3;
  718               perm[3] = (signed char)i4;
  719             } else if (x4[wOffset - 1] >= x4[i4 - 1]) {
  720               perm[0] = (signed char)m;
  721               perm[1] = (signed char)i3;
  722               perm[2] = (signed char)wOffset;
  723               perm[3] = (signed char)i4;
  724             } else {
  725               perm[0] = (signed char)m;
  726               perm[1] = (signed char)i3;
  727               perm[2] = (signed char)i4;
  728               perm[3] = (signed char)wOffset;
  729             }
  730           } else if (x4[m - 1] >= x4[i4 - 1]) {
  731             if (x4[wOffset - 1] >= x4[i4 - 1]) {
  732               perm[0] = (signed char)i3;
  733               perm[1] = (signed char)m;
  734               perm[2] = (signed char)wOffset;
  735               perm[3] = (signed char)i4;
  736             } else {
  737               perm[0] = (signed char)i3;
  738               perm[1] = (signed char)m;
  739               perm[2] = (signed char)i4;
  740               perm[3] = (signed char)wOffset;
  741             }
  742           } else {
  743             perm[0] = (signed char)i3;
  744             perm[1] = (signed char)i4;
  745             perm[2] = (signed char)m;
  746             perm[3] = (signed char)wOffset;
  747           }
  748   
  749           idx->data[ib - 3] = idx4[perm[0] - 1];
  750           idx->data[ib - 2] = idx4[perm[1] - 1];
  751           idx->data[ib - 1] = idx4[perm[2] - 1];
  752           idx->data[ib] = idx4[perm[3] - 1];
  753           b_x->data[ib - 3] = x4[perm[0] - 1];
  754           b_x->data[ib - 2] = x4[perm[1] - 1];
  755           b_x->data[ib - 1] = x4[perm[2] - 1];
  756           b_x->data[ib] = x4[perm[3] - 1];
  757           ib = 0;
  758         }
  759       }
  760     }
  761   
  762     wOffset = (x->size[0] - nNaNs) - 1;
  763     if (ib > 0) {
  764       for (m = 0; m < 4; m++) {
  765         perm[m] = 0;
  766       }
  767   
  768       if (ib == 1) {
  769         perm[0] = 1;
  770       } else if (ib == 2) {
  771         if (x4[0] >= x4[1]) {
  772           perm[0] = 1;
  773           perm[1] = 2;
  774         } else {
  775           perm[0] = 2;
  776           perm[1] = 1;
  777         }
  778       } else if (x4[0] >= x4[1]) {
  779         if (x4[1] >= x4[2]) {
  780           perm[0] = 1;
  781           perm[1] = 2;
  782           perm[2] = 3;
  783         } else if (x4[0] >= x4[2]) {
  784           perm[0] = 1;
  785           perm[1] = 3;
  786           perm[2] = 2;
  787         } else {
  788           perm[0] = 3;
  789           perm[1] = 1;
  790           perm[2] = 2;
  791         }
  792       } else if (x4[0] >= x4[2]) {
  793         perm[0] = 2;
  794         perm[1] = 1;
  795         perm[2] = 3;
  796       } else if (x4[1] >= x4[2]) {
  797         perm[0] = 2;
  798         perm[1] = 3;
  799         perm[2] = 1;
  800       } else {
  801         perm[0] = 3;
  802         perm[1] = 2;
  803         perm[2] = 1;
  804       }
  805   
  806       for (k = 1; k <= ib; k++) {
  807         idx->data[(wOffset - ib) + k] = idx4[perm[k - 1] - 1];
  808         b_x->data[(wOffset - ib) + k] = x4[perm[k - 1] - 1];
  809       }
  810     }
  811   
  812     m = nNaNs >> 1;
  813     for (k = 1; k <= m; k++) {
  814       ib = idx->data[wOffset + k];
  815       idx->data[wOffset + k] = idx->data[n - k];
  816       idx->data[n - k] = ib;
  817       b_x->data[wOffset + k] = xwork->data[n - k];
  818       b_x->data[n - k] = xwork->data[wOffset + k];
  819     }
  820   
  821     if ((nNaNs & 1) != 0) {
  822       b_x->data[(wOffset + m) + 1] = xwork->data[(wOffset + m) + 1];
  823     }
  824   
  825     wOffset = x->size[0] - nNaNs;
  826     m = 2;
  827     if (wOffset > 1) {
  828       if (x->size[0] >= 256) {
  829         ib = wOffset >> 8;
  830         if (ib > 0) {
  831           for (m = 1; m <= ib; m++) {
  832             merge_pow2_block(idx, b_x, (m - 1) << 8);
  833           }
  834   
  835           m = ib << 8;
  836           ib = wOffset - m;
  837           if (ib > 0) {
  838             merge_block(idx, b_x, m, ib, 2, iwork, xwork);
  839           }
  840   
  841           m = 8;
  842         }
  843       }
  844   
  845       merge_block(idx, b_x, 0, wOffset, m, iwork, xwork);
  846     }
  847   
  848     if ((nNaNs > 0) && (wOffset > 0)) {
  849       for (k = 0; k + 1 <= nNaNs; k++) {
  850         xwork->data[k] = b_x->data[wOffset + k];
  851         iwork->data[k] = idx->data[wOffset + k];
  852       }
  853   
  854       for (k = wOffset - 1; k + 1 > 0; k--) {
  855         b_x->data[nNaNs + k] = b_x->data[k];
  856         idx->data[nNaNs + k] = idx->data[k];
  857       }
  858   
  859       for (k = 0; k + 1 <= nNaNs; k++) {
  860         b_x->data[k] = xwork->data[k];
  861         idx->data[k] = iwork->data[k];
  862       }
  863     }
  864   
  865     emxFree_real_T(&xwork);
  866     emxFree_int32_T(&iwork);
  867     wOffset = x->size[0];
  868     x->size[0] = b_x->size[0];
  869     emxEnsureCapacity((emxArray__common *)x, wOffset, (int)sizeof(double));
  870     m = b_x->size[0];
  871     for (wOffset = 0; wOffset < m; wOffset++) {
  872       x->data[wOffset] = b_x->data[wOffset];
  873     }
  874   
  875     emxFree_real_T(&b_x);
  876   }
  877   
  878   /*
  879    * File trailer for sortIdx.c
  880    *
  881    * [EOF]
  882    */
  883