/*iRightDivisionRealMatrixByComplexMatrix*/
int iRightDivisionRealMatrixByComplexMatrix(
    double *_pdblReal1,     int _iInc1,
    double *_pdblReal2,     double *_pdblImg2,      int _iInc2,
    double *_pdblRealOut,   double *_pdblImgOut,    int _iIncOut, int _iSize)
{
    int iErr        = 0;
    int iIndex      = 0; //Main loop index
    int iIndex1     = 0; //Loop index on left operand
    int iIndex2     = 0; //Loop index on right operand
    int iIndexOut   = 0; //Lopp index on result matrix

    if (_iInc2 == 0)
    {
        if ((getieee() == 0) && (dabss(_pdblReal2[iIndex2]) + dabss(_pdblImg2[iIndex2]) == 0))
        {
            return 3;
        }
    }

    for (iIndex = 0 ; iIndex < _iSize ; iIndex++)
    {
        iErr = iRightDivisionRealByComplex(_pdblReal1[iIndex1], _pdblReal2[iIndex2], _pdblImg2[iIndex2], &_pdblRealOut[iIndexOut], &_pdblImgOut[iIndexOut]);
        iIndexOut    += _iIncOut;
        iIndex1      += _iInc1;
        iIndex2      += _iInc2;
    }

    return iErr;
}
/*iRightDivisionComplexByComplex*/
int iRightDivisionComplexByComplex(
    double _dblReal1, double _dblImg1,
    double _dblReal2, double _dblImg2,
    double *_pdblRealOut, double *_pdblImgOut)
{
    int iErr = 0;
    if (_dblImg2 == 0)
    {
        if (_dblReal2 == 0)
        {
            //got NaN + i NaN
            iErr = 10;
            *_pdblRealOut   = _dblImg2 / _dblReal2;
            *_pdblImgOut    = *_pdblRealOut;
        }
        else
        {
            *_pdblRealOut   = _dblReal1 / _dblReal2;
            *_pdblImgOut    = _dblImg1 / _dblReal2;
        }
    }
    else if (_dblReal2 == 0)
    {
        *_pdblRealOut   = _dblImg1 / _dblImg2;
        *_pdblImgOut    = (-_dblReal1) / _dblImg2;
    }
    else
    {
        //Generic division algorithm

        if (dabss(_dblReal2) >= dabss(_dblImg2))
        {
            double dblRatio2    = _dblImg2 / _dblReal2;
            double dblSum       = _dblReal2 + dblRatio2 * _dblImg2;
            *_pdblRealOut       = (_dblReal1 + _dblImg1 * dblRatio2) / dblSum;
            *_pdblImgOut        = (_dblImg1 - _dblReal1 * dblRatio2) / dblSum;
        }
        else
        {
            double dblRatio2    = _dblReal2 / _dblImg2;
            double dblSum       = _dblImg2 +  dblRatio2 * _dblReal2;
            *_pdblRealOut       = (_dblReal1 * dblRatio2 + _dblImg1) / dblSum;
            *_pdblImgOut        = (_dblImg1 * dblRatio2 - _dblReal1) / dblSum;
        }
    }
    return iErr;
}
Exemple #3
0
/*wwpowe*/
int iPowerComplexScalarByComplexScalar(
    double _dblReal1, double _dblImg1,
    double _dblReal2, double _dblImg2,
    double* _pdblRealOut, double* _pdblImgOut)
{
    if (_dblImg2 == 0)
    {
        //C ^ R
        iPowerComplexScalarByRealScalar(
            _dblReal1, _dblImg1,
            _dblReal2,
            _pdblRealOut, _pdblImgOut);
    }
    else
    {
        //C ^ C
        if (dabss(_dblReal1) + dabss(_dblImg1) != 0)
        {
            // ! 0 ^ C
            double dblRealTemp = 0;
            double dblImgTemp  = 0;

            wlog(_dblReal1, _dblImg1, &dblRealTemp, &dblImgTemp);
            C2F(wmul)(&dblRealTemp, &dblImgTemp, &_dblReal2, &_dblImg2, &dblRealTemp, &dblImgTemp);
            dblRealTemp   = dexps(dblRealTemp);
            *_pdblRealOut = dblRealTemp * dcoss(dblImgTemp);
            *_pdblImgOut  = dblRealTemp * dsins(dblImgTemp);
        }
        else
        {
            // 0 ^ C
            //FIXME : ieee
            //generate +Inf
            double dblZero = 0.0;
            *_pdblRealOut  = 1.0 / (dblZero);
            *_pdblImgOut   = 0;
        }
    }
    return 0;
}
/*iRightDivisionRealByComplex*/
int iRightDivisionRealByComplex(
    double _dblReal1,
    double _dblReal2, double _dblImg2,
    double *_pdblRealOut, double *_pdblImgOut)
{
    int iErr = 0;
    if (_dblImg2 == 0)
    {
        *_pdblRealOut   = _dblReal1 / _dblReal2;
        *_pdblImgOut    = 0;
    }
    else if (_dblReal2 == 0)
    {
        *_pdblRealOut   = 0;
        *_pdblImgOut    = -_dblReal1 / _dblImg2;
    }
    else
    {
        double dblAbsSum = dabss(_dblReal2) + dabss(_dblImg2);

        if (dblAbsSum == 0)
        {
            iErr = 10;
            *_pdblRealOut   = _dblReal1 / dblAbsSum;
            *_pdblImgOut    = 0;
        }
        else
        {
            double dblReal1Sum  = _dblReal1 / dblAbsSum;
            double dblReal2Sum  = _dblReal2 / dblAbsSum;
            double dblImg2Sum   = _dblImg2 / dblAbsSum;
            double dblSum       = pow(dblReal2Sum, 2) + pow(dblImg2Sum, 2);
            *_pdblRealOut       = (dblReal1Sum * dblReal2Sum) / dblSum;
            *_pdblImgOut        = (-dblReal1Sum * dblImg2Sum) / dblSum;
        }
    }
    return iErr;
}
Exemple #5
0
/*wdpowe*/
int iPowerComplexScalarByRealScalar(
    double _dblReal1, double _dblImg1,
    double _dblReal2,
    double* _pdblRealOut, double* _pdblImgOut)
{
    if ((int)_dblReal2 == _dblReal2)
    {
        //C ^ Z
        if (_dblReal2 == 0)
        {
            //C ^ 0
            *_pdblRealOut				= 1;
            *_pdblImgOut				= 0;
        }
        else if (_dblReal2 < 0)
        {
            //C ^ Z*-
            if (dabss(_dblReal1) + dabss(_dblImg1) != 0) //_dblReal1 != 0 || _dblImg1 != 0 ?
            {
                int i = 0;
                double dblOne				= 1;
                double dblZero			= 0;
                double dblRealTemp	= 0;
                double dblImgTemp		= 0;

                C2F(wdiv)(&dblOne, &dblZero, &_dblReal1, &_dblImg1, _pdblRealOut, _pdblImgOut);

                dblRealTemp					= *_pdblRealOut;
                dblImgTemp					= *_pdblImgOut;

                for (i = 2 ; i <= dabss(_dblReal2) ; i++)
                {
                    C2F(wmul)(&dblRealTemp, &dblImgTemp, _pdblRealOut, _pdblImgOut, _pdblRealOut, _pdblImgOut);
                }
            }
            else
            {
                //FIXME : ieee
                //generate +Inf
                double dblZero	= 0.0;
                *_pdblRealOut		= 1.0 / (dblZero);
                *_pdblImgOut		= 0;
            }
        }
        else
        {
            //C ^ Z*+
            int i								= 0;
            double dblRealTemp	= 0;
            double dblImgTemp		= 0;

            *_pdblRealOut			= _dblReal1;
            *_pdblImgOut			= _dblImg1;
            dblRealTemp				= *_pdblRealOut;
            dblImgTemp				= *_pdblImgOut;

            for (i = 2 ; i <= dabss(_dblReal2) ; i++)
            {
                C2F(wmul)(&dblRealTemp, &dblImgTemp, _pdblRealOut, _pdblImgOut, _pdblRealOut, _pdblImgOut);
            }
        }
    }
    else
    {
        if (dabss(_dblReal1) + dabss(_dblImg1) != 0)
        {
            //C ^ R
            double dblRealTemp	= 0;
            double dblImgTemp		= 0;

            wlog(_dblReal1, _dblImg1, &dblRealTemp, &dblImgTemp);
            dblRealTemp					= dexps(dblRealTemp * _dblReal2);
            dblImgTemp					= dblImgTemp * _dblReal2;
            *_pdblRealOut				= dblRealTemp * dcoss(dblImgTemp);
            *_pdblImgOut				= dblRealTemp * dsins(dblImgTemp);
        }
        else
        {
            if (_dblReal2 > 0)
            {
                //0 ^ R*+
                *_pdblRealOut		= 0;
                *_pdblImgOut		= 0;
            }
            else if (_dblReal2 < 0)
            {
                //0 ^ R*-
                //FIXME : ieee
                //generate +Inf
                double dblZero	= 0.0;
                *_pdblRealOut		= 1.0 / (dblZero);
                *_pdblImgOut		= 0;
            }
            else
            {
                //0 ^ 0
                *_pdblRealOut		= 1;
                *_pdblImgOut		= 0;
            }
        }
    }
    return 0;
}
Exemple #6
0
/*--------------------------------------------------------------------------*/
types::Function::ReturnValue sci_abs(types::typed_list &in, int _iRetCount, types::typed_list &out)
{
    if (in.size() != 1)
    {
        Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), "abs", 1);
        return types::Function::Error;
    }

    if (_iRetCount > 1)
    {
        Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), "abs", 1);
        return types::Function::Error;
    }

    switch (in[0]->getType())
    {
        case types::InternalType::ScilabDouble:
        {
            api_scilab::Double* pDblIn = api_scilab::getAsDouble(in[0]);
            api_scilab::Double* pDblOut = new api_scilab::Double(pDblIn->getDims(), pDblIn->getDimsArray());

            double* pdblInR = pDblIn->get();
            double* pdblInI = pDblIn->getImg();
            double* pdblOut = pDblOut->get();
            int size = pDblIn->getSize();
            if (pDblIn->isComplex())
            {
                for (int i = 0; i < size; i++)
                {
                    if (ISNAN(pdblInR[i]))
                    {
                        pdblOut[i] = pdblInR[i];
                    }
                    else if (ISNAN(pdblInI[i]))
                    {
                        pdblOut[i] = pdblInI[i];
                    }
                    else
                    {
                        pdblOut[i] = dabsz(pdblInR[i], pdblInI[i]);
                    }
                }
            }
            else
            {
                for (int i = 0; i < size; i++)
                {
                    if (ISNAN(pdblInR[i]))
                    {
                        pdblOut[i] = pdblInR[i];
                    }
                    else
                    {
                        pdblOut[i] = std::fabs(pdblInR[i]);
                    }
                }
            }

            out.push_back(api_scilab::getReturnVariable(pDblOut));
            delete pDblOut;
            delete pDblIn;
            break;
        }
        case types::InternalType::ScilabPolynom:
        {
            types::Polynom* pPolyIn = in[0]->getAs<types::Polynom>();
            types::Polynom* pPolyOut = new types::Polynom(pPolyIn->getVariableName(), pPolyIn->getDims(), pPolyIn->getDimsArray());
            double* data = NULL;

            if (pPolyIn->isComplex())
            {
                for (int i = 0; i < pPolyIn->getSize(); i++)
                {
                    int rank = pPolyIn->get(i)->getRank();
                    types::SinglePoly* pSP = new types::SinglePoly(&data, rank);

                    for (int j = 0; j < rank + 1; j++)
                    {
                        data[j] = dabsz(pPolyIn->get(i)->get()[j], pPolyIn->get(i)->getImg()[j]);
                    }

                    pPolyOut->set(i, pSP);
                    delete pSP;
                    pSP = NULL;
                }
            }
            else
            {
                for (int i = 0; i < pPolyIn->getSize(); i++)
                {
                    int rank = pPolyIn->get(i)->getRank();
                    types::SinglePoly* pSP = new types::SinglePoly(&data, rank);

                    for (int j = 0; j < rank + 1; j++)
                    {
                        data[j] = dabss(pPolyIn->get(i)->get()[j]);
                    }

                    pPolyOut->set(i, pSP);
                    delete pSP;
                    pSP = NULL;
                }
            }

            out.push_back(pPolyOut);
            break;
        }
        case types::InternalType::ScilabInt8:
        {
            out.push_back(absInt(in[0]->getAs<types::Int8>()));
            break;
        }
        case types::InternalType::ScilabInt16:
        {
            out.push_back(absInt(in[0]->getAs<types::Int16>()));
            break;
        }
        case types::InternalType::ScilabInt32:
        {
            out.push_back(absInt(in[0]->getAs<types::Int32>()));
            break;
        }
        case types::InternalType::ScilabInt64:
        {
            out.push_back(absInt(in[0]->getAs<types::Int64>()));
            break;
        }
        case types::InternalType::ScilabUInt8:
        case types::InternalType::ScilabUInt16:
        case types::InternalType::ScilabUInt32:
        case types::InternalType::ScilabUInt64:
        {
            out.push_back(in[0]);
            break;
        }
        default:
        {
            std::wstring wstFuncName = L"%" + in[0]->getShortTypeStr() + L"_abs";
            return Overload::call(wstFuncName, in, _iRetCount, out);
        }
    }

    return types::Function::OK;
}
void	dabsa(double *in, int size, double* out){
  int i = 0;
  for (i = 0; i < size; ++i) {
    out[i] = dabss(in[i]);
  }
}
floatComplex		catans(floatComplex z) {
  static float sSlim	= 0.2f;
  /*    .
  **   / \	WARNING : this algorithm was based on double precision
  **  / ! \	using float truncate the value to 0.
  ** `----'
  **
  ** static float sAlim	= 1E-150f;
  */
  static float sAlim	= 0.0f;
  static float sTol	= 0.3f;
  static float sLn2	= 0.6931471805599453094172321f;

  float RMax				= (float) getOverflowThreshold();
  float Pi_2				= 2.0f * satans(1);

  float _inReal = creals(z);
  float _inImg = cimags(z);
  float _outReal = 0;
  float _outImg = 0;

  /* Temporary variables */
  float R2 = 0;
  float S = 0;


  if(_inImg == 0)
    {
      _outReal	= satans(_inReal);
      _outImg	= 0;
    }
  else
    {
      R2 = _inReal * _inReal + _inImg * _inImg; /* Oo */
      if(R2 > RMax)
	{
	  if( dabss(_inImg) > RMax)
	    S = 0;
	  else
	    S = 1.0f / (((0.5f * _inReal) / _inImg) * _inReal + 0.5f * _inImg );
	}
      else
	S = (2 * _inImg) / (1+R2);

      if(dabss(S) < sSlim)
	{
	  /*
	    s is small: |s| < SLIM  <=>  |z| outside the following disks:
	    D+ = D(center = [0;  1/slim], radius = sqrt(1/slim**2 - 1)) if b > 0
	    D- = D(center = [0; -1/slim], radius = sqrt(1/slim**2 - 1)) if b < 0
	    use the special evaluation of log((1+s)/(1-s)) (5)
	  */
	  _outImg = slnp1m1s(S) * 0.25f;
	}
      else
	{
	  if(sabss(S) == 1 && sabss(_inReal) <= sAlim)
	    {
	      /* |s| >= SLIM  => |z| is inside D+ or D- */
	      _outImg = _sign(0.5f,_inImg) * ( sLn2 - logf(sabss(_inReal)));
	    }
	  else
	    {
	      _outImg = 0.25f * logf((powf(_inReal,2) + powf((_inImg + 1.0f),2)) / (powf(_inReal,2) + powf((_inImg - 1.0f),2)));
	    }
	}
      if(_inReal == 0)
	{/* z is purely imaginary */
	  if( dabss(_inImg) > 1)
	    {/* got sign(b) * pi/2 */
	      _outReal = _sign(1, _inImg) * Pi_2;
	    }
	  else if( dabss(_inImg) == 1)
	    {/* got a Nan with 0/0 */
	      _outReal = (_inReal - _inReal) / (_inReal - _inReal); /* Oo */
	    }
	  else
	    _outReal = 0;
	}
      else if(R2 > RMax)
	{/* _outImg is necessarily very near sign(a)* pi/2 */
	  _outReal = _sign(1, _inReal) * Pi_2;
	}
      else if(sabss(1 - R2) + sabss(_inReal) <= sTol)
	{/* |b| is very near 1 (and a is near 0)  some cancellation occur in the (next) generic formula */
	  _outReal = 0.5f * atan2f(2.0f * _inReal, (1.0f - _inImg) * (1.0f + _inImg) - powf(_inReal,2.0f));
	}
      else
	_outReal = 0.5f * atan2f(2.0f * _inReal, 1.0f - R2);
    }

  return FloatComplex(_outReal, _outImg);
}
floatComplex	csqrts(floatComplex in) {
  float RMax =  (float) getOverflowThreshold();
  float BRMin = 2.0f * (float) getUnderflowThreshold();

  float RealIn = creals(in);
  float ImgIn = cimags(in);

  float RealOut = 0;
  float ImgOut = 0;

  if(RealIn == 0)
    {/* pure imaginary case */
      if(dabss(ImgIn >= BRMin))
	RealOut = ssqrts(0.5f * sabss(ImgIn));
      else
	RealOut = ssqrts(sabss(ImgIn)) * ssqrts(0.5);

      ImgOut = _sign(1, ImgIn) * RealOut;
    }
  else if( sabss(RealIn) <= RMax && sabss(ImgIn) <= RMax)
    {/* standard case : a (not zero) and b are finite */
      float Temp = ssqrts(2.0f * (sabss(RealIn) + spythags(RealIn, ImgIn)));
      /* overflow test */
      if(Temp > RMax)
	{/*     handle (spurious) overflow by scaling a and b */
	  float RealTemp = RealIn / 16.0f;
	  float ImgTemp = ImgIn / 16.0f;
	  Temp = ssqrts(2.0f * (sabss(RealIn) + spythags(RealIn, ImgTemp)));
	  if(RealTemp >= 0)
	    {
	      RealOut	= 2 * Temp;
	      ImgOut	= 4 * ImgTemp / Temp;
	    }
	  else
	    {
	      RealOut	= 4 * sabss(ImgIn) / Temp;
	      ImgOut	= _sign(2, ImgIn) * Temp;
	    }
	}
      else if(RealIn >= 0) /* classic switch to get the stable formulas */
	{
	  RealOut	= 0.5f * Temp;
	  ImgOut	= ImgIn / Temp;
	}
      else
	{
	  RealOut	= sabss(ImgIn) / Temp;
	  ImgOut	= (_sign(0.5f, ImgIn)) * Temp;
	}
    }
  else
    {
      /*
      //Here we treat the special cases where a and b are +- 00 or NaN.
      //The following is the treatment recommended by the C99 standard
      //with the simplification of returning NaN + i NaN if the
      //the real part or the imaginary part is NaN (C99 recommends
      //something more complicated)
      */

      if(isnan(RealIn) == 1 || isnan(ImgIn) == 1)
	{/* got NaN + i NaN */
	  RealOut	= RealIn + ImgIn;
	  ImgOut	= RealOut;
	}
      else if( dabss(ImgIn) > RMax)
	{/* case a +- i oo -> result must be +oo +- i oo  for all a (finite or not) */
	  RealOut	= sabss(ImgIn);
	  ImgOut	= ImgIn;
	}
      else if(RealIn < -RMax)
	{/* here a is -Inf and b is finite */
	  RealOut	= 0;
	  ImgOut	= _sign(1, ImgIn) * sabss(RealIn);
	}
      else
	{/* here a is +Inf and b is finite */
	  RealOut	= RealIn;
	  ImgOut	= 0;
	}
    }

  return FloatComplex(RealOut, ImgOut);
}
Exemple #10
0
/*
*     PURPOSE
*        computes sqrt(a^2 + b^2) with accuracy and
*        without spurious underflow / overflow problems
*
*     MOTIVATION
*        This work was motivated by the fact that the original Scilab
*        PYTHAG, which implements Moler and Morrison's algorithm is slow.
*        Some tests showed that the Kahan's algorithm, is superior in
*        precision and moreover faster than the original PYTHAG.  The speed
*        gain partly comes from not calling DLAMCH.
*
*     REFERENCE
*        This is a Fortran-77 translation of an algorithm by William Kahan,
*        which appears in his article "Branch cuts for complex elementary
*        functions, or much ado about nothing's sign bit",
*        Editors: Iserles, A. and Powell, M. J. D.
*        in "States of the Art in Numerical Analysis"
*        Oxford, Clarendon Press, 1987
*        ISBN 0-19-853614-3
**     AUTHOR
*        Bruno Pincon <*****@*****.**>,
*        Thanks to Lydia van Dijk <*****@*****.**>
*/
ELEMENTARY_FUNCTIONS_IMPEXP double dpythags(double _dblVal1, double _dblVal2)
{
    double dblSqrt2		= 1.41421356237309504;
    double dblSqrt2p1	= 2.41421356237309504;
    double dblEsp		= 1.25371671790502177E-16;
    double dblRMax		= getOverflowThreshold();

    double dblAbs1 = 0;
    double dblAbs2 = 0;
    double dblTemp = 0;

    if (ISNAN(_dblVal1) == 1)
    {
        return _dblVal2;
    }

    if (ISNAN(_dblVal2) == 1)
    {
        return _dblVal1;
    }

    dblAbs1 = dabss(_dblVal1);
    dblAbs2 = dabss(_dblVal2);

    //Order x and y such that 0 <= y <= x
    if (dblAbs1 < dblAbs2)
    {
        dblTemp = dblAbs1;
        dblAbs1 = dblAbs2;
        dblAbs2 = dblTemp;
    }

    //Test for overflowing x
    if ( dblAbs1 >= dblRMax)
    {
        return dblAbs1;
    }

    //Handle generic case
    dblTemp = dblAbs1 - dblAbs2;
    if (dblTemp != dblAbs1)
    {
        double dblS = 0;
        if (dblTemp > dblAbs2)
        {
            dblS = dblAbs1 / dblAbs2;
            dblS += dsqrts(1 + dblS * dblS);
        }
        else
        {
            dblS	= dblTemp / dblAbs2;
            dblTemp = (2 + dblS) * dblS;
            dblS	= ((dblEsp + dblTemp / (dblSqrt2 + dsqrts(2 + dblTemp))) + dblS) + dblSqrt2p1;
        }
        return dblAbs1 + dblAbs2 / dblS;
    }
    else
    {
        return dblAbs1;
    }
}
double	       dcoshs(double x) {
  double y = dexps(dabss(x));
  return (0.5 * (y + 1.0/y));
}