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

interface
uses
  Classes, SysUtils, math,
  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:double):double; inline;   overload;
function TAN( x:Complex):double;inline;   overload;
function COT( x:double):double; inline;   overload;
function COT( x:Complex):double;inline;   overload;
function SEC( x:double):double; inline;   overload;
function SEC( x:Complex):double;inline;   overload;
function CSC( x:double):double; inline;   overload;
function CSC( x:Complex):double;inline;   overload;
function ACOS( x:double):double; inline;  overload;
function ASIN( x:double):double; inline;  overload;
function ACOS( x:Complex):double;inline;  overload;
function ASIN( x:Complex):double;inline;  overload;
function TANDEG( x:double):double;inline; overload;
function COTDEG( x:double):double;inline; overload;
function SECDEG( x:double):double;inline; overload;
function CSCDEG( x:double):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:double):double;inline;  overload;
function SINH( x:double):double;inline;  overload;
function COSH( x:Complex):double;inline; overload;
function SINH( x:Complex):double;inline; overload;
function EXP( x:double):double; inline;  overload;
function LOG2( x:double):double;inline;  overload;
function LOG10( x:double):double;inline; overload;
function EXP( x:Complex):Complex;inline; overload;
function LOG( x:Complex):Complex;inline; 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, math2sub, baslib, mathlib0;


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

 function TAN( x:double):double;inline;   overload;
 begin
     result:=math.tan(x);
 end;

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

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

function COT( x:double):double; inline;   overload;
begin
    result:=math.cot(x);
end;

function SEC( x:double):double;inline;   overload;
begin
    result:=math.sec(x);
end;

function CSC( x:double):double;inline;   overload;
begin
    result:=math.csc(x);
end;

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

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


function ACOS( x:double):double;inline;   overload;
 begin
      result:=math2sub.acos(x);
 end;

 function ASIN( x:double):double;inline;  overload;
 begin
      result:=math2sub.asin(x);
 end;


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

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


function TANDEG( x:double):double;inline; overload;
begin
   result:=math2sub.tandeg(x);
end;

function COTDEG( x:double):double; inline; overload;
begin
    result:=math2sub.cotdeg(x);
end;

 function SECDEG( x:double):double;inline; overload;
begin
    result:=math2sub.secdeg(x);
end;

function CSCDEG( x:double):double;inline; overload;
begin
    result:=math2sub.cscdeg(x);
end;

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

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

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

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

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

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

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

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

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

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

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

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

function COSH( x:double):double;inline;
begin
    result:=math2sub.cosh(x);
end;

function SINH( x:double):double;inline;
begin
    result:=math2sub.sinh(x);
end;


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

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

function EXP( x:double):double; inline;
begin
    result:=system.exp(x);
 end;

function LOG2( x:double):double;inline;
begin
    result:=Math.log2(x);
end;

function LOG10( x:double):double;inline;
begin
    result:=Math.log10(x);
end;

function EXP( x:Complex):Complex;inline;   overload;
begin
   result:=mathc.EXP(x);
end;

function LOG( x:Complex):Complex;inline;   overload;
begin
   result:=mathc.LOG(x);
end;

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

function LOG10( x:Complex):double;inline; overload;
begin
    result:=math.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:=mathlib0.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:=mathlib0.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:=mathlib0.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.


