View Raw SPL

/* convert unraveled indices to row, col form */
ind2sub(nr, nc, np, ind)
{
        local row, col, page;

        (nr, nc, np, ind) = ind2sub_parse_args(nr, nc, np, ind);

        row = mod(ind - 1, nr) + 1;

        if (outargc <= 1)
        {
                /* force series */
                row = {row};
        }

        if (isarray(row))
        {
                setcomment(row, "Row");
        }

        if (argc < 4)
        {
                /* 2D */
                col = floor((ind - 1) / nr) + 1;

                if (outargc <= 1)
                {
                        /* force series */
                        col = {col};
                }

                if (isarray(col))
                {
                        setcomment(col, "Col");
                }

                if (outargc <= 1)
                {
                        return(ravel(row, col));

                }

                return(row, col);
        }

        /* 3D indexing */
        col  = mod(floor((ind - 1) / nr), nc) + 1;
        page = floor((ind - 1) / (nr * nc)) + 1;

        if (outargc <= 1)
        {
                /* force series */
                col  = {col};
                page = {page};
        }

        if (isarray(col))
        {
                setcomment(col, "Col");
        }

        if (isarray(page))
        {
                setcomment(page, "Page");
        }

        if (outargc <= 1)
        {
                return(ravel(row, col, page));
        }

        return(row, col, page);
}


/* parse input args */
ind2sub_parse_args(nr, nc, np, ind)
{
        if (argc < 4)
        {
                if (argc < 3)
                {
                        if (argc < 2)
                        {
                                error(sprintf("%s - 2 or 3 inputs required", __CALLER__));
                        }

                        if (isarray(nr) && numrows(nr) >= 2)
                        {
                                ind = nc;

                                if (numrows(nr) >= 3)
                                {
                                        /* 3D */
                                        np = nr[3];
                                }
                                else
                                {
                                        np = 1;
                                }

                                nc = nr[2];
                                nr = nr[1];
                        }
                        else
                        {
                                error(sprintf("%s - 2xN or 3xN size array expected", __CALLER__));
                        }
                }
                else
                {
                        ind = np;
                        np = ones(size(nr));
                }
        }

        return(nr, nc, np, ind);
}