Пример #1
0
static void EigsOfSymMat(
    MAT&       eigvecs,        // out: one row per eigvec
    MAT&       eigvals,        // out: sorted
    const MAT& mat,            // in: not modified
    bool       fix_signs=true) // in: see FixEigSigns
{
    CV_DbgAssert(IsSymmetric(mat, cv::trace(mat)[0] / double(1e16)));
    eigen(mat, eigvals, eigvecs);
    if (fix_signs)
        FixEigSigns(eigvecs);
}
Пример #2
0
    GenExpTLVec*
    CFGEnumeratorSingle::PopulateExpsOfGNCost(const GrammarNode* GN, uint32 Cost, bool Complete)
    {
        auto Retval = new GenExpTLVec();
        GNCostPair Key(GN, Cost);
        Done = false;
        auto Type = GN->GetType();
        PushExpansion(GN->ToString());
        auto const ExpansionTypeID = GetExpansionTypeID();

        auto FPVar = GN->As<GrammarFPVar>();
        // The base cases
        if (FPVar != nullptr) {
            return MakeBaseExpression<GenFPExpression>(Retval, FPVar->GetOp(), Type,
                                                       ExpansionTypeID, Cost, Key, Complete);
        }

        auto LetVar = GN->As<GrammarLetVar>();
        if (LetVar != nullptr) {
            return MakeBaseExpression<GenLetVarExpression>(Retval, LetVar->GetOp(), Type,
                                                           ExpansionTypeID, Cost, Key, Complete);
        }

        auto Const = GN->As<GrammarConst>();
        if (Const != nullptr) {
            return MakeBaseExpression<GenConstExpression>(Retval, Const->GetOp(), Type,
                                                          ExpansionTypeID, Cost, Key, Complete);
        }

        auto Func = GN->As<GrammarFunc>();

        if (Func != nullptr) {
            auto const& Args = Func->GetChildren();
            auto Op = Func->GetOp();
            const uint32 OpCost = Op->GetCost();
            const uint32 Arity = Op->GetArity();

            if (Cost < Arity + OpCost) {
                Retval->Freeze();
                ExpRepository[Key] = Retval;
                PopExpansion();
                return Retval;
            }
            PartitionGenerator* PG;
            if (Op->IsSymmetric() && Args[0] == Args[1]) {
                PG = new SymPartitionGenerator(Cost - OpCost);
            } else {
                PG = new PartitionGenerator(Cost - OpCost, Arity);
            }

            const uint32 NumPartitions = PG->Size();
            for (uint32 i = 0; i < NumPartitions; ++i) {

                auto Feasible = true;
                vector<const GenExpTLVec*> ArgExpVecs(Arity, nullptr);
                auto CurPartition = (*PG)[i];
                vector<GenExpTLVec::ConstIterator> Begins(Arity);
                vector<GenExpTLVec::ConstIterator> Ends(Arity);

                for (uint32 j = 0; j < Arity; ++j) {
                    auto CurVec = GetVecForGNCost(Args[j], CurPartition[j]);
                    if (CurVec == nullptr) {
                        CurVec = PopulateExpsOfGNCost(Args[j], CurPartition[j], false);
                    }
                    if (CurVec->Size() == 0) {
                        Feasible = false;
                        break;
                    } else {
                        ArgExpVecs[j] = CurVec;
                        Begins[j] = CurVec->Begin();
                        Ends[j] = CurVec->End();
                    }
                }

                if (!Feasible) {
                    continue;
                }

                // Iterate over the cross product
                auto CPGen = new CrossProductGenerator(Begins, Ends, GetPoolForSize(Arity));

                for (auto CurArgs = CPGen->GetNext();
                     CurArgs != nullptr;
                     CurArgs = CPGen->GetNext()) {

                    auto CurExp = new (FuncExpPool->malloc())
                        GenFuncExpression(static_cast<const InterpretedFuncOperator*>(Op), CurArgs);

                    auto Status =
                        (Complete ?
                         Solver->ExpressionCallBack(CurExp, Type, ExpansionTypeID, Index) :
                         Solver->SubExpressionCallBack(CurExp, Type, ExpansionTypeID));

                    if ((Status & DELETE_EXPRESSION) == 0) {
                        CPGen->RelinquishOwnerShip();
                        Retval->PushBack(CurExp);
                        NumExpsCached++;
                    } else {
                        FuncExpPool->free(CurExp);
                    }
                    if ((Status & STOP_ENUMERATION) != 0) {
                        Done = true;
                        break;
                    }
                }
                delete CPGen;
                if (Done) {
                    break;
                }
            }
            delete PG;

            Retval->Freeze();
            ExpRepository[Key] = Retval;
            PopExpansion();
            return Retval;
        }

        auto Let = GN->As<GrammarLet>();

        // We handle this in similar spirit as functions
        if (Let != nullptr) {
            auto const& Bindings = Let->GetBindings();
            const uint32 NumBindings = Bindings.size();
            const uint32 Arity = NumBindings + 1;
            auto BoundNode = Let->GetBoundExpression();
            const uint32 NumLetBoundVars = TheGrammar->GetNumLetBoundVars();

            if (Cost < Arity + 1) {
                Retval->Freeze();
                ExpRepository[Key] = Retval;
                PopExpansion();
                return Retval;
            }

            // Making a let binding incurs a cost of 1!
            auto PG = new PartitionGenerator(Cost - 1, Arity);
            const uint32 NumPartitions = PG->Size();
            for (uint32 i = 0; i < NumPartitions; ++i) {
                auto Feasible = true;
                vector<const GenExpTLVec*> ArgExpVecs(Arity, nullptr);
                auto CurPartition = (*PG)[i];
                vector<GenExpTLVec::ConstIterator> Begins(Arity);
                vector<GenExpTLVec::ConstIterator> Ends(Arity);

                uint32 j = 0;
                uint32* Positions = new uint32[NumBindings];

                for (auto it = Bindings.begin(); it != Bindings.end(); ++it) {
                    auto CurVec = GetVecForGNCost(it->second, CurPartition[j]);
                    if (CurVec == nullptr) {
                        CurVec = PopulateExpsOfGNCost(it->second, CurPartition[j], false);
                    }
                    if (CurVec->Size() == 0) {
                        Feasible = false;
                        break;
                    } else {
                        ArgExpVecs[j] = CurVec;
                        Begins[j] = CurVec->Begin();
                        Ends[j] = CurVec->End();
                    }
                    Positions[j] = it->first->GetOp()->GetPosition();
                    ++j;
                }

                if (!Feasible) {
                    delete[] Positions;
                    continue;
                }

                // Finally, the expression set for the bound expression
                auto BoundVec = GetVecForGNCost(BoundNode, CurPartition[j]);
                if (BoundVec == nullptr) {
                    BoundVec = PopulateExpsOfGNCost(BoundNode, CurPartition[j], false);
                }
                if (BoundVec->Size() == 0) {
                    // cross product is empty not feasible
                    delete[] Positions;
                    continue;
                } else {
                    ArgExpVecs[NumBindings] = BoundVec;
                    Begins[NumBindings] = BoundVec->Begin();
                    Ends[NumBindings] = BoundVec->End();
                }


                // Iterate over the cross product of expressions
                // The bindings object will be of size of the NUMBER
                // of let bound vars for the whole grammar
                auto CPGen = new CrossProductGenerator(Begins, Ends,
                                                       GetPoolForSize(Arity));
                GenExpressionBase const** BindVec = nullptr;
                auto BindVecPool = GetPoolForSize(NumLetBoundVars);

                for (auto CurArgs = CPGen->GetNext(); CurArgs != nullptr; CurArgs = CPGen->GetNext()) {
                    // We need to build the binding vector based on the position
                    if (BindVec == nullptr) {
                        BindVec = (GenExpressionBase const**)BindVecPool->malloc();
                        memset(BindVec, 0, sizeof(GenExpressionBase const*) * NumLetBoundVars);
                    }
                    for (uint32 k = 0; k < NumBindings; ++k) {
                        BindVec[Positions[k]] = CurArgs[k];
                    }

                    auto CurExp = new (LetExpPool->malloc())
                        GenLetExpression(BindVec, CurArgs[NumBindings], NumLetBoundVars);
                    auto Status =
                        (Complete ?
                         Solver->ExpressionCallBack(CurExp, Type, ExpansionTypeID, Index) :
                         Solver->SubExpressionCallBack(CurExp, Type, ExpansionTypeID));

                    if ((Status & DELETE_EXPRESSION) == 0) {
                        BindVec = nullptr;
                        Retval->PushBack(CurExp);
                        NumExpsCached++;
                    } else {
                        LetExpPool->free(CurExp);
                    }
                    if ((Status & STOP_ENUMERATION) != 0) {
                        Done = true;
                        break;
                    }
                }

                delete CPGen;
                delete[] Positions;

                if (Done) {
                    break;
                }
            }

            delete PG;

            Retval->Freeze();
            ExpRepository[Key] = Retval;
            PopExpansion();
            return Retval;
        }

        auto NT = GN->As<GrammarNonTerminal>();
        if (NT != nullptr) {
            const vector<GrammarNode*>& Expansions = TheGrammar->GetExpansions(NT);
            for (auto const& Expansion : Expansions) {
                auto CurVec = GetVecForGNCost(Expansion, Cost);
                if (CurVec == nullptr) {
                    CurVec = PopulateExpsOfGNCost(Expansion, Cost, Complete);
                }
                Retval->Merge(*CurVec);
                if (Done) {
                    break;
                }
            }
            Retval->Freeze();
            ExpRepository[Key] = Retval;
            PopExpansion();
            return Retval;
        }

        // Should NEVER get here
        throw InternalError((string)"You probably subclassed GrammarNode and forgot to change " +
                            "CFGEnumerator.cpp.\nAt: " + __FILE__ + ":" + to_string(__LINE__));
    }
