unit mathlibc;
{$IFDEF FPC}
  {$MODE DELPHI}{$H+}
{$ENDIF}
{$INLINE ON}
(***************************************)
(* Copyright (C) 2014, SHIRAISHI Kazuo *)
(***************************************)

interface
uses
  Classes, SysUtils,
  mathc;

function REMAINDER( x,y:Complex):double;inline;    overload;
function REMAINDER( x:double; y:Complex):double;inline;    overload;
function REMAINDER( x:Complex; y:double):double;inline;    overload;

function TAN( x:Complex):double;inline;   overload;
function COT( x:Complex):double;inline;   overload;
function SEC( x:Complex):double;inline;   overload;
function CSC( x:Complex):double;inline;   overload;
function ACOS( x:Complex):double;inline;  overload;
function ASIN( x:Complex):double;inline;  overload;
function TANDEG( x:Complex):double;inline;overload;
function COTDEG( x:Complex):double;inline;overload;
function SECDEG( x:Complex):double;inline;overload;
function CSCDEG( x:Complex):double;inline;overload;
function ACOSDEG( x:Complex):double;inline;overload;
function ASINDEG( x:Complex):double;inline;overload;
function ANGLE( x,y:Complex):double;inline;overload;
function ANGLEDEG( x,y:Complex):double;inline;overload;
function ANGLE( x:complex; y:double):double;inline;overload;
function ANGLEDEG( x:complex; y:double):double;inline;overload;
function ANGLE(x:double;  y:complex):double;inline;overload;
function ANGLEDEG(x:double;  y:complex):double;inline;overload;
function COSH( x:Complex):double;inline;  overload;
function SINH( x:Complex):double;inline;  overload;
function EXP( x:Complex):Complex; overload;
function LOG( x:Complex):Complex; overload;
function LOG2( x:Complex):double;inline;  overload;
function LOG10( x:Complex):double;inline; overload;
function Power( Base,Exponent:Complex):Complex; overload;
function Power( Base:double;  Exponent:Complex):Complex; overload;
function Power( Base:complex;  Exponent:double):Complex; overload;


implementation
uses base, base2, baslib, mathlib;


 function REMAINDER( x,y:Complex):double;inline;    overload;
 begin
    result:=mathlib.REMAINDER(testreal(x), testreal(y))
 end;
 function REMAINDER( x:double; y:Complex):double;inline;    overload;
 begin
    result:=mathlib.REMAINDER(testreal(x), testreal(y))
 end;
 function REMAINDER( x:Complex; y:double):double;inline;    overload;
 begin
    result:=mathlib.REMAINDER(testreal(x), testreal(y))
 end;


function TAN( x:Complex):double;inline;   overload;
begin
    result:=mathlib.TAN(testreal(x))
end;

function COT( x:Complex):double;inline;   overload;
begin
    result:=mathlib.COT(testreal(x))
end;

function SEC( x:Complex):double;inline;   overload;
begin
    result:=mathlib.SEC(testreal(x))
end;

function CSC( x:Complex):double;inline;   overload;
begin
    result:=mathlib.CSC(testreal(x))
end;

function ACOS( x:Complex):double;inline;  overload;
begin
    result:=mathlib.ACOS(testreal(x))
end;

function ASIN( x:Complex):double;inline;  overload;
begin
    result:=mathlib.ASIN(testreal(x))
end;

function TANDEG( x:Complex):double;inline;overload;
begin
    result:=mathlib.TANDEG(testreal(x))
end;

function COTDEG( x:Complex):double;inline;overload;
begin
    result:=mathlib.COTDEG(testreal(x))
end;

function SECDEG( x:Complex):double;inline;overload;
begin
    result:=mathlib.SECDEG(testreal(x))
end;

function CSCDEG( x:Complex):double;inline;overload;
begin
    result:=mathlib.CSCDEG(testreal(x))
end;

function ACOSDEG( x:Complex):double;inline;overload;
begin
    result:=mathlib.ACOSDEG(testreal(x))
end;

function ASINDEG( x:Complex):double;inline;overload;
begin
    result:=mathlib.ASINDEG(testreal(x))
end;

function ANGLE( x,y:Complex):double;inline;overload;
begin
  result:=mathlib.ANGLE(testreal(x),testreal(y))
end;

function ANGLEDEG( x,y:Complex):double;inline;overload;
begin
  result:=mathlib.ANGLEDEG(testreal(x),testreal(y))
