예제 #1
0
bool SpidirParams::order(SpeciesTree *stree)
{
    if (stree->nnodes != nsnodes) {
        printError("wrong number of parameters: %d %d\n", stree->nnodes, nsnodes);
        return false;
    }
    
    ExtendArray<Node*> nodeorder(0, stree->nnodes);
    getTreePreOrder(stree, &nodeorder);
        

    // make interior node names
    ExtendArray<int> inodes(stree->nnodes);
    
    int inodename = 1;
    for (int i=0; i<stree->nnodes; i++) {
        Node *node = nodeorder[i];
        if (node->isLeaf()) {
            inodes[node->name] = -1;
        } else {
            inodes[node->name] = inodename++;
        }
    }
    
    
    // loop through preordered nodes to construct permutation
    ExtendArray<int> invperm(0, stree->nnodes);
        
    for (int j=0; j<nsnodes; j++) {
        if (invperm.size() != j) {
            printError("unable to match '%s' to the species tree", 
                       names[j].c_str());
            return false;
        }

        // try to parse node id as an int
        int id;
        bool isint = (sscanf(names[j].c_str(), "%d", &id) == 1);
        
        for (int i=0; i<stree->nnodes; i++) {
            if (stree->nodes[i]->isLeaf()) {
                // if leaf, check if names match
                if (names[j] == stree->nodes[i]->longname) {
                    invperm.append(i);
                    break;
                }
            } else {
                if (isint && id == inodes[i]) {
                    invperm.append(i);
                    break;
                }
            }
        }
    }

    
    // apply permutation
    ExtendArray<int> perm(stree->nnodes);
    invertPerm(invperm, perm, nsnodes);    
      
    permute(names, perm, nsnodes);
    permute(sp_alpha, perm, nsnodes);
    permute(sp_beta, perm, nsnodes);
    
    return true;
}
예제 #2
0
        skyline_lu(const Matrix &A, const params &prm = params())
            : n( backend::rows(A) ), perm(n), ptr(n + 1, 0), D(n, 0), y(n)
        {
            typedef typename backend::row_iterator<Matrix>::type row_iterator;

            // Find the permutation for the ordering.
            ordering::get(A, perm);

            // Get inverse permutation
            std::vector<int> invperm(n);
            for(int i = 0; i < n; ++i) invperm[perm[i]] = i;

            /* Let us find how large the rows of L and the columns of U should
             * be.  Provisionally, we will store in ptr[i] the minimum required
             * height of column i over the diagonal, and length of row i below
             * the diagonal.  The value(i,j) in the reordered matrix will be
             * the same as the value(perm[i],perm[j]) in the original matrix;
             * or, the value(i,j) in the original matrix will be the same as
             * value(invperm[i],invperm[j]) in the reordered matrix.
             */

            // Traverse the matrix finding nonzero elements
            for(int i = 0; i < n; ++i) {
                for(row_iterator a = backend::row_begin(A, i); a; ++a) {
                    int  j = a.col();
                    real v = a.value();

                    int newi = invperm[i];
                    int newj = invperm[j];

                    if (v != 0) {
                        if (newi > newj) {
                            // row newi needs length at least newi - newj
                            if (ptr[newi] < newi - newj) ptr[newi]= newi - newj;
                        } else if (newi < newj) {
                            // column newj needs height at least newj - newi
                            if (ptr[newj] < newj - newi) ptr[newj]= newj - newi;
                        }
                    }
                }
            }

            // Transform ptr so that it doesn't contain the required lengths
            // and heights, but the indexes to the entries
            {
                int last = 0;
                for(int i = 1; i <= n; ++i) {
                    int tmp = ptr[i];
                    ptr[i] = ptr[i-1] + last;
                    last = tmp;
                }
            }

            // Allocate variables for skyline format entries
            L.resize(ptr.back(), 0);
            U.resize(ptr.back(), 0);

            // And finally traverse again the CSR matrix, copying its entries
            // into the correct places in the skyline format
            for(int i = 0; i < n; ++i) {
                for(row_iterator a = backend::row_begin(A, i); a; ++a) {
                    int  j = a.col();
                    real v = a.value();

                    int newi = invperm[i];
                    int newj = invperm[j];

                    if (v != 0) {
                        if (newi < newj) {
                            U[ ptr[newj + 1] + newi - newj ] = v;
                        } else if (newi == newj) {
                            D[newi] = v;
                        } else /* newi > newj */ {
                            L[ ptr[newi + 1] + newj - newi ] = v;
                        }
                    }
                }
            }

            factorize();
        }