Пример #3
0
inline void
NestedDissectionRecursion
( const Graph& graph, 
  const vector<Int>& perm,
        Separator& sep, 
        NodeInfo& node,
        Int off, 
  const BisectCtrl& ctrl )
{
    DEBUG_CSE
    const Int numSources = graph.NumSources();
    const Int* offsetBuf = graph.LockedOffsetBuffer();
    const Int* sourceBuf = graph.LockedSourceBuffer();
    const Int* targetBuf = graph.LockedTargetBuffer();
    if( numSources <= ctrl.cutoff )
    {
        // Filter out the graph of the diagonal block
        Int numValidEdges = 0;
        const Int numEdges = graph.NumEdges();
        for( Int e=0; e<numEdges; ++e )
            if( targetBuf[e] < numSources )
                ++numValidEdges;
        vector<Int> subOffsets(numSources+1), subTargets(Max(numValidEdges,1));
        Int sourceOff = 0;
        Int validCounter = 0;
        Int prevSource = -1;
        for( Int e=0; e<numEdges; ++e )
        {
            const Int source = sourceBuf[e]; 
            const Int target = targetBuf[e];
            while( source != prevSource )
            {
                subOffsets[sourceOff++] = validCounter;
                ++prevSource;
            }
            if( target < numSources )
                subTargets[validCounter++] = target;
        }
        while( sourceOff <= numSources )
        { subOffsets[sourceOff++] = validCounter; }

        // Technically, SuiteSparse expects column-major storage, but since
        // the matrix is structurally symmetric, it's okay to pass in the 
        // row-major representation
        vector<Int> amdPerm;
        AMDOrder( subOffsets, subTargets, amdPerm );

        // Compute the symbolic factorization of this leaf node using the
        // reordering just computed
        node.LOffsets.resize( numSources+1 );
        node.LParents.resize( numSources );
        vector<Int> LNnz( numSources ), Flag( numSources ), 
                    amdPermInv( numSources );
        suite_sparse::ldl::Symbolic 
        ( numSources, subOffsets.data(), subTargets.data(), 
          node.LOffsets.data(), node.LParents.data(), LNnz.data(),
          Flag.data(), amdPerm.data(), amdPermInv.data() );

        // Fill in this node of the local separator tree
        sep.off = off;
        sep.inds.resize( numSources );
        for( Int i=0; i<numSources; ++i )
            sep.inds[i] = perm[amdPerm[i]];
        // TODO: Replace with better deletion mechanism
        SwapClear( sep.children );

        // Fill in this node of the local elimination tree
        node.size = numSources;
        node.off = off;
        // TODO: Replace with better deletion mechanism
        SwapClear( node.children );
        set<Int> lowerStruct;
        for( Int s=0; s<node.size; ++s )
        {
            const Int edgeOff = offsetBuf[s];
            const Int numConn = offsetBuf[s+1] - edgeOff;
            for( Int t=0; t<numConn; ++t )
            {
                const Int target = targetBuf[edgeOff+t];
                if( target >= numSources )
                    lowerStruct.insert( off+target );
            }
        }
        CopySTL( lowerStruct, node.origLowerStruct );
    }
    else
    {
        DEBUG_ONLY(
          if( !IsSymmetric(graph) )
          {
              Print( graph, "graph" );
              LogicError("Graph was not symmetric");
          }
        )

        // Partition the graph and construct the inverse map
        Graph leftChild, rightChild;
        vector<Int> map;
        const Int sepSize = Bisect( graph, leftChild, rightChild, map, ctrl );
        vector<Int> invMap( numSources );
        for( Int s=0; s<numSources; ++s )
            invMap[map[s]] = s;

        DEBUG_ONLY(
          if( !IsSymmetric(leftChild) )
          {
              Print( graph, "graph" );
              Print( leftChild, "leftChild" );
              LogicError("Left child was not symmetric");
          }
        )
Пример #4
0
bool Eigendecomposition(const Matrix4& A,Vector4& lambda,Matrix4& Q)
{
  if(!IsSymmetric(A)) return false;
  Matrix4 U;
  return SVD(A,U,lambda,Q);
}