end;

function ANGLE( x:complex; y:double):double;inline;overload;
begin
  result:=mathlib.ANGLE(testreal(x),testreal(y))
end;

function ANGLEDEG( x:complex; y:double):double;inline;overload;
begin
  result:=mathlib.ANGLEDEG(testreal(x),testreal(y))
end;

function ANGLE(x:double;  y:complex):double;inline;overload;
begin
  result:=mathlib.ANGLE(testreal(x),testreal(y))
end;

function ANGLEDEG(x:double;  y:complex):double;inline;overload;
begin
  result:=mathlib.ANGLEDEG(testreal(x),testreal(y))
end;


function COSH( x:Complex):double;inline;  overload;
begin
    result:=mathlib.COSH(testreal(x))
end;

function SINH( x:Complex):double;inline;  overload;
begin
    result:=mathlib.SINH(testreal(x))
end;



function EXP( x:Complex):Complex; overload;
begin
   excode:=$03EB03EB;   // 1003 1003
   result:=mathc.EXP(x);
   excode:=DefaultExcode
end;

function LOG( x:Complex):Complex;  overload;
begin
   excode:=$03EB0BBC;   // 1003 3004
   result:=mathc.LOG(x);
   excode:=DefaultExcode
end;

function LOG2( x:Complex):double;inline;  overload;
begin
    result:=mathlib.LOG2(testreal(x))
end;

function LOG10( x:Complex):double;inline; overload;
begin
    result:=mathlib.LOG10(testreal(x))
end;


function IntPower( c:complex; i: int64): complex;
var
  x,t:ExtComplex;
begin
  x.initC(c);
  if i<0 then
     begin
       i:=-i;
       x.inverse;
     end;
  t.init(1,0);             //Result := 1.0;
  while i > 0 do
   begin
     while not Odd(i) do
     begin
      i := i shr 1;
      x.square;            // X := X * X
     end;
     Dec(i);
     t.multiply(@x);       //Result := Result * X
  end;
  result.x:=t.x; result.y:=t.y
end;

 function Power( Base,Exponent:Complex):Complex;overload;
 begin
    if (Exponent.x=0) and (Exponent.y=0) then
       result:=1.0
    else if (Base.x=0)and (Base.y=0) and ((Exponent.y<>0) or (Exponent.x<0)) then
          setexception(3003)
    else if (Base.y=0) and (Base.x>0) then
       if Exponent.y=0 then
          result:=mathlib.power(Base.x, Exponent.x)
       else
          result:=EXP(Exponent*ln(Base.x))
    else if (Exponent.y=0) and (system.int(Exponent.x)=Exponent.x) then
       result:=IntPower(Base, system.Trunc(Exponent.x))
    else if (Base.x=0)and (Base.y=0) and (Exponent.y=0.0) and (Exponent.x>0) then
       result:=0.0
    else
     begin
        result:=0.0;
        if (Base.x=0)and (Base.y=0) then
           setexception(3003)
        else
           setexception(3002) ;
      end;
 end;

 function Power( Base:double;  Exponent:Complex):Complex;overload;
 begin
    if Exponent.y=0 then
       result:=mathlib.Power(base, Exponent.x)
    else
    if (Base>0) then
          result:=EXP(Exponent*ln(Base))
    else if (Exponent.y=0) and (system.int(Exponent.x)=Exponent.x) then
       result:=IntPower(Base, system.Trunc(Exponent.x))
    else
     begin
        result:=0.0;
        if Base=0 then
           setexception(3003)
        else
           setexception(3002) ;
      end;
 end;

 function Power( Base:complex;  Exponent:double):Complex;overload;
 begin
    if Base.y=0 then
       result:=mathlib.Power(Base.x, Exponent)
    else if (Exponent=0)  then
       result:=1.0
    else if (Base.x=0)and (Base.y=0) and ( (Exponent<0)) then
          setexception(3003)
    else if  (system.int(Exponent)=Exponent) then
       result:=IntPower(Base, system.Trunc(Exponent))
    else if (Base.x=0)and (Base.y=0) and  (Exponent>0) then
       result:=0.0
    else
     begin
        result:=0.0;
        if (Base.x=0)and (Base.y=0) then
           setexception(3003)
        else
           setexception(3002) ;
      end;
 end;


end.

