ValueInt<Base<F>> InverseFreeSignDivide( ElementalMatrix<F>& XPre )
{
    DEBUG_CSE

    DistMatrixReadWriteProxy<F,F,MC,MR> XProx( XPre );
    auto& X = XProx.Get();

    typedef Base<F> Real;
    const Grid& g = X.Grid();
    const Int n = X.Width();
    if( X.Height() != 2*n )
        LogicError("Matrix should be 2n x n");
   
    // Expose A and B, and then copy A
    auto B = X( IR(0,n  ), ALL );
    auto A = X( IR(n,2*n), ALL );
    DistMatrix<F> ACopy( A );

    // Run the inverse-free alternative to Sign
    InverseFreeSign( X );

    // Compute the pivoted QR decomp of inv(A + B) A [See LAWN91]
    // 1) B := A + B 
    // 2) [Q,R,Pi] := QRP(A)
    // 3) B := Q^H B
    // 4) [R,Q] := RQ(B)
    B += A;
    DistMatrix<F,MD,STAR> t(g);
    DistMatrix<Base<F>,MD,STAR> d(g);
    DistMatrix<Int,VR,STAR> p(g);
    QR( A, t, d, p );
    qr::ApplyQ( LEFT, ADJOINT, A, t, d, B );
    RQ( B, t, d );

    // A := Q^H A Q
    A = ACopy;
    rq::ApplyQ( LEFT, ADJOINT, B, t, d, A );
    rq::ApplyQ( RIGHT, NORMAL, B, t, d, A );

    // Return || E21 ||1 / || A ||1
    // Return || E21 ||1 / || A ||1
    ValueInt<Real> part = ComputePartition( A );
    part.value /= OneNorm(ACopy);
    return part;
}
Base<F> InverseFreeSignDivide( Matrix<F>& X )
{
    DEBUG_CSE
    typedef Base<F> Real;
    const Int n = X.Width();
    if( X.Height() != 2*n )
        LogicError("Matrix should be 2n x n");
   
    // Expose A and B, and then copy A
    auto B = X( IR(0,n  ), ALL );
    auto A = X( IR(n,2*n), ALL );
    Matrix<F> ACopy( A );

    // Run the inverse-free alternative to Sign
    InverseFreeSign( X );

    // Compute the pivoted QR decomp of inv(A + B) A [See LAWN91]
    // 1) B := A + B 
    // 2) [Q,R,Pi] := QRP(A)
    // 3) B := Q^H B
    // 4) [R,Q] := RQ(B)
    B += A;
    Matrix<F> t;
    Matrix<Base<F>> d;
    Matrix<Int> p;
    QR( A, t, d, p );
    qr::ApplyQ( LEFT, ADJOINT, A, t, d, B );
    RQ( B, t, d );

    // A := Q^H A Q
    A = ACopy;
    rq::ApplyQ( LEFT, ADJOINT, B, t, d, A );
    rq::ApplyQ( RIGHT, NORMAL, B, t, d, A );

    // Return || E21 ||1 / || A ||1
    ValueInt<Real> part = ComputePartition( A );
    part.value /= OneNorm(ACopy);
    return part;
}
Exemple #3
0
inline ValueInt<BASE(F)>
QDWHDivide
( UpperOrLower uplo, DistMatrix<F>& A, DistMatrix<F>& G, bool returnQ=false )
{
    DEBUG_ONLY(CallStackEntry cse("herm_eig::QDWHDivide"))

    // G := sgn(G)
    // G := 1/2 ( G + I )
    herm_polar::QDWH( uplo, G ); 
    UpdateDiagonal( G, F(1) );
    Scale( F(1)/F(2), G );

    // Compute the pivoted QR decomposition of the spectral projection 
    const Grid& g = A.Grid();
    DistMatrix<F,MD,STAR> t(g);
    DistMatrix<Int,VR,STAR> p(g);
    elem::QR( G, t, p );

    // A := Q^H A Q
    MakeHermitian( uplo, A );
    const Base<F> oneA = OneNorm( A );
    if( returnQ )
    {
        ExpandPackedReflectors( LOWER, VERTICAL, CONJUGATED, 0, G, t );
        DistMatrix<F> B(g);
        Gemm( ADJOINT, NORMAL, F(1), G, A, B );
        Gemm( NORMAL, NORMAL, F(1), B, G, A );
    }
    else
    {
        qr::ApplyQ( LEFT, ADJOINT, G, t, A );
        qr::ApplyQ( RIGHT, NORMAL, G, t, A );
    }

    // Return || E21 ||1 / || A ||1 and the chosen rank
    auto part = ComputePartition( A );
    part.value /= oneA;
    return part;
}
Exemple #4
0
static enum eExprErr ComputeExpr(char *expr, BigInteger *ExpressionResult)
{
  int i, shLeft;
  int retcode;
  limb carry;
  boolean leftNumberFlag = FALSE;
  int exprIndexAux, offset;
  enum eExprErr SubExprResult;
  int len;
  limb largeLen;
  limb *ptrLimb;
  BigInteger *pBigInt;
  int c;
  int startStackIndex = stackIndex;
  
