예제 #1
0
void Relationship::assertSingular(bool singular) const {
  if (singular) {
    if (!isSingular()) {
      LOG_AND_THROW("Relationship named '" << m_name << "', and associated with ModelObject" << 
        m_object.briefDescription() << ", is singular but is being used in a plural contex.");
    }
  } else {
    if (isSingular()) {
      LOG_AND_THROW("Relationship named '" << m_name << "', and associated with ModelObject" << 
        m_object.briefDescription() << ", is plural but is being used in a singular contex.");
    }    
  }
}
예제 #2
0
파일: affine.cpp 프로젝트: Spin0za/inkscape
/** @brief Check whether this matrix represents pure, nonzero uniform scaling.
 * @param eps Numerical tolerance
 * @return True iff the matrix is of the form
 *         \f$\left[\begin{array}{ccc}
           a_1 & 0 & 0 \\
           0 & a_2 & 0 \\
           0 & 0 & 1 \end{array}\right]\f$ where \f$|a_1| = |a_2|\f$
 * and \f$a_1, a_2 \neq 1\f$. */
bool Affine::isNonzeroUniformScale(Coord eps) const {
    if (isSingular(eps)) return false;
    // we need to test both c0 and c3 to handle the case of flips,
    // which should be treated as nonzero uniform scales
    return !(are_near(_c[0], 1.0, eps) && are_near(_c[3], 1.0, eps)) &&
           are_near(fabs(_c[0]), fabs(_c[3]), eps) &&
           are_near(_c[1], 0.0, eps) && are_near(_c[2], 0.0, eps) &&  
           are_near(_c[4], 0.0, eps) && are_near(_c[5], 0.0, eps);
}
예제 #3
0
void ImplicitFunctionInternal::init(){
  // Initialize the residual function
  if(!f_.isInit()) f_.init();
  
  // Allocate inputs
  setNumInputs(f_.getNumInputs()-1);
  for(int i=0; i<getNumInputs(); ++i){
    input(i) = f_.input(i+1);
  }
  
  // Allocate outputs
  setNumOutputs(f_.getNumOutputs());
  output(0) = f_.input(0);
  for(int i=1; i<getNumOutputs(); ++i){
    output(i) = f_.output(i);
  }

  // Call the base class initializer
  FXInternal::init();

  // Number of equations
  N_ = output().size();

  // Generate Jacobian if not provided
  if(J_.isNull()) J_ = f_.jacobian(0,0);
  J_.init();
  
  casadi_assert_message(J_.output().size1()==J_.output().size2(),"ImplicitFunctionInternal::init: the jacobian must be square but got " << J_.output().dimString());
  
  casadi_assert_message(!isSingular(J_.output().sparsity()),"ImplicitFunctionInternal::init: singularity - the jacobian is structurally rank-deficient. sprank(J)=" << sprank(J_.output()) << " (in stead of "<< J_.output().size1() << ")");
  
  // Get the linear solver creator function
  if(linsol_.isNull() && hasSetOption("linear_solver")){
    linearSolverCreator linear_solver_creator = getOption("linear_solver");
  
    // Allocate an NLP solver
    linsol_ = linear_solver_creator(CRSSparsity());
  
    // Pass options
    if(hasSetOption("linear_solver_options")){
      const Dictionary& linear_solver_options = getOption("linear_solver_options");
      linsol_.setOption(linear_solver_options);
    }
  }
  
  // Initialize the linear solver, if provided
  if(!linsol_.isNull()){
    linsol_.setSparsity(J_.output().sparsity());
    linsol_.init();
  }
    
  // Allocate memory for directional derivatives
  ImplicitFunctionInternal::updateNumSens(false);

}
예제 #4
0
bool containsZero(const IntervalObject& v)
{

  typename IntervalObject::const_iterator b = v.begin(), e=v.end();
  while(b!=e)
  {
    if(!(isSingular(*b)))
      return false;
    ++b;
  }
  return true;
}
예제 #5
0
  void CSparseCholeskyInternal::prepare(){

    prepared_ = false;
  
    // Get a reference to the nonzeros of the linear system
    const vector<double>& linsys_nz = input().data();
  
    // Make sure that all entries of the linear system are valid
    for(int k=0; k<linsys_nz.size(); ++k){
      casadi_assert_message(!isnan(linsys_nz[k]),"Nonzero " << k << " is not-a-number");
      casadi_assert_message(!isinf(linsys_nz[k]),"Nonzero " << k << " is infinite");
    }
  
    if(verbose()){
      cout << "CSparseCholeskyInternal::prepare: numeric factorization" << endl;
      cout << "linear system to be factorized = " << endl;
      input(0).printSparse();
    }
  
    if(L_) cs_nfree(L_);
    L_ = cs_chol(&AT_, S_) ;                 // numeric Cholesky factorization 
    if(L_==0){
      DMatrix temp = input();
      makeSparse(temp);
      if (isSingular(temp.sparsity())) {
        stringstream ss;
        ss << "CSparseCholeskyInternal::prepare: factorization failed due to matrix being singular. Matrix contains numerical zeros which are structurally non-zero. Promoting these zeros to be structural zeros, the matrix was found to be structurally rank deficient. sprank: " << rank(temp.sparsity()) << " <-> " << temp.size1() << endl;
        if(verbose()){
          ss << "Sparsity of the linear system: " << endl;
          input(LINSOL_A).sparsity().print(ss); // print detailed
        }
        throw CasadiException(ss.str());
      } else {
        stringstream ss;
        ss << "CSparseCholeskyInternal::prepare: factorization failed, check if Jacobian is singular" << endl;
        if(verbose()){
          ss << "Sparsity of the linear system: " << endl;
          input(LINSOL_A).sparsity().print(ss); // print detailed
        }
        throw CasadiException(ss.str());
      }
    }
    casadi_assert(L_!=0);

    prepared_ = true;
  }
