#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;
}