Ejemplo n.º 1
0
void calc_unwrap (double& p[], int N)
{
    double dp[MAX_LENGTH];
    double dps[MAX_LENGTH];
    double dp_corr[MAX_LENGTH];
    double cumsum[MAX_LENGTH];
    double cutoff = M_PI;               /* default value in matlab */
    int j;

    //assert(N <= MAX_LENGTH);

   // incremental phase variation
   // MATLAB: dp = diff(p, 1, 1);
    for (j = 0; j < N-1; j++)
      dp[j] = p[j+1] - p[j];

   // equivalent phase variation in [-pi, pi]
   // MATLAB: dps = mod(dp+dp,2*pi) - pi;
    for (j = 0; j < N-1; j++)
      dps[j] = (dp[j]+M_PI) - MathFloor((dp[j]+M_PI) / (2*M_PI))*(2*M_PI) - M_PI;

   // preserve variation sign for +pi vs. -pi
   // MATLAB: dps(dps==pi & dp>0,:) = pi;
    for (j = 0; j < N-1; j++)
      if ((dps[j] == -M_PI) && (dp[j] > 0))
        dps[j] = M_PI;

   // incremental phase correction
   // MATLAB: dp_corr = dps - dp;
    for (j = 0; j < N-1; j++)
      dp_corr[j] = dps[j] - dp[j];

   // Ignore correction when incremental variation is smaller than cutoff
   // MATLAB: dp_corr(abs(dp)<cutoff,:) = 0;
    for (j = 0; j < N-1; j++)
      if (MathAbs(dp[j]) < cutoff)
        dp_corr[j] = 0;

   // Find cumulative sum of deltas
   // MATLAB: cumsum = cumsum(dp_corr, 1);
    cumsum[0] = dp_corr[0];
    for (j = 1; j < N-1; j++)
      cumsum[j] = cumsum[j-1] + dp_corr[j];

   // Integrate corrections and add to P to produce smoothed phase values
   // MATLAB: p(2:m,:) = p(2:m,:) + cumsum(dp_corr,1);
    for (j = 1; j < N; j++)
    {
        p[j] += cumsum[j-1];

        if (DEBUG == 1)
        {
            Print ("phase_unwrapped[", DoubleToStr(j,0), "] ", DoubleToStr(p[j],10));
            file_result = FileWrite (file_handle, "phase_unwrapped", j, p[j]);
        }
    }
}
Ejemplo n.º 2
0
// LCOV_EXCL_STOP
ex_expr::exp_return_type ExFunctionMath::eval(char *op_data[],
					      CollHeap *heap,
					      ComDiagsArea** diagsArea)
{
  ex_expr::exp_return_type retcode = ex_expr::EXPR_OK;

  short err = 0;
  errno = 0;

  if ((getOperand()) &&
      (getOperand(0)->getDatatype() != REC_FLOAT64))
    {
      return evalUnsupportedOperations(op_data, heap, diagsArea);
    }

  switch (getOperType())
    {
    case ITM_DEGREES:
      // radians to degrees
      *(double *)op_data[0] = (*(double *)op_data[1] * 180E0) / PIVALUE;
      break;

    case ITM_PI:
      *(double *)op_data[0] = PIVALUE;
      break;

    case ITM_RADIANS:
      // degrees to radians
      *(double *)op_data[0] = (*(double *)op_data[1] / 180E0) * PIVALUE;
      break;

    case ITM_ROUND:
    {
      double op, res;
      short err1 = 0, err2 = 0, err3 = 0;
      Int32 roundTo;

      roundTo = (getNumOperands() > 2) ? (Int32)(*((double*)op_data[2])) : 0;

      switch (getOperand(1)->getDatatype()) {
        case REC_IEEE_FLOAT32:
          op = *((float*)op_data[1]);
          break;
        case REC_IEEE_FLOAT64:
          op = *((double*)op_data[1]);
          break;
        default:
            // LCOV_EXCL_START
          ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC);
          **diagsArea << DgString0("ROUND");
          return ex_expr::EXPR_ERROR;
          // LCOV_EXCL_STOP
      }

      //
      // For commenting purposes, assume the following:
      //
      // op      = -12.58
      // roundTo = 0
      //
      //

      double pow1 = MathPow(10.0, roundTo, err1);             // = 1
      double pow2 = MathPow(10.0, -roundTo, err2);            // = 1
      double pow3 = MathPow(10.0, roundTo+1, err3);           // = 10


      double abs1 = (op < 0.0) ? -op : op;                    // = 12.58
      double sign = (op < 0.0) ? -1.0 : 1.0;                  // = -1.0

      double floor1 = MathFloor(abs1*pow3, err);              // = 125
      double floor2 = 10.0 * MathFloor(floor1 / 10.0, err);   // = 120
      double floor3 = floor1 - floor2;                        // = 5

      double floor4 = MathFloor(abs1*pow1, err);              // = 12
      double floor5 = pow2 * sign;                            // = -1.0

      // Is digit at rounding position less than 5?
      if (floor3 < 5.0) {
        res = floor4 * floor5;                                // = -12.0
      }
      // Is digit at rounding position greater than 5?
      else if (floor3 > 5.0) {
        res = (floor4 + 1.0) * floor5;                        // = -13.0
      }
      else {
        // Are digits after rounding position greater than 0?
        if (((abs1*pow3) - floor1) > 0.0)
          res = (floor4 + 1.0) * floor5;                      // = -13.0
        else {
          double floor6 = 2.0 * MathFloor(floor4 / 2.0, err); // = 12.0

          // Now round to even
          if ((floor4 - floor6) == 1.0)
            res = (floor4 + 1.0) * floor5;                    // = -13.0
          else
            res = floor4 * floor5;                            // = -12.0
        }
      }

      *(double *)op_data[0] = res;

      break;
    }

    case ITM_SCALE_TRUNC:
      {
          // LCOV_EXCL_START
	ExRaiseSqlError(heap, diagsArea, EXE_MATH_FUNC_NOT_SUPPORTED);
	if (getOperType() == ITM_ROUND)
	  **diagsArea << DgString0("ROUND");
	else
	  **diagsArea << DgString0("TRUNCATE");
	  
	retcode = ex_expr::EXPR_ERROR;
      }
     break;
     // LCOV_EXCL_STOP

    case ITM_ACOS:
      if ((*(double *)op_data[1] < -1) ||
	  (*(double *)op_data[1] > 1))
	{
	  ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC);
	  **diagsArea << DgString0("ACOS");
	  return ex_expr::EXPR_ERROR;
	}

      *(double *)op_data[0] = MathAcos(*(double *)op_data[1], err);
      break;

    case ITM_ASIN:
      if ((*(double *)op_data[1] < -1) ||
	  (*(double *)op_data[1] > 1))
	{
	  ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC);
	  **diagsArea << DgString0("ASIN");

	  return ex_expr::EXPR_ERROR;
	}

      *(double *)op_data[0] = MathAsin(*(double *)op_data[1], err);
      break;

    case ITM_ATAN:
      // No error checks, all numeric values allowed.

      *(double *)op_data[0] = MathAtan(*(double *)op_data[1], err);
      break;
      
    case ITM_ATAN2:
      // No error checks, all numeric values allowed.

      *(double *)op_data[0] = MathAtan2(*(double *)op_data[1],
				    *(double *)op_data[2], err);
      break;

    case ITM_CEIL:
      // No error checks, all numeric values allowed.

      *(double *)op_data[0] = MathCeil(*(double *)op_data[1], err);
      break;

    case ITM_COS:

       *(double *)op_data[0] = MathCos(*(double *)op_data[1], err);
      break;

    case ITM_COSH:
      *(double *)op_data[0] = MathCosh(*(double *)op_data[1], err);
      if (*(double *)op_data[0] == HUGE_VAL)
	{
	  ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC);
	  **diagsArea << DgString0("COSH");
	  return ex_expr::EXPR_ERROR;
	}
      break;

    case ITM_EXP:
      *(double *)op_data[0] = MathExp(*(double *)op_data[1], err);

      // Check for overflow. 
      if (err) 
	// if  (*(double *)op_data[0] == HUGE_VAL_REAL64)
	{
	  // Overflow

	  ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC);
	  **diagsArea << DgString0("EXP");
	  return ex_expr::EXPR_ERROR;
	}

      break;

    case ITM_FLOOR:
      // No error checks, all numeric values allowed.

      *(double *)op_data[0] = MathFloor(*(double *)op_data[1], err);
      break;

    case ITM_LOG:
      if (*(double *)op_data[1] <= 0)
	{
	  ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC);
	  **diagsArea << DgString0("LOG");
	  return ex_expr::EXPR_ERROR;
	}
      
      *(double *)op_data[0] = MathLog(*(double *)op_data[1], err);
      break;

    case ITM_LOG10:
      if (*(double *)op_data[1] <= 0)
	{
	  ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC);
	  **diagsArea << DgString0("LOG10");
	  return ex_expr::EXPR_ERROR;
	}
      
      *(double *)op_data[0] = MathLog10(*(double *)op_data[1], err);
      break;

    case ITM_SIN:

      *(double *)op_data[0] = MathSin(*(double *)op_data[1], err);
      break;

    case ITM_SINH:
      *(double *)op_data[0] = MathSinh(*(double *)op_data[1], err);
      if (*(double *)op_data[0] == HUGE_VAL)
	{
	  ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC);
	  **diagsArea << DgString0("SINH");
	  return ex_expr::EXPR_ERROR;
	}
	
      break;

    case ITM_SQRT:
      if (*(double *)op_data[1] < 0)
	{
	  ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC);
	  **diagsArea << DgString0("SQRT");
	  return ex_expr::EXPR_ERROR;
	}
      
      *(double *)op_data[0] = MathSqrt(*(double *)op_data[1], err);
      break;

    case ITM_TAN:

      *(double *)op_data[0] = MathTan(*(double *)op_data[1], err);
      break;

    case ITM_TANH:
      // No error checks, all numeric values allowed.

      *(double *)op_data[0] = MathTanh(*(double *)op_data[1], err);
      break;
     
    case ITM_EXPONENT:
    case ITM_POWER:
      if (((*(double *)op_data[1] == 0) &&
	   (*(double *)op_data[2] <= 0)) ||
	  ((*(double *)op_data[1] < 0) &&
	   (MathFloor(*(double *)op_data[2], err) != *(double *)op_data[2])))
	{
	  ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC);
	  **diagsArea << DgString0("POWER");
	  return ex_expr::EXPR_ERROR;
	}

      *(double *)op_data[0] = MathPow(*(double *)op_data[1],
				  *(double *)op_data[2], err);
        if (errno == ERANGE)	
	{
	  // Overflow

	  ExRaiseSqlError(heap, diagsArea, EXE_BAD_ARG_TO_MATH_FUNC);
	  **diagsArea << DgString0("POWER");
	  return ex_expr::EXPR_ERROR;
	}
	

      break;

    default:
      {
	ExRaiseSqlError(heap, diagsArea, EXE_INTERNAL_ERROR);
	retcode = ex_expr::EXPR_ERROR;
      }
      break;
     }
  
  return retcode;
}