{ Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina }

unit varExponential;

interface
uses
  BaseVariation, XFormMan;
  
{$ifdef CPUX86}
  {$define _ASM_}
{$endif}  

type
  TVariationExponential = class(TBaseVariation)
  private
    
  public
    constructor Create;

    class function GetName: string; override;
    class function GetInstance: TBaseVariation; override;

    procedure CalcFunction; override;
  end;


implementation

uses
  Math;
  
////////////////////////

procedure TVariationExponential.CalcFunction;
{$ifndef _ASM_}
var
  vex: double;
  siny, cosy: double;
begin
  SinCos(PI * FTy^, siny, cosy);
  vex := vvar * exp(FTx^ - 1); 
  FPx^ := FPx^ +  cosy * vex;
  FPy^ := FPy^ +  siny * vex;
{$else}
asm
    mov     edx, [eax + FTx]
	  fld     qword ptr [edx]
    fld1
    fsubp   st(1), st
	// here goes exp(x) code from System.pas
    FLDL2E
    FMUL
    FLD     ST(0)
    FRNDINT
    FSUB    ST(1), ST
    FXCH    ST(1)
    F2XM1
    FLD1
    FADD
    FSCALE
    FSTP    ST(1)
	// -----
    fmul    qword ptr [eax + vvar]
    fld     qword ptr [edx + 8]
    fldpi
    fmulp
    fsincos
    fmul    st, st(2)
    fadd    qword ptr [edx + 16]
    fstp    qword ptr [edx + 16]
    fmulp
    fadd    qword ptr [edx + 24]
    fstp    qword ptr [edx + 24]
    fwait
{$endif}
end;

constructor TVariationExponential.Create;
begin
  inherited Create;
end;

class function TVariationExponential.GetInstance: TBaseVariation;
begin
   Result := TVariationExponential.Create;
end;

class function TVariationExponential.GetName: string;
begin
   Result := 'exponential';
end;

//////////////////////////////
initialization
  RegisterVariation(TVariationClassLoader.Create(TVariationExponential), false, false);

end.