  exprLength = (int)strlen(expr);
  while (exprIndex < exprLength)
  {
    char charValue;

    charValue = *(expr+exprIndex);
    if (charValue == ' ' || charValue == 9)
    {           // Ignore spaces and horizontal tabs.
      exprIndex++;
      continue;
    }
    if (charValue == '^')
    {           // Caret is exponentiation operation.
      charValue = OPER_POWER;
      exprIndex++;
    }
    else if (charValue == '*' && *(expr + exprIndex + 1) == '*')
    {           // Double asterisk is exponentiation operation too.
      charValue = OPER_POWER;
      exprIndex += 2;
    }
    else if (charValue == '*')
    {
      charValue = OPER_MULTIPLY;
      exprIndex++;
    }
    else if (charValue == '/')
    {
      charValue = OPER_DIVIDE;
      exprIndex++;
    }
    else if (charValue == '%')
    {
      charValue = OPER_REMAINDER;
      exprIndex++;
    }
    else if (charValue == '+')
    {
      charValue = OPER_PLUS;
      exprIndex++;
    }
    else if (charValue == '-')
    {
      charValue = OPER_MINUS;
      exprIndex++;
    }
    else if (charValue == '<' && *(expr + exprIndex + 1) == '=')
    {
      charValue = OPER_NOT_GREATER;
      exprIndex += 2;
    }
    else if (charValue == '>' && *(expr + exprIndex + 1) == '=')
    {
      charValue = OPER_NOT_LESS;
      exprIndex += 2;
    }
    else if (charValue == '!' && *(expr + exprIndex + 1) == '=')
    {
      charValue = OPER_NOT_EQUAL;
      exprIndex += 2;
    }
    else if (charValue == '=' && *(expr + exprIndex + 1) == '=')
    {
      charValue = OPER_EQUAL;
      exprIndex += 2;
    }
    else if (charValue == '>')
    {
      charValue = OPER_GREATER;
      exprIndex++;
    }
    else if (charValue == '<')
    {
      charValue = OPER_LESS;
      exprIndex++;
    }
    else if ((charValue & 0xDF) == 'N' && (*(expr + exprIndex + 1) & 0xDF) == 'O' &&
      (*(expr + exprIndex + 2) & 0xDF) == 'T')
    {
      charValue = OPER_NOT;
      exprIndex += 3;
    }
    else if ((charValue & 0xDF) == 'A' && (*(expr + exprIndex + 1) & 0xDF) == 'N' &&
      (*(expr + exprIndex + 2) & 0xDF) == 'D')
    {
      charValue = OPER_AND;
      exprIndex += 3;
    }
    else if ((charValue & 0xDF) == 'O' && (*(expr + exprIndex + 1) & 0xDF) == 'R')
    {
      charValue = OPER_OR;
      exprIndex += 2;
    }
    else if ((charValue & 0xDF) == 'X' && (*(expr + exprIndex + 1) & 0xDF) == 'O' &&
      (*(expr + exprIndex + 2) & 0xDF) == 'R')
    {
      charValue = OPER_XOR;
      exprIndex += 3;
    }
    else if ((charValue & 0xDF) == 'S' && (*(expr + exprIndex + 1) & 0xDF) == 'H' &&
      (*(expr + exprIndex + 2) & 0xDF) == 'L')
    {
      charValue = OPER_SHL;
      exprIndex += 3;
    }
    else if ((charValue & 0xDF) == 'S' && (*(expr + exprIndex + 1) & 0xDF) == 'H' &&
      (*(expr + exprIndex + 2) & 0xDF) == 'R')
    {
      charValue = OPER_SHR;
      exprIndex += 3;
    }
    else if (charValue == '!')
    {           // Calculating factorial.
      if (leftNumberFlag == FALSE)
      {
        return EXPR_SYNTAX_ERROR;
      }
      if (stackValues[stackIndex].nbrLimbs > 1)
      {
        return EXPR_INTERM_TOO_HIGH;
      }
#ifdef FACTORIZATION_APP
      if (stackValues[stackIndex].limbs[0].x < 0 || stackValues[stackIndex].limbs[0].x >= 47177)
#else
      if (stackValues[stackIndex].limbs[0].x < 0 || stackValues[stackIndex].limbs[0].x >= 5984)
#endif
      {
        return EXPR_INTERM_TOO_HIGH;
      }
      factorial(&stackValues[stackIndex], (int)stackValues[stackIndex].limbs[0].x);
      exprIndex++;
      continue;
    }
    else if (charValue == '#')
    {           // Calculating primorial.
      if (leftNumberFlag == FALSE)
      {
        return EXPR_SYNTAX_ERROR;
      }
      if (stackValues[stackIndex].nbrLimbs > 2)
      {
        return EXPR_INTERM_TOO_HIGH;
      }
      if (stackValues[stackIndex].nbrLimbs == 2)
      {
        largeLen.x = stackValues[stackIndex].limbs[0].x +
             (stackValues[stackIndex].limbs[1].x << BITS_PER_GROUP);
      }
      else
      {
        largeLen.x = stackValues[stackIndex].limbs[0].x;
      }
      len = (int)largeLen.x;
#ifdef FACTORIZATION_APP
      if (len < 0 || len > 460490)
#else
      if (len < 0 || len > 46049)
#endif
      {
        return EXPR_INTERM_TOO_HIGH;
      }
      primorial(&stackValues[stackIndex], (int)stackValues[stackIndex].limbs[0].x);
      exprIndex++;
      continue;
    }
    else if ((retcode = func(expr, ExpressionResult,
      "GCD", 2, leftNumberFlag)) <= 0)
    {
      if (retcode != 0) { return retcode; }
      BigIntGcd(&stackValues[stackIndex], &stackValues[stackIndex + 1], &stackValues[stackIndex]);
      leftNumberFlag = 1;
      continue;
    }
    else if ((retcode = func(expr, ExpressionResult,
      "MODPOW", 3, leftNumberFlag)) <= 0)
    {
      if (retcode != 0) { return retcode; }
      retcode = BigIntGeneralModularPower(&stackValues[stackIndex], &stackValues[stackIndex + 1],
        &stackValues[stackIndex + 2], &stackValues[stackIndex]);
      if (retcode != 0) { return retcode; }
      leftNumberFlag = 1;
      continue;
    }
    else if ((retcode = func(expr, ExpressionResult,
      "MODINV", 2, leftNumberFlag)) <= 0)
    {
      if (retcode != 0) { return retcode; }
      retcode = ComputeModInv();
      if (retcode != 0) { return retcode; }
      leftNumberFlag = 1;
      continue;
    }
#ifdef FACTORIZATION_FUNCTIONS
    else if ((retcode = func(expr, ExpressionResult,
      "TOTIENT", 1, leftNumberFlag)) <= 0)
    {
      if (retcode != 0) { return retcode; }
      retcode = ComputeTotient();
      if (retcode != 0) { return retcode; }
      leftNumberFlag = 1;
      continue;
    }
    else if ((retcode = func(expr, ExpressionResult,
      "NUMDIVS", 1, leftNumberFlag)) <= 0)
    {
      if (retcode != 0) { return retcode; }
      retcode = ComputeNumDivs();
      if (retcode != 0) { return retcode; }
      leftNumberFlag = 1;
      continue;
    }
    else if ((retcode = func(expr, ExpressionResult,
      "SUMDIVS", 1, leftNumberFlag)) <= 0)
    {
      if (retcode != 0) { return retcode; }
      retcode = ComputeSumDivs();
      if (retcode != 0) { return retcode; }
      leftNumberFlag = 1;
      continue;
    }
    else if ((retcode = func(expr, ExpressionResult,
      "CONCATFACT", 2, leftNumberFlag)) <= 0)
    {
      if (retcode != 0) { return retcode; }
      retcode = ComputeConcatFact();
      if (retcode != 0) { return retcode; }
      leftNumberFlag = 1;
      continue;
    }
#endif
    else if ((retcode = func(expr, ExpressionResult,
      "SUMDIGITS", 2, leftNumberFlag)) <= 0)
    {
      if (retcode != 0) { return retcode; }
      retcode = ComputeSumDigits();
      if (retcode != 0) { return retcode; }
      leftNumberFlag = 1;
      continue;
    }
    else if ((retcode = func(expr, ExpressionResult,
      "NUMDIGITS", 2, leftNumberFlag)) <= 0)
    {
      if (retcode != 0) { return retcode; }
      retcode = ComputeNumDigits();
      if (retcode != 0) { return retcode; }
      leftNumberFlag = 1;
      continue;
    }
    else if ((retcode = func(expr, ExpressionResult,
      "REVDIGITS", 2, leftNumberFlag)) <= 0)
    {
      if (retcode != 0) { return retcode; }
      retcode = ComputeRevDigits();
      if (retcode != 0) { return retcode; }
      leftNumberFlag = 1;
      continue;
    }
    else if ((retcode = func(expr, ExpressionResult,
      "ISPRIME", 1, leftNumberFlag)) <= 0)
    {
      if (retcode != 0) { return retcode; }
#ifdef FACTORIZATION_APP
      if (BpswPrimalityTest(&stackValues[stackIndex], NULL) == 0)
#else
      if (BpswPrimalityTest(&stackValues[stackIndex]) == 0)
#endif
      {    // Argument is a probable prime.
        intToBigInteger(&stackValues[stackIndex], -1);
      }
      else
      {    // Argument is not a probable prime.
        intToBigInteger(&stackValues[stackIndex], 0);
      }
      leftNumberFlag = 1;
      continue;
    }
    else if ((retcode = func(expr, ExpressionResult,
      "F", 1, leftNumberFlag)) <= 0)
    {
      if (retcode != 0) { return retcode; }
      retcode = ComputeFibLucas(0);
      if (retcode != 0) { return retcode; }
      leftNumberFlag = 1;
      continue;
    }
    else if ((retcode = func(expr, ExpressionResult,
      "L", 1, leftNumberFlag)) <= 0)
    {
      if (retcode != 0) { return retcode; }
      retcode = ComputeFibLucas(2);
      if (retcode != 0) { return retcode; }
      leftNumberFlag = 1;
      continue;
    }
    else if ((retcode = func(expr, ExpressionResult,
      "P", 1, leftNumberFlag)) <= 0)
    {
      if (retcode != 0) { return retcode; }
      retcode = ComputePartition();
      if (retcode != 0) { return retcode; }
      leftNumberFlag = 1;
      continue;
    }
    else if ((retcode = func(expr, ExpressionResult,
      "N", 1, leftNumberFlag)) <= 0)
    {
      if (retcode != 0) { return retcode; }
      retcode = ComputeNext();
      if (retcode != 0) { return retcode; }
      leftNumberFlag = 1;
      continue;
    }
    else if ((retcode = func(expr, ExpressionResult,
      "B", 1, leftNumberFlag)) <= 0)
    {
      if (retcode != 0) { return retcode; }
      retcode = ComputeBack();
      if (retcode != 0) { return retcode; }
      leftNumberFlag = 1;
      continue;
    }
    else if ((charValue & 0xDF) == 'X')
    {
      if (leftNumberFlag || valueX.nbrLimbs == 0)
      {
        return EXPR_SYNTAX_ERROR;
      }
      CopyBigInt(&stackValues[stackIndex], &valueX);
      valueXused = TRUE;
      exprIndex++;
      leftNumberFlag = TRUE;
      continue;
    }
    else if ((charValue & 0xDF) == 'C')
    {
      if (leftNumberFlag || valueX.nbrLimbs == 0)
      {
        return EXPR_SYNTAX_ERROR;
      }
      intToBigInteger(&stackValues[stackIndex], counterC);
      valueXused = TRUE;
      exprIndex++;
      leftNumberFlag = TRUE;
      continue;
    }
    else if (charValue == '(')
    {
      if (leftNumberFlag == TRUE)
      {
        return EXPR_SYNTAX_ERROR;
      }
      if (stackIndex >= PAREN_STACK_SIZE)
      {
        return EXPR_TOO_MANY_PAREN;
      }
      stackOperators[stackIndex++] = charValue;
      exprIndex++;
      continue;
    }
    else if (charValue == ')' || charValue == ',')
    {
      if (leftNumberFlag == 0)
      {
        return EXPR_SYNTAX_ERROR;
      }
      while (stackIndex > startStackIndex &&
        stackOperators[stackIndex - 1] != '(')
      {
        if ((SubExprResult = ComputeSubExpr()) != 0)
        {
          return SubExprResult;
        }
      }
      if (stackIndex == startStackIndex)
      {
        break;
      }
      if (charValue == ',')
      {
        return EXPR_PAREN_MISMATCH;
      }
      stackIndex--;    /* Discard ')' */
      stackValues[stackIndex] = stackValues[stackIndex + 1];
      leftNumberFlag = 1;
      exprIndex++;
      continue;
    }
    else if (charValue >= '0' && charValue <= '9')
    {
      exprIndexAux = exprIndex;
      if (charValue == '0' && exprIndexAux < exprLength - 2 &&
          *(expr+exprIndexAux + 1) == 'x')
      {  // hexadecimal
        exprIndexAux++;
        while (exprIndexAux < exprLength - 1)
        {
          charValue = *(expr+exprIndexAux + 1);
          if ((charValue >= '0' && charValue <= '9') ||
              (charValue >= 'A' && charValue <= 'F') ||
              (charValue >= 'a' && charValue <= 'f'))
          {
            exprIndexAux++;
          }
          else
          {
            break;
          }
        }
        // Generate big integer from hexadecimal number from right to left.
        carry.x = 0;
        i = 0;  // limb number.
        shLeft = 0;
        offset = exprIndexAux;
        ptrLimb = &stackValues[stackIndex].limbs[0];
        for (; exprIndexAux >= exprIndex + 2; exprIndexAux--)
        {
          c = *(expr + exprIndexAux);
          if (c >= '0' && c <= '9')
          {
            c -= '0';
          }
          else if (c >= 'A' && c <= 'F')
          {
            c -= 'A' - 10;
          }
          else
          {
            c -= 'a' - 10;
          }
          carry.x += c << shLeft;
          shLeft += 4;   // 4 bits per hex digit.
          if (shLeft >= BITS_PER_GROUP)
          {
            shLeft -= BITS_PER_GROUP;
            (ptrLimb++)->x = carry.x & MAX_VALUE_LIMB;
            carry.x = c >> (4-shLeft);
          }
        }
        if (carry.x != 0 || ptrLimb == &stackValues[stackIndex].limbs[0])
        {
          (ptrLimb++)->x = carry.x;
        }
        exprIndex = offset+1;
        stackValues[stackIndex].nbrLimbs = (int)(ptrLimb - &stackValues[stackIndex].limbs[0]);
        stackValues[stackIndex].sign = SIGN_POSITIVE;
      }