예제 #6
0
  int DA_blockPartStage2(std::vector<TreeNode> &nodes, std::vector<TreeNode> &globalCoarse,
      unsigned int dim, unsigned int maxDepth, MPI_Comm commActive) {
#ifdef __PROF_WITH_BARRIER__
    MPI_Barrier(commActive);
#endif
    PROF_BLKPART2_BEGIN

      int npesActive, rankActive;

    MPI_Comm_rank(commActive, &rankActive);
    MPI_Comm_size(commActive, &npesActive);

    int *sendCnt = new int[npesActive];
    int *recvCnt = new int[npesActive];
    int *sendOffsets = new int[npesActive];
    int *recvOffsets = new int[npesActive];

    //1. Now compute the wts of these cells ...
    //    a. Get the min and max nodes at each processor.
    std::vector<TreeNode> _mins_maxs(2*npesActive);

    // communicate ...
    TreeNode sendMinMax[2];
    TreeNode rootNode (dim,maxDepth);

    if (!nodes.empty()) {
      sendMinMax[0] =  nodes[0];
      sendMinMax[1] =  nodes[nodes.size()-1];
    } else {
      sendMinMax[0] = rootNode;
      sendMinMax[1] = rootNode;
    }

    par::Mpi_Allgather<ot::TreeNode>(sendMinMax, &(*_mins_maxs.begin()), 2, commActive);

    std::vector<std::vector<TreeNode> > sendNodes(npesActive);
    std::vector<std::vector<unsigned int> > keymap(npesActive);

    for (int i = 0; i < npesActive; i++) {
      sendCnt[i] = 0;
      sendNodes[i].clear();
      keymap[i].clear();	
    }

    //    b. Now compute which cells go to which cells ...
    //       logic is that if the coarse cell is between the min and max at a
    //       processor or if it is an ancestor of min, then it is sent to that
    //       processor.
    //Naive Logic:
    for (unsigned int i = 0; i < globalCoarse.size(); i++) {
      for (int p = 0; p < npesActive; p++) {
        if ( (globalCoarse[i].isAncestor(_mins_maxs[2*p])) ||
            ( (globalCoarse[i] >= _mins_maxs[2*p]) &&
              (globalCoarse[i] <=_mins_maxs[(2*p)+1]) ) ) {
          sendNodes[p].push_back(globalCoarse[i]);
          // save keymap so that we can assign weights back to globalCoarse.
          keymap[p].push_back(i);    
          sendCnt[p]++;
        }//end if
      }//end for
    }//end for

    _mins_maxs.clear();

    //2. Send nodes to all cells to compute the wts ... locally ...

    //    a. Communicate how many you'll be sending and how many will be
    //       received.

    // Now do an All2All to get numKeysRecv
    par::Mpi_Alltoall<int>( sendCnt, recvCnt, 1, commActive);

    //    b. Concatenate all nodes into one single Carray ...
    unsigned int totalSend = 0;
    unsigned int totalRecv = 0;
    for (unsigned int i = 0; i < npesActive; i++) {
      totalSend+= sendCnt[i];
      totalRecv+= recvCnt[i];
    }

    // create the send and recv buffers ...
    std::vector<ot::TreeNode> sendK (totalSend);
    std::vector<ot::TreeNode> recvK (totalRecv);

    // Now create sendK
    sendOffsets[0] = 0;
    recvOffsets[0] = 0;

    // compute offsets ...
    for (int i = 1; i < npesActive; i++) {
      sendOffsets[i] = sendOffsets[i-1] + sendCnt[i-1];
      recvOffsets[i] = recvOffsets[i-1] + recvCnt[i-1];
    }

    for (int i = 0; i < npesActive; i++) {
#ifdef __DEBUG_DA__
      assert( sendCnt[i]  == sendNodes[i].size() );
#endif
      for (unsigned int j=0; j<sendCnt[i]; j++) {
#ifdef __DEBUG_DA__
        assert( (sendOffsets[i] + j) < totalSend);
#endif
        sendK[sendOffsets[i] + j] = sendNodes[i][j];
      }//end for j
    }//end for i

    //3. send and receive all keys ...

    ot::TreeNode* sendKptr = NULL;
    ot::TreeNode* recvKptr = NULL;
    if(!sendK.empty()) {
      sendKptr = &(*(sendK.begin()));
    }
    if(!recvK.empty()) {
      recvKptr = &(*(recvK.begin()));
    }
    par::Mpi_Alltoallv_sparse<ot::TreeNode>( sendKptr, sendCnt, sendOffsets,
        recvKptr, recvCnt, recvOffsets, commActive);

    sendK.clear();

    //4. Now compute the wts of the locally received nodes ...
    //    a. loop through nodes and update the wts of the local chunks ...
    unsigned int *wts = NULL;
    char * isAnchorHanging = NULL;
    if(totalRecv) {
      wts = new unsigned int [totalRecv];
      isAnchorHanging = new char [totalRecv];
    }

    for (unsigned int i = 0; i < totalRecv; i++) {
      wts[i] = 0;
      isAnchorHanging[i] = 0;
    }

    //decendants and chunks are both sorted at this point.
    unsigned int nextPt = 0;
    unsigned int nextNode = 0;
    //Every element in nodes is inside some element in recvK.
    while (nextPt < nodes.size()) {
      //The first pt. lies in some block.
#ifdef __DEBUG_DA__
      assert(nextNode < recvK.size());
#endif
      if ((recvK[nextNode].isAncestor(nodes[nextPt])) ||
          (recvK[nextNode] == nodes[nextPt])) {
        wts[nextNode]++;
        if( (recvK[nextNode].getAnchor() == nodes[nextPt].getAnchor()) &&
            (!(nodes[nextPt].getFlag() & ot::TreeNode::NODE)) ) {
          isAnchorHanging[nextNode] = 1;
#ifdef __DEBUG_DA__
          //Only singular blocks can have hanging anchors
          assert(recvK[nextNode] == nodes[nextPt]);
#endif
        }
        nextPt++;
      } else {
        nextNode++;
        if (nextNode >= totalRecv) {
          //If this fails then either recvK and nodes are not sorted or
          //Some pt in nodes is not in any of recvK
          assert(false);
        }
      }//end if-else
    }//end while

    recvK.clear();

    //5. Now communicate the wts back to the procs ...
    unsigned int *recvWts = NULL;
    char *recvChars = NULL;
    if(totalSend) {
      recvWts = new unsigned int[totalSend];
      recvChars = new char[totalSend];
    }

    par::Mpi_Alltoallv_sparse<unsigned int>( wts, recvCnt, recvOffsets, 
        recvWts, sendCnt, sendOffsets,  commActive);

    par::Mpi_Alltoallv_sparse<char>( isAnchorHanging, recvCnt, recvOffsets, 
        recvChars, sendCnt, sendOffsets, commActive);

    //6. Now map them back to the blocks ...
    std::vector<bool> isSingular(globalCoarse.size());
    for (int i = 0; i < globalCoarse.size(); i++) {
      globalCoarse[i].setWeight(0);
      isSingular[i] = false;
    }

    for (int i = 0; i < npesActive; i++) {
      for (int j = 0; j < sendCnt[i]; j++) {
#ifdef __DEBUG_DA__
        assert(j < keymap[i].size());
        assert(keymap[i][j] < globalCoarse.size());
        assert( (sendOffsets[i] + j) < totalSend );
#endif
        globalCoarse[keymap[i][j]].addWeight(recvWts[sendOffsets[i] + j]);
        isSingular[keymap[i][j]] = ( isSingular[keymap[i][j]] ||
            recvChars[sendOffsets[i] + j]  );
      }//end for j
    }//end for i

    for (unsigned int i = 0; i < npesActive; i++) {
      keymap[i].clear();
      sendNodes[i].clear();
    }//end for i

    sendNodes.clear();
    keymap.clear();

    if(recvWts) {
      delete [] recvWts;
      recvWts = NULL;
    }

    if(recvChars) {
      delete [] recvChars;
      recvChars = NULL;
    }

    if(wts) {
      delete [] wts;
      wts = NULL;
    }

    if(isAnchorHanging) {
      delete [] isAnchorHanging;
      isAnchorHanging = NULL;
    }

    if(npesActive > 1) {
      //For DA only.....
      //Pick singular blocks on this processor...
      std::vector<ot::TreeNode> singularBlocks;
      for(unsigned int i=0;i<globalCoarse.size(); i++) {
        if(isSingular[i]) {
          singularBlocks.push_back(globalCoarse[i]);
        }
      }//end for i

      //Gather all singular blocks on all processors.
      std::vector<int> numSingular(npesActive);
      std::vector<int> singularDisps(npesActive);

      int singularSz = singularBlocks.size();

      par::Mpi_Allgather<int>(&singularSz, &(*numSingular.begin()), 1, commActive);

      unsigned int totSingular = 0;
      for(int i = 0; i < npesActive; i++) {
        totSingular += numSingular[i];
      }

      std::vector<TreeNode> allSingular(totSingular);

      singularDisps[0] = 0;
      for (unsigned int i=1; i < npesActive; i++) {
        singularDisps[i] = singularDisps[i-1] + numSingular[i-1];
      }

      ot::TreeNode* singularBlocksPtr = NULL;
      ot::TreeNode* allSingularPtr = NULL;
      if(!singularBlocks.empty()) {
        singularBlocksPtr = &(*(singularBlocks.begin()));
      }
      if(!allSingular.empty()) {
        allSingularPtr = &(*(allSingular.begin()));
      }
      par::Mpi_Allgatherv<ot::TreeNode>(singularBlocksPtr, singularSz,
          allSingularPtr, &(*numSingular.begin()), &(*singularDisps.begin()), commActive);

      singularBlocks.clear();
      numSingular.clear();
      singularDisps.clear();

#ifdef __DEBUG_DA__
      MPI_Barrier(commActive);
      assert(seq::test::isUniqueAndSorted(allSingular));
      assert(par::test::isUniqueAndSorted(globalCoarse, commActive));
      MPI_Barrier(commActive);
#endif

      //Loop through globalCoarse and set wts of all elements in between some
      //singular Block's parent and the singular Block to 0. So that the global
      //scan of all these elements in partW is the same and hence they will be
      //sent to the same processor...
      unsigned int lastIdxFound = (globalCoarse.size() -1);
      for(int singCnt = (allSingular.size()-1); singCnt >= 0; singCnt--) {
        unsigned int idxMLB;          
        bool foundMLB = seq::maxLowerBound<ot::TreeNode>(globalCoarse, 
            allSingular[singCnt], idxMLB, NULL, &lastIdxFound);
        if(foundMLB) {
          ot::TreeNode requiredOct = allSingular[singCnt].getParent().getDFD().
            getAncestor(allSingular[singCnt].getLevel());
          while(globalCoarse[idxMLB] > requiredOct) {
            globalCoarse[idxMLB].setWeight(0);
            if(idxMLB > 0) {
              idxMLB--;
            }else {
              break;
            }              
          }
          lastIdxFound = idxMLB;
          while( (singCnt >= 0) && (allSingular[singCnt] > requiredOct) ) {
            singCnt--;
          }
          singCnt++;
        }else {
          break;
        }//end if found
      }//end for i

      allSingular.clear();
    }//end if npes > 1

    isSingular.clear();

    par::partitionW<ot::TreeNode>(globalCoarse, getNodeWeight, commActive);

    //Reset weights
    for (unsigned int i=0;i<globalCoarse.size(); i++) {
      globalCoarse[i].setWeight(1);
    }

    // clean up ...
    delete [] sendCnt;
    sendCnt = NULL;

    delete [] recvCnt;
    recvCnt = NULL;

    delete [] sendOffsets;
    sendOffsets = NULL;

    delete [] recvOffsets;
    recvOffsets = NULL;

    PROF_BLKPART2_END
  } // end blockPart
