#help_index "Math"
public U0 R2P(F64 *_mag=NULL, F64 *_arg=NULL, F64 x, F64 y)
{//Rect to polar
//Returns angle in range (-pi,pi]
        if (_arg)
                *_arg = Arg(x, y);
        if (_mag)
                *_mag = Sqrt(x * x + y * y);
}

public U0 P2R(F64 *_x=NULL, F64 *_y=NULL, F64 mag, F64 arg)
{//Polar to Rect
        if (_x)
                *_x = mag * Cos(arg);
        if (_y)
                *_y = mag * Sin(arg);
}

public F64 Wrap(F64 theta, F64 base=-pi)
{//Returns angle in range [base,base+2*pi)
        F64 res = theta % (2 * pi);

        if (res >= base + 2 * pi)
                res -= 2 * pi;
        else if (res < base)
                res += 2 * pi;

        return res;
}

public I64 DistSqrI64(I64 x1, I64 y1, I64 x2, I64 y2)
{//Distance-squared between 2 points.
        I64 dx = x1 - x2, dy = y1 - y2;

        return dx * dx + dy * dy;
}

public F64 ASin(F64 s)
{//Arc Sin (Inverse Sin).
        F64 c;

        c = s * s;
        if (c >= 1.0)
                return pi / 2.0;
        c = Sqrt(1.0 - c);

        return ATan(s / c);
}

public F64 ACos(F64 c)
{//Arc Cos (Inverse Cos).
        F64 s;

        if (!c)
                return pi / 2.0;
        s = c * c;
        if (s >= 1.0)
                return 0.0;
        s = Sqrt(1.0 - s);

        return ATan(s / c);
}

public F64 Sinh(F64 x)
{//Hyperbolic Sine.
        return 0.5 * (Exp(x) - Exp(-x));
}

public F64 Cosh(F64 x)
{//Hyperbolic Cosine.
        return 0.5 * (Exp(x) + Exp(-x));
}

#help_index "Math/Complex;Data Types/Complex"
public Complex *CAdd(Complex *sum, Complex *n1, Complex *n2)
{//sum=n1+n2
        sum->x = n1->x + n2->x;
        sum->y = n1->y + n2->y;

        return sum;
}

public Complex *CSub(Complex *diff, Complex *n1, Complex *n2)
{//diff=n1-n2
        diff->x = n1->x - n2->x;
        diff->y = n1->y - n2->y;

        return diff;
}

public Complex *CMul(Complex *prod, Complex *n1, Complex *n2)
{//prod=n1*n2
        prod->x = n1->x * n2->x - n1->y * n2->y;
        prod->y = n1->x * n2->y + n1->y * n2->x;

        return prod;
}

public Complex *CDiv(Complex *quot, Complex *n1, Complex *n2)
{//quot=n1/n2
        F64 m1, arg1, m2, arg2;

        R2P(&m1, &arg1, n1->x, n1->y);
        R2P(&m2, &arg2, n2->x, n2->y);
        m1 /= m2;
        arg1 -= arg2;
        quot->x = m1 * Cos(arg1);
        quot->y = m1 * Sin(arg1);

        return quot;
}

public Complex *CScale(Complex *dst, F64 s)
{//dst*=s
        dst->x *= s;
        dst->y *= s;

        return dst;
}

public Complex *CCopy(Complex *dst, Complex *src)
{//dst=src
        dst->x = src->x;
        dst->y = src->y;

        return dst;
}

public Complex *CEqu(Complex *dst, F64 x, F64 y)
{//dst=(x,y)
        dst->x = x;
        dst->y = y;

        return dst;
}

public Complex *CPoly(Complex *dst, I64 n, Complex *zeros, Complex *x)
{//Eval complex polynomial
        I64             i;
        Complex n1, n2;

        if (n > 0)
        {
                CSub(dst, x, &zeros[0]);
                for (i = 1; i < n; i++)
                {
                        CCopy(&n1, dst);
                        CMul(dst, &n1, CSub(&n2, x, &zeros[i]));
                }
        }
        else
                CEqu(dst, 1.0, 0.0);

        return dst;
}