예제 #7
0
/**
 * Returns the inverse of the matrix.  This method makes sure that the
 * matrix can be inverted by verifying that the matrix is not singular.
 * @return A new matrix which is the inverse of the original.
 */
gmMatrix4 gmMatrix4::inverse() const
{
  assert(!isSingular());
  return adjoint() * gmInv(determinant());
}
예제 #8
0
파일: plane.cpp 프로젝트: rizar/rizar-3d
qreal Plane::calculateZ(qreal x, qreal y) {
    Q_ASSERT(!isSingular());
    return a * x + b * y + c;
}
예제 #9
0
파일: affine.cpp 프로젝트: Spin0za/inkscape
/** @brief Check whether the transformation preserves angles between lines.
 * This means that the transformation can be any combination of translation, uniform scaling,
 * rotation and flipping.
 * @param eps Numerical tolerance
 * @return True iff the matrix is of the form
 *         \f$\left[\begin{array}{ccc}
             a & b & 0 \\
             -b & a & 0 \\
             c & d & 1 \end{array}\right]\f$ or
           \f$\left[\begin{array}{ccc}
             -a & b & 0 \\
             b & a & 0 \\
             c & d & 1 \end{array}\right]\f$. */
bool Affine::preservesAngles(Coord eps) const
{
    if (isSingular(eps)) return false;
    return (are_near(_c[0], _c[3], eps) && are_near(_c[1], -_c[2], eps)) ||
           (are_near(_c[0], -_c[3], eps) && are_near(_c[1], _c[2], eps));
}
예제 #10
0
파일: affine.cpp 프로젝트: Spin0za/inkscape
/** @brief Check whether this matrix represents zooming.
 * Zooming is any combination of translation and uniform non-flipping scaling.
 * It preserves angles, ratios of distances between arbitrary points
 * and unit vectors of line segments.
 * @param eps Numerical tolerance
 * @return True iff the matrix is invertible and of the form
 *         \f$\left[\begin{array}{ccc}
           a & 0 & 0 \\
           0 & a & 0 \\
           b & c & 1 \end{array}\right]\f$. */
bool Affine::isZoom(Coord eps) const {
    if (isSingular(eps)) return false;
    return are_near(_c[0], _c[3], eps) && are_near(_c[1], 0, eps) && are_near(_c[2], 0, eps);
}
예제 #11
0
파일: affine.cpp 프로젝트: Spin0za/inkscape
/** @brief Check whether this matrix represents pure uniform scaling.
 * @param eps Numerical tolerance
 * @return True iff the matrix is of the form
 *         \f$\left[\begin{array}{ccc}
           a_1 & 0 & 0 \\
           0 & a_2 & 0 \\
           0 & 0 & 1 \end{array}\right]\f$ where \f$|a_1| = |a_2|\f$. */
bool Affine::isUniformScale(Coord eps) const {
    if (isSingular(eps)) return false;
    return are_near(fabs(_c[0]), fabs(_c[3]), eps) &&
           are_near(_c[1], 0.0, eps) && are_near(_c[2], 0.0, eps) &&  
           are_near(_c[4], 0.0, eps) && are_near(_c[5], 0.0, eps);
}
예제 #12
0
파일: affine.cpp 프로젝트: Spin0za/inkscape
/** @brief Check whether this matrix represents pure, nonzero scaling.
 * @param eps Numerical tolerance
 * @return True iff the matrix is of the form
 *         \f$\left[\begin{array}{ccc}
           a & 0 & 0 \\
           0 & b & 0 \\
           0 & 0 & 1 \end{array}\right]\f$ and \f$a, b \neq 1\f$. */
bool Affine::isNonzeroScale(Coord eps) const {
    if (isSingular(eps)) return false;
    return (!are_near(_c[0], 1.0, eps) || !are_near(_c[3], 1.0, eps)) &&  //NOTE: these are the diags, and the next line opposite diags
           are_near(_c[1], 0.0, eps) && are_near(_c[2], 0.0, eps) && 
           are_near(_c[4], 0.0, eps) && are_near(_c[5], 0.0, eps);
}
예제 #13
0
파일: affine.cpp 프로젝트: Spin0za/inkscape
/** @brief Check whether this matrix represents pure scaling.
 * @param eps Numerical tolerance
 * @return True iff the matrix is of the form
 *         \f$\left[\begin{array}{ccc}
           a & 0 & 0 \\
           0 & b & 0 \\
           0 & 0 & 1 \end{array}\right]\f$. */
bool Affine::isScale(Coord eps) const {
    if (isSingular(eps)) return false;
    return are_near(_c[1], 0.0, eps) && are_near(_c[2], 0.0, eps) && 
           are_near(_c[4], 0.0, eps) && are_near(_c[5], 0.0, eps);
}