Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/sffe
diff options
context:
space:
mode:
Diffstat (limited to 'src/sffe')
-rw-r--r--src/sffe/About4
-rw-r--r--src/sffe/Makefile.in36
-rw-r--r--src/sffe/asm/build.sh3
-rw-r--r--src/sffe/asm/build_win.sh3
-rw-r--r--src/sffe/asm/cmplx.asm901
-rw-r--r--src/sffe/sffe.c1013
-rw-r--r--src/sffe/sffe.pri23
-rw-r--r--src/sffe/sffe_cmplx_asm.c331
-rw-r--r--src/sffe/sffe_cmplx_gsl.c294
9 files changed, 2608 insertions, 0 deletions
diff --git a/src/sffe/About b/src/sffe/About
new file mode 100644
index 0000000..bea0456
--- /dev/null
+++ b/src/sffe/About
@@ -0,0 +1,4 @@
+SFFE ( Segfautlabs Formula Evaluator )
+sffe is very fast complex math formula evaluator written in C.
+you can read more about sffe lib at
+ http://www.segfaultlabs.com/projects/sffe
diff --git a/src/sffe/Makefile.in b/src/sffe/Makefile.in
new file mode 100644
index 0000000..6d1f565
--- /dev/null
+++ b/src/sffe/Makefile.in
@@ -0,0 +1,36 @@
+CC = @CC@
+CFLAGS = @CFLAGS@
+LIBS = @LIBS@
+LFLAGS = @LDFLAGS@
+AR = @AR@
+RANLIB = @RANLIB@
+
+SRCS = sffe.c \
+ sffe_cmplx_asm.c \
+ sffe_cmplx_gsl.c
+
+OBJS = $(SRCS:.c=.o) @ASM_CMPLX_O@
+
+TLIB = ../lib/libsffe.a
+
+all: $(TLIB)
+
+asm/cmplx.o: asm/cmplx.asm
+ nasm -f @CMPLX_O_TARGET@ asm/cmplx.asm -oasm/cmplx.o
+
+$(TLIB):$(OBJS)
+ rm -f $@
+ $(AR) rc $@ $(OBJS) @ASM_CMPLX_O@
+ $(RANLIB) $@
+
+keywords.c: keywords.gperf
+ gperf -t -p -D -C -a keywords.gperf > keywords.c
+
+clean:
+ rm -f $(TLIB)
+ rm -f *.[oas] asm/*.o
+ rm -f *~
+ rm -f core
+
+distclean:clean
+ rm Makefile
diff --git a/src/sffe/asm/build.sh b/src/sffe/asm/build.sh
new file mode 100644
index 0000000..9c0f362
--- /dev/null
+++ b/src/sffe/asm/build.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+nasm -f elf cmplx.asm -ocmplx.o
+# Not used anymore because ../Makefile already contains this compilation.
diff --git a/src/sffe/asm/build_win.sh b/src/sffe/asm/build_win.sh
new file mode 100644
index 0000000..8f1214b
--- /dev/null
+++ b/src/sffe/asm/build_win.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+nasm -f coff cmplx.asm -ocmplx.o
+# Not used anymore because ../Makefile already contains this compilation.
diff --git a/src/sffe/asm/cmplx.asm b/src/sffe/asm/cmplx.asm
new file mode 100644
index 0000000..ea3826b
--- /dev/null
+++ b/src/sffe/asm/cmplx.asm
@@ -0,0 +1,901 @@
+ ; COMPLEX NUMBER ARITHMETICS
+ ; Mateusz Malczak
+ ; NASM version
+ ; http://www.malczak.info
+ ; SFFE libs
+ ; http://segfaultlabs.com/projects/sffe
+ global _sffecabs,_sffecarg,_sffecargs,_sffecargc
+ global _sffecinv
+ global _sffecexp,_sffecln,_sffeclog2,_sffeclog
+ global _sffecsin,_sffeccos,_sffecsincos,_sffectan,_sffeccot
+ global _sffecsinh,_sffeccosh,_sffectanh,_sffeccoth
+ global _sffeccpow, _sffecpowd, _sffecpowi, _sffecpowc
+ global _sffecsqrt, _sffecrtni
+
+ %ifndef DELPHI
+ ; section .text use32 class=CODE ;class=CODE - needed for Borlands Compiler
+
+ ; section CODE use32
+ ; ".text" is more portable than "CODE use32":
+ section .text
+ %endif
+
+ ;; internal use
+%ifdef DELPHI
+[section expfunc_text use32]
+%endif
+_sffecexpfnc: ; exponent of real argument
+ fldl2e
+ fmulp st1
+ fld st0
+ frndint
+ fsub to st1
+ fld1
+ fscale
+ fstp st1
+ fxch st1
+ f2xm1
+ fld1
+ faddp st1
+ fmulp st1
+ ret
+
+ ;; globals
+%ifdef DELPHI
+[section cabs_text use32]
+%endif
+_sffecabs:
+ push ebp
+ mov ebp, esp
+ fld qword [ebp+08h]
+ fmul qword [ebp+08h]
+ fld qword [ebp+10h]
+ fmul qword [ebp+10h]
+ faddp st1
+ fsqrt
+ leave
+ ret
+
+%ifdef DELPHI
+[section carg_text use32]
+%endif
+_sffecarg:
+ push ebp
+ mov ebp, esp
+ fld qword [ebp+08h]
+ fld qword [ebp+10h]
+ fpatan
+ wait
+ leave
+ ret
+
+%ifdef DELPHI
+[section cargs_text use32]
+%endif
+_sffecargs:
+ push ebp
+ mov ebp, esp
+ fld qword [ebp+10h]
+ fld qword [ebp+08h]
+ fmul qword [ebp+08h]
+ fld qword [ebp+10h]
+ fmul qword [ebp+10h]
+ faddp st1
+ fsqrt
+ fdivp st1
+ wait
+ leave
+ ret
+
+%ifdef DELPHI
+[section cargc_text use32]
+%endif
+_sffecargc:
+ push ebp
+ mov ebp, esp
+ fld qword [ebp+08h]
+ fld qword [ebp+08h]
+ fmul qword [ebp+08h]
+ fld qword [ebp+10h]
+ fmul qword [ebp+10h]
+ faddp st1
+ fsqrt
+ fdivp st1
+ wait
+ leave
+ ret
+
+%ifdef DELPHI
+[section cinv_text use32]
+%endif
+_sffecinv:
+ push ebp
+ mov ebp, esp
+ mov edx, [ebp+08h]
+ fld qword [ebp+0ch]
+ fld qword [ebp+14h]
+ fld st0
+ fmul to st0
+ fld st2
+ fmul to st0
+ faddp st1
+ fdiv to st1
+ fdiv to st2
+ fstp st0
+ fchs
+ fstp qword [edx+08h]
+ fstp qword [edx]
+ wait
+ leave
+ ret
+
+%ifdef DELPHI
+[section cexp_text use32]
+%endif
+_sffecexp:
+ push ebp
+ mov ebp,esp
+ mov eax, [ebp+08h]
+ fld qword [ebp+0ch]
+ call _sffecexpfnc
+ fld qword [ebp+14h]
+ fsincos
+ fld st2
+ fmulp st1
+ fstp qword [eax]
+ fmulp st1
+ fstp qword [eax+08h]
+ wait
+ leave
+ ret
+
+%ifdef DELPHI
+[section cln_text use32]
+%endif
+_sffecln:
+ push ebp
+ mov ebp,esp
+ mov eax, [ebp+08h]
+ ;theta
+ fld qword [ebp+14h]
+ fld qword [ebp+0ch]
+ fpatan
+ ;z module
+ fld qword [ebp+0ch]
+ fmul qword [ebp+0ch]
+ fld qword [ebp+14h]
+ fmul qword [ebp+14h]
+ faddp st1
+ fsqrt
+ ;ln||z||
+ fld1
+ fxch st1
+ fyl2x
+ fldl2e
+ fdivp st1
+ fstp qword [eax]
+ fstp qword [eax+08h]
+ wait
+ leave
+ ret
+
+%ifdef DELPHI
+[section clog2_text use32]
+%endif
+_sffeclog2:
+ push ebp
+ mov ebp,esp
+ mov eax, [ebp+08h]
+ fld1
+ ;z module
+ fld qword [ebp+0ch]
+ fmul qword [ebp+0ch]
+ fld qword [ebp+14h]
+ fmul qword [ebp+14h]
+ faddp st1
+ fsqrt
+ fyl2x
+ ;theta
+ fld qword [ebp+14h]
+ fld qword [ebp+0ch]
+ fpatan
+ fldln2
+ fdivp st1
+ fstp qword [eax+08h]
+ fstp qword [eax]
+ wait
+ leave
+ ret
+
+%ifdef DELPHI
+[section clog_text use32]
+%endif
+_sffeclog:
+ push ebp
+ mov ebp,esp
+ mov eax, [ebp+08h]
+ ;ln(base)
+ fld1
+ fild word [ebp+1ch]
+ fyl2x
+ fldl2e
+ fdivp st1
+ ;z module
+ fld qword [ebp+0ch]
+ fmul qword [ebp+0ch]
+ fld qword [ebp+14h]
+ fmul qword [ebp+14h]
+ faddp st1
+ fsqrt
+ ;ln||z||
+ fld1
+ fxch st1
+ fyl2x
+ fldl2e
+ fdivp st1
+ fdiv st1
+ ;theta
+ fld qword [ebp+14h]
+ fld qword [ebp+0ch]
+ fpatan
+ fdiv st2
+ fstp qword [eax+08h]
+ fstp qword [eax]
+ fstp st0
+ wait
+ leave
+ ret
+
+%ifdef DELPHI
+[section csin_text use32]
+%endif
+_sffecsin:
+ push ebp
+ mov ebp, esp
+ mov eax, [ebp+08h]
+ fld1
+ fld1
+ faddp st1
+ fld qword [ebp+14h]
+ call _sffecexpfnc
+ fld1
+ fdiv st1
+ fld st1;-
+ fld st1;- optimize
+ faddp st1;-
+ fdiv st3
+ fxch st2
+ fxch st1
+ fsubp st1
+ fdiv st2
+ fld qword [ebp+0ch]
+ fsincos
+ fxch st3
+ fmulp st1
+ fstp qword [eax]
+ fmulp st1
+ fstp qword [eax+08h]
+ fstp st0
+ fwait
+ leave
+ ret
+
+%ifdef DELPHI
+[section ccos_text use32]
+%endif
+_sffeccos:
+ push ebp
+ mov ebp,esp
+ mov eax, [ebp+08h]
+ fld1
+ fld1
+ faddp st1
+ fld qword [ebp+14h]
+ call _sffecexpfnc
+ fld1
+ fdiv st1
+ fld st1
+ fld st1
+ faddp st1
+ fdiv st3
+ fxch st2
+ fxch st1
+ fsubp st1
+ fdiv st2
+ fld qword [ebp+0ch]
+ fsincos
+ fxch st2
+ fmulp st1
+ fchs
+ fstp qword [eax+08h]
+ fmulp st1
+ fstp qword [eax]
+ fstp st0
+ fwait
+ leave
+ ret
+
+%ifdef DELPHI
+[section ctan_text use32]
+%endif
+_sffectan:
+ push ebp
+ mov ebp,esp
+ mov eax, [ebp+08h]
+ ;sinh(2b) cosh(2b)
+ fld1
+ fld1
+ faddp st1
+ fld qword [ebp+14h]
+ fadd qword [ebp+14h]
+ call _sffecexpfnc
+ fld1
+ fdiv st1
+ fld st1
+ fld st1
+ faddp st1
+ fdiv st3
+ fxch st2
+ fxch st1
+ fsubp st1
+ fdivrp st2 ;fdivrp st(2),st(0)
+ ;sin(2b) cos(2b)
+ fld qword [ebp+0ch]
+ fadd qword [ebp+0ch]
+ fsincos
+ faddp st2
+ ;check if zero
+ fdiv st1
+ fstp qword [eax]
+ fdivp st1
+ fstp qword [eax+08h]
+ fwait
+ leave
+ ret
+
+%ifdef DELPHI
+[section ccot_text use32]
+%endif
+_sffeccot:
+ push ebp
+ mov ebp,esp
+ mov eax, [ebp+08h]
+ ;sinh(2b) cosh(2b)
+ fld1
+ fld1
+ faddp st1
+ fld qword [ebp+14h]
+ fadd qword [ebp+14h]
+ call _sffecexpfnc
+ fld1
+ fdiv st1
+ fld st1
+ fld st1
+ fsubp st1
+ fdiv st3
+ fxch st2
+ fxch st1
+ faddp st1
+ fdivrp st2 ;fdivrp st(2),st(0)
+ ;sin(2b) cos(2b)
+ fld qword [ebp+0ch]
+ fld st0
+ faddp st1
+ fsincos
+ fsubp st3
+ ;check if zero
+ fdiv st2
+ fstp qword [eax]
+ fdiv st1
+ fchs
+ fstp qword [eax+08h]
+ fstp st0
+ fwait
+ leave
+ ret
+
+%ifdef DELPHI
+[section csinh_text use32]
+%endif
+_sffecsinh:
+ push ebp
+ mov ebp,esp
+ mov eax, [ebp+08h]
+ fld1
+ fld1
+ faddp st1
+ fld qword [ebp+0Ch]
+ call _sffecexpfnc
+ fld1
+ fdiv st1
+ fld st1
+ fld st1
+ faddp st1
+ fdiv st3
+ fxch st2
+ fxch st1
+ fsubp st1
+ fdivrp st2 ;jak w tan i cot
+ fld qword [ebp+14h]
+ fsincos
+ fxch st2
+ fmulp st1
+ fstp qword [eax+08h]
+ fmulp st1
+ fstp qword [eax]
+ fwait
+ leave
+ ret
+
+%ifdef DELPHI
+[section ccosh_text use32]
+%endif
+_sffeccosh:
+ push ebp
+ mov ebp,esp
+ mov eax, [ebp+08h]
+ fld qword [ebp+0ch]
+ call _sffecexpfnc
+ fld st0
+ fld1
+ fxch st1
+ fdivp st1
+ fld st1
+ fld st1
+ faddp st1
+ fld1
+ fld1
+ faddp st1
+ fdivp st1
+ fxch st2
+ fxch st1
+ fsubp st1
+ fld1
+ fld1
+ faddp st1
+ fdivp st1
+ fld qword [ebp+14h]
+ fsincos
+ fxch st2
+ fmulp st1
+ fstp qword [eax+08h]
+ fmulp st1
+ fstp qword [eax]
+ fwait
+ leave
+ ret
+
+%ifdef DELPHI
+[section ctanh_text use32]
+%endif
+_sffectanh:
+ push ebp
+ mov ebp,esp
+ mov eax, [ebp+08h]
+ ;sinh(2a) cosh(2a)
+ fld1
+ fld1
+ faddp st1
+ fld qword [ebp+0ch]
+ fadd qword [ebp+0ch]
+ call _sffecexpfnc
+ fld1
+ fdiv st1
+ fld st1
+ fld st1
+ fsubp st1
+ fdiv st3
+ fxch st2
+ fxch st1
+ faddp st1
+ fdivrp st2 ;jak wczesniej
+ ;sin(2b) cos(2b)
+ fld qword [ebp+14h]
+ fadd qword [ebp+14h]
+ fsincos
+ faddp st3
+ ;check if zero
+ fdiv st2
+ fstp qword [eax+08h]
+ fxch st1
+ fdivp st1
+ fstp qword [eax]
+ fwait
+ leave
+ ret
+
+%ifdef DELPHI
+[section ccoth_text use32]
+%endif
+_sffeccoth:
+ push ebp
+ mov ebp,esp
+ mov eax, [ebp+08h]
+ ;sinh(2b) cosh(2b)
+ fld1
+ fld1
+ faddp st1
+ fld qword [ebp+0ch]
+ fadd qword [ebp+0ch]
+ call _sffecexpfnc
+ fld1
+ fdiv st1
+ fld st1
+ fld st1
+ fsubp st1
+ fdiv st3
+ fxch st2
+ fxch st1
+ faddp st1
+ fdivrp st2 ;jak wczesniej
+ ;sin(2b) cos(2b)
+ fld qword [ebp+14h]
+ fadd qword [ebp+14h]
+ fsincos
+ fsubp st3
+ ;check if zero
+ fdiv st2
+ fchs
+ fstp qword [eax+08h]
+ fxch st1
+ fdivp st1
+ fstp qword [eax]
+ fwait
+ leave
+ ret
+
+;***************** COMPLEX TO COMPLEX POWER
+%ifdef DELPHI
+[section ccpow_text use32]
+%endif
+_sffeccpow:
+;TODO: wyeliminowac xch po wystepujace po obliczeniu theta
+ push ebp
+ mov ebp,esp
+ fld1
+ ;z module
+ fld qword [ebp+0ch]
+ fmul qword [ebp+0ch]
+ fld qword [ebp+14h]
+ fmul qword [ebp+14h]
+ faddp st1
+ fsqrt
+ ftst
+ fstsw ax
+ test ah, 1000000b
+ jnz MZ
+ mov eax, [ebp+08h]
+ ;ln||z||*/
+ fyl2x
+ fldl2e
+ fdivp st1
+ ;theta*/
+ fld qword [ebp+14h]
+ fld qword [ebp+0ch]
+ fpatan
+
+ fld st1 ;ln||z||
+ fmul qword [ebp+1ch]
+ fld st1 ;theta
+ fmul qword [ebp+24h]
+ fsubp st1 ; st0-st1
+ fxch st2 ; w st2 mam teraz a = z2.re * lnz - z2.im * theta w st0 jest ln||z||
+ fmul qword [ebp+24h]
+ fxch st1
+ fmul qword [ebp+1ch]
+ faddp st1
+ fxch st1
+
+ call _sffecexpfnc
+ fxch st1
+ fsincos
+ fld st2
+ fmulp st1
+ fstp qword [eax]
+ fmulp st1
+ fstp qword [eax+08h]
+ jmp END
+MZ:
+ mov eax, [ebp+08h]
+ fstp qword [eax+08h]
+ fldz
+ fstp qword [eax]
+ fstp st0
+END:
+s fwait
+ leave
+ ret
+
+;***************** COMPLEX TO REAL POWER
+%ifdef DELPHI
+[section cpowd_text use32]
+%endif
+_sffecpowd:
+ push ebp
+ mov ebp,esp
+; fld1
+ ;z module
+ fld qword [ebp+0ch]
+ fmul qword [ebp+0ch]
+ fld qword [ebp+14h]
+ fmul qword [ebp+14h]
+ faddp st1
+ fsqrt
+ ftst
+ fstsw ax
+ test ah, 1000000b
+ jnz MZ2
+ mov eax, [ebp+08h]
+ fld1
+ ;theta
+ fld qword [ebp+14h]
+ fld qword [ebp+0ch]
+ fpatan
+ fmul qword [ebp+1ch]
+ fxch st2
+ ;ln||z||
+ fyl2x
+ fldl2e
+ fdivp st1
+ fmul qword [ebp+1ch]
+
+ call _sffecexpfnc
+ fxch st1
+ fsincos
+ fld st2
+ fmulp st1
+ fstp qword [eax]
+ fmulp st1
+ fstp qword [eax+08h]
+ jmp END2
+MZ2:
+ mov eax, [ebp+08h]
+ fstp qword [eax+08h]
+ fldz
+ fstp qword [eax]
+END2:
+ fwait
+ leave
+ ret
+
+;***************** COMPLEX TO INT POWER
+%ifdef DELPHI
+[section cpowi_text use32]
+%endif
+_sffecpowi:
+ push ebp
+ mov ebp,esp
+ ;z module
+ fild dword [ebp+1ch] ;st(0)=n
+ fld qword [ebp+0ch]
+ fmul qword [ebp+0ch]
+ fld qword [ebp+14h]
+ fmul qword [ebp+14h]
+ faddp st1
+ fsqrt
+ ftst
+ fstsw ax
+ test ah, 1000000b
+ jnz MZ5
+ mov eax, [ebp+08h]
+ ;||z||^n
+ fld1
+ fxch st1
+ fyl2x
+ fmulp st1
+ fld st0
+ frndint
+ fsub to st1
+ fld1
+ fscale
+ fstp st1
+ fxch st1
+ f2xm1
+ fld1
+ faddp st1
+ fmulp st1
+ ;theta
+ fld qword [ebp+14h]
+ fld qword [ebp+0ch]
+ fpatan
+ fild dword [ebp+1ch]
+ fmulp st1
+ fsincos
+ fld st2
+ fmulp st1
+ fstp qword [eax]
+ fmulp st1
+ fstp qword [eax+08h]
+ jmp END53
+MZ5:
+ mov eax, [ebp+08h]
+ fstp qword [eax+08h]
+ fldz
+ fstp qword [eax]
+ fstp st0
+END53:
+ fwait
+ leave
+ ret
+
+;***************** INT/DOUBLE TO COMPLEX POWER
+%ifdef DELPHI
+[section cpowc_text use32]
+%endif
+_sffecpowc:
+ push ebp
+ mov ebp,esp
+ fld qword [ebp+0ch]
+ ftst
+ fstsw ax
+ test ah, 1000000b
+ jnz MZ3
+ mov eax, [ebp+08h]
+ ;n^a
+ fld qword [ebp+14h]
+ fxch st1
+ fabs
+ fld1
+ fxch st1
+ fyl2x
+ fmulp st1
+ fld st0
+ frndint
+ fsub to st1
+ fld1
+ fscale
+ fstp st1
+ fxch st1
+ f2xm1
+ fld1
+ faddp st1
+ fmulp st1
+ ;ln||n||
+ fld qword [ebp+0ch]
+ fabs
+ fld1
+ fxch st1
+ fyl2x
+ fldl2e
+ fdivp st1
+ fld qword [ebp+1ch]
+ fmulp st1
+ fsincos
+ fld st2
+ fmulp st1
+ fstp qword [eax]
+ fmulp st1
+ fstp qword [eax+08h]
+ jmp END3
+MZ3:
+ mov eax, [ebp+08h]
+ fstp qword [eax+08h]
+ fldz
+ fstp qword [eax]
+END3:
+ fwait
+ leave
+ ret
+
+;***************** SQRT
+%ifdef DELPHI
+[section csqrt_text use32]
+%endif
+_sffecsqrt:
+ push ebp
+ mov ebp,esp
+ push ebx
+ mov ebx, [ebp+08h]
+ ;z module
+ fld qword [ebp+0ch]
+ fmul qword [ebp+0ch]
+ fld qword [ebp+14h]
+ fmul qword [ebp+14h]
+ faddp st1
+ fsqrt
+ fld st0 ;duplicate |z|
+ ;real
+ fadd qword [ebp+0ch]
+ fld1
+ fld1
+ faddp st1
+ fdivp st1
+ fsqrt
+ fstp qword [ebx]
+ fwait
+ ;imag
+ fsub qword [ebp+0ch]
+ fld1
+ fld1
+ faddp st1
+ fdivp st1
+ fsqrt
+ ;imag sign check
+ push eax
+ fld qword [ebp+14h]
+ ftst
+ fstp st0
+ fstsw ax
+ test ah, 1b
+ jz IMAGPOS
+ fchs
+IMAGPOS:
+ pop eax
+ fwait
+ fstp qword [ebx+08h]
+ pop ebx
+ leave
+ ret
+
+;***************** Nth ORDER ROOT
+%ifdef DELPHI
+[section crtni_text use32]
+%endif
+_sffecrtni:
+ push ebp
+ mov ebp,esp
+ ;z module
+ fld qword [ebp+0ch]
+ fmul qword [ebp+0ch]
+ fld qword [ebp+14h]
+ fmul qword [ebp+14h]
+ faddp st1
+ fsqrt
+ ftst
+ fstsw ax
+ test ah, 1000000b
+ jnz MZ4
+ mov eax, [ebp+08h]
+ ;n-th root if ||z||
+ fld1
+ fild word [ebp+1ch]
+ fdivp st1 ;st0=1/n
+ fxch st1 ;st0=||z|| st1=1/n
+ fyl2x ;log2(||z||/n)
+ fld st0 ;duplikuj st0
+ frndint
+ fsub to st1 ;st0=int( log2(||z||/n) ) st1=frac( log2(||z||/n) )
+ fld1 ;st0=1
+ fscale ;st0=2^int( log2(||z||/n) ) st1=frac( log2(||z||/n) )
+ fstp st1
+ fxch st1
+ f2xm1 ;st1=2^frac( log2(||z||/n) )-1
+ fld1
+ faddp st1
+ fmulp st1 ;sqrt(||z||)
+ ;theta
+ fld qword [ebp+14h]
+ fld qword [ebp+0ch]
+ fpatan ;st0=theta st1=sqrN(||z||)
+ ;theta_i
+ fldpi
+ fldpi
+ faddp st1 ;st0=2Pi st1=theta st2=sqrN(||z||)
+ fimul word [ebp+20h]
+ faddp st1 ;st1=theta+i2Pi
+ fidiv word [ebp+1ch] ;st0=theta_i
+ ;re/im
+ fsincos
+
+ fld st2
+ fmulp st1
+ fstp qword [eax]
+ fmulp st1
+ fstp qword [eax+08h]
+ jmp END4
+MZ4:
+ fldz
+ fstp qword [eax]
+ fstp qword [eax+08h]
+END4:
+ leave
+ ret
+
+%ifndef DELPHI
+_sffecfunc:
+ push ebp
+ mov ebp,esp
+ mov eax, [ebp+08h]
+ leave
+ ret
+%endif
diff --git a/src/sffe/sffe.c b/src/sffe/sffe.c
new file mode 100644
index 0000000..668893e
--- /dev/null
+++ b/src/sffe/sffe.c
@@ -0,0 +1,1013 @@
+/*/////////////////////////////////////////////////////////////////////////////////////
+// project : sFFe ( SegFault (or Segmentation Fault :) ) formula evalutaor )
+// author : Mateusz Malczak ( mateusz@malczak.info )
+// wpage : www.segfaultlabs.com/projects/sffe
+///////////////////////////////////////////////////////////////////////////////////////
+// special build for XaoS, for more info visit
+// http://www.segfaultlabs.com/projects/sfXaos
+/////////////////////////////////////////////////////////////////////////////////////*/
+
+#include <config.h>
+#ifdef SFFE_USING
+
+#include <stdlib.h>
+#include <stdio.h>
+#ifdef linux
+#include <ctype.h>
+#endif
+#include <string.h>
+
+#include "sffe.h"
+#ifdef SFFE_CMPLX_ASM
+#include "sffe_cmplx_asm.h"
+#elif SFFE_CMPLX_GSL
+#include "sffe_cmplx_gsl.h"
+#endif
+
+#define sfset(arg,val) {\
+ (arg)->value = (sfNumber*)malloc(sizeof(sfNumber));\
+ if ( (arg)->value ) cmplxset( *((arg)->value), (val),0 ); }
+
+#define sfvar(p,parser,idx) (p)->value = (sfNumber*)((parser)->vars+idx)
+
+/************************* custom function */
+/* all used in this section variables are defined depanding on complex number realization */
+sffunction *sffe_function(char *fn, size_t len)
+{
+ unsigned char idx;
+ for (idx = 5; idx < sffnctscount; idx += 1) /* sffnctscount - defined in sffe_cmplx_* file */
+ if (!strncmp(fn, sfcmplxfunc[idx].name, len))
+ return (sffunction *) (sfcmplxfunc + idx);
+ return NULL;
+};
+
+sffunction *sffe_operator(char op)
+{
+ switch (op) {
+ case '^':
+ return (sffunction *) sfcmplxfunc;
+ break;
+ case '+':
+ return (sffunction *) sfcmplxfunc + 1;
+ break;
+ case '-':
+ return (sffunction *) sfcmplxfunc + 2;
+ break;
+ case '*':
+ return (sffunction *) sfcmplxfunc + 3;
+ break;
+ case '/':
+ return (sffunction *) sfcmplxfunc + 4;
+ break;
+ };
+ return NULL;
+};
+
+void *sffe_const(char *fn, size_t len, void *ptr)
+{
+ unsigned char idx = 3;
+ for (idx = 0; idx < sfvarscount; idx += 1)
+ if (!strncmp(fn, sfcnames[idx], len)) {
+ sfcvals[idx] ((sfNumber *) ptr);
+ return ptr;
+ };
+ return NULL;
+};
+
+/************************* custom function */
+
+
+sffe *sffe_alloc(void)
+{
+ sffe *rp = (sffe *) malloc(sizeof(sffe));
+ if (!rp)
+ return NULL;
+ memset(rp, 0, sizeof(sffe));
+ return rp;
+};
+
+static void sffe_clear(sffe ** parser)
+{
+ sffe *p = *parser;
+ unsigned int i = 0, j;
+ for (; i < p->argCount; i++) {
+ for (j = 0; j < p->varCount; j++)
+ if (p->args[i].value == p->varPtrs[j])
+ j = p->varCount;
+ if (j == p->varCount)
+ if (p->args[i].value)
+ free(p->args[i].value);
+ };
+ if (p->expression)
+ free(p->expression);
+ if (p->args)
+ free(p->args);
+ if (p->oprs)
+ free(p->oprs);
+ p->expression = NULL;
+ p->args = NULL;
+ p->oprs = NULL;
+};
+
+void sffe_free(sffe ** parser)
+{
+ sffe_clear(parser);
+ if ((*parser)->userf)
+ free((*parser)->userf);
+ if ((*parser)->varChars)
+ free((*parser)->varChars);
+ if ((*parser)->varPtrs)
+ free((*parser)->varPtrs);
+ free(*parser);
+ parser = NULL;
+};
+
+/* not really used, marked to remove
+void sffe_eval2(sffe *const parser)
+{
+ register sfopr* optro;
+ register sfopr* optr = parser->oprs;
+ register sfopr* optrl = parser->oprs+parser->oprCount;
+ optro = optr;
+ for ( optr=optr; optr!=optrl; optr+=1, optro+=1 )
+ {
+ optro->arg->parg = optro->arg-1;
+ optr->arg->parg = optr->f( optr->arg )->parg;
+ };
+};*/
+
+sfNumber sffe_eval(sffe * const parser)
+{
+ register sfopr *optro;
+ register sfopr *optr = parser->oprs;
+ register sfopr *optrl = parser->oprs + parser->oprCount;
+ optro = optr;
+ for (optr = optr; optr != optrl; optr += 1, optro += 1) {
+ optro->arg->parg = optro->arg - 1;
+ optr->arg->parg = optr->f(optr->arg)->parg;
+ };
+ return *(parser->result);
+};
+
+void *sffe_regvar(sffe ** parser, sfNumber * vptrs, char vchars)
+{
+ unsigned int i = (*parser)->varCount;
+ (*parser)->varCount += 1;
+ (*parser)->varPtrs =
+ (sfNumber **) realloc((*parser)->varPtrs,
+ (*parser)->varCount * sizeof(sfNumber *));
+ if (!(*parser)->varPtrs)
+ return NULL;
+ (*parser)->varChars =
+ (char *) realloc((*parser)->varChars, (*parser)->varCount);
+ if (!(*parser)->varChars)
+ return NULL;
+ (*parser)->varPtrs[i] = vptrs;
+ (*parser)->varChars[i] = toupper(vchars);
+ return (void *) ((*parser)->varPtrs + i);
+};
+
+void *sffe_regvars(sffe ** parser, unsigned int cN, sfNumber ** vptrs,
+ char *vchars)
+{
+ unsigned int i = (*parser)->varCount;
+ (*parser)->varCount += cN;
+ (*parser)->varPtrs =
+ (sfNumber **) realloc((*parser)->varPtrs,
+ (*parser)->varCount * sizeof(sfNumber *));
+ if (!(*parser)->varPtrs)
+ return NULL;
+ (*parser)->varChars =
+ (char *) realloc((*parser)->varChars, (*parser)->varCount);
+ if (!(*parser)->varChars)
+ return NULL;
+ for (cN = 0; i < (*parser)->varCount; i += 1, cN += 1) {
+ (*parser)->varPtrs[i] = vptrs[cN];
+ (*parser)->varChars[i] = toupper(vchars[cN]);
+ };
+ return (void *) ((*parser)->varPtrs + i);
+};
+
+sfNumber *sffe_varptr(sffe * const parser, char vchar)
+{
+ unsigned int i = 0;
+ while (i < parser->varCount) {
+ if (parser->varChars[i] == vchar)
+ return parser->varPtrs[i];
+ i += 1;
+ };
+ return NULL;
+};
+
+sfNumber *sffe_setvar(sffe ** parser, sfNumber * vptrs, char vchars)
+{
+ unsigned int i = 0;
+ while (i < (*parser)->varCount) {
+ if ((*parser)->varChars[i] == vchars) {
+ sfNumber *ret = (*parser)->varPtrs[i];
+ (*parser)->varPtrs[i] = vptrs;
+ return ret;
+ };
+ i += 1;
+ };
+ return NULL;
+};
+
+void *sffe_regfunc(sffe ** parser, char *vname, unsigned int parcnt,
+ sffptr funptr)
+{
+ sffunction *sff;
+ unsigned short i;
+ (*parser)->userf =
+ (sffunction *) realloc((*parser)->userf,
+ ((*parser)->userfCount +
+ 1) * sizeof(sffunction));
+ if (!(*parser)->userf)
+ return NULL;
+ sff = (*parser)->userf + (*parser)->userfCount;
+ /* 2.XI.2007 changed to get rid of warinings */
+ strcpy(sff->name, vname);
+ /* sff->name = (char*)malloc( strlen(vname) ); */
+ for (i = 0; i < strlen(vname); i += 1)
+ sff->name[i] = (char) toupper((int) vname[i]);
+ sff->parcnt = parcnt;
+ sff->fptr = funptr;
+ (*parser)->userfCount += 1;
+ return (void *) sff;
+};
+
+void *sffe_variable(sffe * const p, char *fname, size_t len)
+{
+ unsigned int idx = 0;
+ if (len == 1) /*FIXME vars names with length > 1 should be allowed */
+ for (; idx < p->varCount; idx += 1)
+ /* if ( !strncmp(fname,p->varChars[idx],len) ) */
+ if (p->varChars[idx] == *fname)
+ return (void *) p->varPtrs[idx];
+ return NULL;
+};
+
+sffunction *userfunction(const sffe * const p, char *fname, size_t len)
+{
+ unsigned char idx;
+ for (idx = 0; idx < p->userfCount; idx += 1)
+ if (!strncmp(fname, p->userf[idx].name, len))
+ return (sffunction *) (p->userf + idx);
+ return NULL;
+};
+
+char sffe_donum(char **str)
+{ /* parse number in format [-+]ddd[.dddd[e[+-]ddd]] */
+ unsigned char flag = 0; /*bit 1 - dot, bit 2 - dec, bits 3,4 - stan, bits 5..8 - error */
+ if (**str == '-') {
+ flag = 0x80;
+ *str += 1;
+ };
+ if (**str == '+')
+ *str += 1;
+ while (!((flag >> 4) & 0x07)) {
+ switch ((flag & 0x0f) >> 2) {
+ case 0: /*0..9 */
+ while (isdigit(**str))
+ *str += 1;
+ switch (**str) { /*only '.' or 'E' allowed */
+ case '.':
+ flag = (flag & 0xf3) | 4;
+ break;
+ case 'E':
+ flag = (flag & 0xf3) | 8;
+ break;
+ default:
+ flag = 0x10;
+ };
+ break;
+ case 1: /*. */
+ if (flag & 0x03)
+ flag = 0x20;
+ else
+ *str += 1; /*no 2nd dot, no dot after E */
+ flag = (flag & 0xf2) | 0x01;
+ break;
+ case 2: /*e */
+ if (flag & 0x02)
+ flag = 0x30;
+ else
+ *str += 1; /*no 2nd E */
+ if (!isdigit(**str)) { /*after E noly [+-] allowed */
+ if (**str != '-' && **str != '+')
+ flag = 0x40;
+ else
+ *str += 1;
+ };
+ flag = (flag & 0xf1) | 0x02;
+ break;
+ };
+ };
+ if (flag & 0x80)
+ flag ^= 0x80;
+ return flag >> 4;
+};
+
+char sffe_docmplx(char **str, sfarg ** arg)
+{ /* parse complex number in format { [-+]ddd[.dddd[e[+-]ddd]] ; [-+]ddd[.dddd[e[+-]ddd]] } */
+ char *chr, *chi;
+ chr = *str;
+ if (sffe_donum(str) > 1)
+ return 1;
+ if (*(*str)++ != ';')
+ return 2;
+ chi = *str;
+ if (sffe_donum(str) > 1)
+ return 1;
+ if (*(*str)++ != '}')
+ return 2;
+
+ cmplxset(*(*arg)->value, atof(chr), atof(chi));
+ return 0;
+};
+
+char sffe_doname(char **str)
+{
+ do {
+ *str += 1;
+ } while (isalnum(**str) || **str == '_');
+ if (strchr("+-*/^~!@#$%&<>?\\:\"|", (int) **str))
+ return 1; /*punctator */
+ if (**str == '(')
+ return 2; /* ( - funkcja */
+ if (**str == '.')
+ return 3; /*error :( this means something like X. COS. PI. */
+ return 1;
+};
+
+int sffe_parse(sffe ** parser, char *expression)
+{
+/**************var area */
+ struct opstack__ {
+#ifdef SFFE_DEVEL
+ char c; /* used in debug build to store operator character */
+#endif
+ unsigned char t; /* store priority of the operator 'f' */
+ sffptr f;
+ };
+ struct stack__ {
+ struct opstack__ *stck;
+ unsigned int size; //number of items on stack
+ struct stack__ *prev;
+ } *stmp, *stack;
+ sffunction **fnctbl;
+ sffunction **f;
+ sfarg *arg, *argcnt;
+ char *ech;
+ char *ch1, *ch2;
+ char *expcode; /*tokenized form : (f(n)+f(n))*f(n)-n (f-func, n-num,const) */
+ unsigned int ui1, ui2;
+ unsigned char opr;
+ char err;
+ sffe *p;
+/**************used defines */
+#define MEMERROR 1
+#define UNBALANCEDBRACKES 2
+#define INVALIDFUNCTION 3
+#define INAVLIDNUMBER 4
+#define UNKNOWNCONST 5
+#define OPERATOR 6
+#define STACKERROR 7
+#define PARCNTERROR 8
+#define NO_FUNCTIONS 9
+#define code(chr) \
+ expcode = (char*)realloc(expcode,ui1+2);\
+ expcode[ui1++] = chr;\
+ ch2 = expcode+ui1-1;\
+ opr = chr;\
+ expcode[ui1] = '\0';
+#define errset(errno) {\
+ err = errno;\
+ break;}
+#define insertfnc(fnc) \
+ for ( argcnt=p->args+p->argCount-1; argcnt>arg; argcnt-=1 )\
+ argcnt->value = (argcnt-1)->value;\
+ sfset(argcnt,-1.0);
+#ifdef SFFE_DEVEL
+#define sfpopstack(a)\
+ {\
+ stack->size-=1;\
+ insertfnc(NULL);\
+ printf("%c",stack->stck[stack->size].c);\
+ p->oprs[ui1].arg = (sfarg*)arg;\
+ p->oprs[ui1].f = stack->stck[stack->size].f;\
+ ui1 += 1;\
+ arg += 1;\
+ };
+#else
+#define sfpopstack(a)\
+ {\
+ stack->size-=1;\
+ insertfnc(NULL);\
+ p->oprs[ui1].arg = (sfarg*)arg;\
+ p->oprs[ui1].f = stack->stck[stack->size].f;\
+ ui1 += 1;\
+ arg += 1;\
+ };
+#endif
+
+#define priority(chr)\
+ (*chr=='f')?0x60:(\
+ (*chr=='^')?0x40:(\
+ ((*chr=='/')||(*chr=='*'))?0x20:(\
+ ((*chr=='+')||(*chr=='-'))?0x00:0x80\
+ )\
+ )\
+ )
+
+#ifdef SFFE_DEVEL
+ printf("parse - BEGIN\n");
+#endif
+/**************** CODE */
+ fnctbl = NULL;
+ ech = expression;
+ expcode = (char *) malloc(1);
+ err = 0;
+ //parser
+ p = *parser;
+ /* clear all internal structures */
+ if (p->expression)
+ sffe_clear(parser);
+
+ p->oprCount = 0;
+ p->argCount = 0;
+ p->expression = (char *) malloc(strlen(expression) + 1);
+ strcpy(p->expression, expression);
+ ech = p->expression;
+
+#ifdef SFFE_DEVEL
+ printf
+ ("\n|-----------------------------------------\n+ > %s[%d] - parsing\n|-----------------------------------------\n",
+ __FILE__, __LINE__);
+ printf("| input (dl.=%d) :|%s|\n", strlen(p->expression),
+ p->expression);
+#endif
+
+/*! PHASE 1 !!!!!!!!! remove spaces, count brackets, change decimal separators ',' to '.', remove multiple operators eg. ++--++1 -> 1, -+++2 -> -2 */
+ ch1 = NULL;
+ ui1 = 0; /*brackets */
+ ch2 = ech;
+ while (isspace(*ech))
+ ech += 1; /* skip leading spaces */
+ while (*ech) {
+ /*handle brackets and chaange ','->'.' */
+ switch (*ech) {
+ case '[':
+ *ech = '(';
+ case '(':
+ ui1 += 1;
+ break;
+ case ']':
+ *ech = ')';
+ case ')':
+ ui1 -= 1;
+ break;
+ case ',':
+ *ech = '.';
+ break;
+ };
+ *ch2 = (char) toupper((int) *ech);
+ /*fix multiple arithm operators */
+ if (ch1 && strchr("+-/*^", (int) *ech)
+ && strchr("+-/*^", (int) *ch1)) {
+ if (*ch1 == '-' && *ech == '-')
+ *ch1 = '+';
+ else if (*ch1 == '-' && *ech == '+')
+ *ch1 = '-';
+ else if (*ch1 == '+' && *ech == '-')
+ *ch1 = '-';
+ else if (*ch1 == *ech)
+ *ch1 = *ech;
+ else if (*ech == '-')
+ ch1 = ++ch2;
+ else if (*ch1 != *ech) {
+ err = OPERATOR;
+ break;
+ };
+ } else {
+ ch1 = ch2;
+ ch2 += 1;
+ };
+ do {
+ ech += 1;
+ } while (isspace(*ech)); /*skip spaces */
+ };
+ *ch2 = '\0';
+ p->expression =
+ (char *) realloc(p->expression, strlen(p->expression) + 1);
+ if (ui1 && !err)
+ err = UNBALANCEDBRACKES;
+
+#ifdef SFFE_DEVEL
+ printf("| check (dl.=%d) :|%s|\n", strlen(p->expression),
+ p->expression);
+#endif
+
+/*! PHASE 2 !!!!!!!! tokenize expression, lexical analysis (need optimizations) */
+ *expcode = '\0';
+ ch2 = NULL;
+ ui1 = 0;
+ ch1 = NULL; /*string starting position */
+ ech = p->expression;
+ opr = '('; /* in case of leading '-' */
+ while (*ech && !err) {
+ ch1 = ech;
+
+ if (isalpha(*ech)) {
+ switch (sffe_doname(&ech)) {
+ case 1: /* const or variable */
+ p->args =
+ (sfarg *) realloc(p->args,
+ (++p->argCount) * sizeof(sfarg));
+ if (!p->args)
+ errset(MEMERROR);
+ arg = p->args + p->argCount - 1;
+ arg->value =
+ (sfNumber *) sffe_variable(p, ch1,
+ (size_t) (ech - ch1));
+ if (!arg->value) {
+ sfset(arg, 10.0);
+ if (arg->value) {
+ if (!sffe_const
+ (ch1, (size_t) (ech - ch1), arg->value))
+ errset(UNKNOWNCONST);
+ } else
+ errset(MEMERROR);
+ };
+ opr = 'n';
+ break;
+ case 2: /* function */
+ fnctbl =
+ (sffunction **) realloc(fnctbl,
+ (p->oprCount +
+ 1) * sizeof(sffunction *));
+ if (!fnctbl)
+ errset(MEMERROR);
+ f = fnctbl + (p->oprCount++);
+ *f = NULL;
+ if (p->userfCount)
+ /*is it user defined function */
+ *f = (sffunction *) (void *) userfunction(p, ch1,
+ (size_t) (ech
+ -
+ ch1));
+ if (!*f)
+ /*if not, is it build in function */
+ *f = (sffunction *) (void *) sffe_function(ch1,
+ (size_t)
+ (ech -
+ ch1));
+ /* if not -> ERROR */
+ if (!*f)
+ errset(INVALIDFUNCTION);
+ opr = 'f';
+ break;
+ case 3: /* what ? */
+ errset(OPERATOR);
+ break;
+ };
+ } else /* numbers (this part can be optimized) */
+ /* is it a real number */ if (isdigit(*ech)
+ || (strchr("/*^(", (int) opr)
+ && strchr("+-", *ech))) {
+ ch1 = ech; /* st = 1; */
+ if (sffe_donum(&ech) > 1)
+ errset(INAVLIDNUMBER);
+ /*epx */
+ p->args =
+ (sfarg *) realloc(p->args,
+ (++p->argCount) * sizeof(sfarg));
+ if (!p->args)
+ errset(MEMERROR);
+ arg = p->args + p->argCount - 1;
+ /* 22.I.2009 fix for '-n'/'+n', which was parsed as 0*n */
+ if ((ech - ch1) == 1 && (*ch1 == '-'))
+ sfset(arg, -1)
+ else
+ sfset(arg, atof(ch1));
+ /*epx */
+ opr = 'n';
+ } else
+ /* if not, it can be complex number */
+#ifdef SFFE_COMPLEX
+ if (*ech == '{') {
+ ech += 1;
+ p->args =
+ (sfarg *) realloc(p->args,
+ (++p->argCount) * sizeof(sfarg));
+ if (!p->args)
+ errset(MEMERROR);
+ arg = p->args + p->argCount - 1;
+ sfset(arg, 0);
+ if (sffe_docmplx(&ech, &arg))
+ errset(INAVLIDNUMBER);
+ opr = 'n';
+ } else
+#endif
+ /* if not, we have operator */
+ {
+ ch1 = (char *) sffe_operator(*ech);
+
+ if (ch1) {
+ fnctbl =
+ (sffunction **) realloc(fnctbl,
+ (++p->oprCount) *
+ sizeof(sffunction *));
+ if (!fnctbl)
+ errset(MEMERROR);
+ fnctbl[p->oprCount - 1] = (sffunction *) ch1;
+ };
+ ch1 = ech;
+ opr = *ech;
+ ech += 1;
+ };
+
+
+ /* check if multiply sign skipped, nf, n(, )( */
+ if (!err && ui1 > 0)
+ if (opr == 'f' || opr == 'n' || opr == '(')
+ if (*ch2 == 'n' || *ch2 == ')') {
+ ch1 = (char *) sffe_operator('*');
+ fnctbl =
+ (sffunction **) realloc(fnctbl,
+ (++p->oprCount) *
+ sizeof(sffunction *));
+ if (!fnctbl)
+ errset(MEMERROR);
+ if (opr == 'f') {
+ fnctbl[p->oprCount - 1] = fnctbl[p->oprCount - 2];
+ fnctbl[p->oprCount - 2] = (sffunction *) ch1;
+ } else
+ fnctbl[p->oprCount - 1] = (sffunction *) ch1;
+ ch1 = (char *) (int) opr; /* ]:-> */
+ code('*');
+ opr = (char) (int) ch1;
+ ch1 = NULL;
+ };
+
+ code(opr);
+ };
+
+ ech = expcode;
+
+#ifdef SFFE_DEVEL
+ printf
+ ("| compiled expr. :|%s|\n| operacje: %d\n| stale,zmienne: %d\n| stack not.: ",
+ expcode, p->oprCount, p->argCount);
+#endif
+
+/*! PRE PHASE 3 !!!!! no operations in expression = single numeric value */
+ if (!p->oprCount && p->argCount == 1) {
+ p->oprs = (sfopr *) malloc(p->argCount * sizeof(sfopr));
+ p->oprs[0].arg = (sfarg *) p->args;
+ p->oprs[0].f = NULL;
+ p->result = (sfNumber *) p->args->value;
+ } else
+/*! PHASE 3 !!!!! create sffe 'stack' notation ]:-> */
+/* lots of memory operations are done here but no memory leaks should occur */
+ if (!err) {
+ ui1 = p->argCount + p->oprCount;
+ p->args = (sfarg *) realloc(p->args, ui1 * sizeof(sfarg));
+ memset(p->args + p->argCount, 0, p->oprCount * sizeof(sfarg));
+ p->argCount = ui1;
+ arg = p->args;
+ p->oprs = (sfopr *) malloc(p->oprCount * sizeof(sfopr));
+ ch1 = NULL; /* number */
+ /* stacks ( stores operations and controls parameters count inside of brackts blocks ) */
+ stack = (struct stack__ *) malloc(sizeof(struct stack__));
+ stack->size = 0; /* 0-stack is empty, but ready to write (one slot allocated), >0-number of element on stack */
+ stack->stck =
+ (struct opstack__ *) malloc(sizeof(struct opstack__));
+ stack->prev = NULL;
+ memset(stack->stck, 0, sizeof(struct opstack__));
+ ui1 = 0; /* used in defines */
+ f = fnctbl;
+
+ while (*ech && !err) {
+ switch (*ech) {
+ /* O */
+ case '+':
+ case '-':
+ case '*':
+ case '/':
+ case '^':
+ if (ch1) {
+#ifdef SFFE_DEVEL
+ printf("%c", *ch1);
+#endif
+ arg += 1;
+ };
+
+ ch1 = (char *) (int) (priority(ech));
+ /* there is an operator on stack */
+ if (stack->size) {
+ /* double casting to get rid of 'cast from pointer to integer of different size' warning
+ * remove all operators with higher, or equal priority
+ **/
+ while ((unsigned char) (int) ch1 <=
+ stack->stck[stack->size - 1].t) {
+ sfpopstack(NULL);
+ stack->stck = (struct opstack__ *) realloc(stack->stck, sizeof(struct opstack__)); /* is this reallocation really needed ?!? */
+ if (stack->size == 0)
+ break;
+ };
+ stack->stck =
+ (struct opstack__ *) realloc(stack->stck,
+ (stack->size +
+ 1) *
+ sizeof(struct
+ opstack__));
+ };
+
+#ifdef SFFE_DEVEL
+ stack->stck[stack->size].c = *ech;
+#endif
+
+ stack->stck[stack->size].t = (unsigned char) (int) ch1; /* store operator prority */
+ stack->stck[stack->size].f = ((sffunction *) (*f))->fptr; /* get function pointer */
+ stack->size += 1;
+ f += 1;
+ ch1 = NULL;
+ break;
+ /* F */
+ case 'f':
+ stack->stck =
+ (struct opstack__ *) realloc(stack->stck,
+ (stack->size +
+ 1) *
+ sizeof(struct opstack__));
+#ifdef SFFE_DEVEL
+ stack->stck[stack->size].c = 'f';
+#endif
+
+ /* mark operator as a function, and store number of parameters (0 - unlimited) */
+ stack->stck[stack->size].t =
+ 0x60 | (((sffunction *) (*f))->parcnt & 0x1F);
+ stack->stck[stack->size].f = ((sffunction *) (*f))->fptr; /* get function pointer */
+
+ stack->size += 1;
+ f += 1;
+ ch1 = NULL;
+ break;
+ /* ( */
+ case '(':
+ /* store current stack */
+ stmp = (struct stack__ *) malloc(sizeof(struct stack__));
+ stmp->prev = stack;
+ stack = stmp;
+ stack->size = 0;
+ stack->stck =
+ (struct opstack__ *) malloc(sizeof(struct opstack__));
+#ifdef SFFE_DEVEL
+ stack->stck[0].c = '_';
+#endif
+ opr = 0;
+ break;
+ /* ; */
+ case ';':
+ /* check if anything whas been read !!! */
+ if (ch1) {
+#ifdef SFFE_DEVEL
+ printf("%c", *ch1);
+#endif
+ arg += 1;
+ ch1 = NULL;
+ };
+ /* if there is something on stack, flush it we need to read next parameter */
+ while (stack->size)
+ sfpopstack(NULL);
+
+ /* wrong number of parameters */
+ ch2 = (char *) (stack->prev->stck + stack->prev->size - 1);
+ if ((((struct opstack__ *) ch2)->t & 0x1f) == 1)
+ errset(PARCNTERROR);
+ ((struct opstack__ *) ch2)->t =
+ 0x60 | ((((struct opstack__ *) ch2)->t & 0x1f) - 1);
+ break;
+ /* ) */
+ case ')':
+ if (ch1) {
+#ifdef SFFE_DEVEL
+ printf("%c", *ch1);
+#endif
+ arg += 1;
+ }
+ ch1 = NULL;
+
+ /* if there is something on stack, flush it we need to read next parameter */
+ while (stack->size)
+ sfpopstack(NULL);
+
+ if (!stack->prev)
+ errset(STACKERROR);
+ stmp = stack;
+ free(stmp->stck);
+ stack = stmp->prev;
+ free(stmp);
+
+ /* i was reading function, if so at the top of current
+ * stack is a function. identified by '*.t==3'
+ **/
+ ch2 = (char *) (stack->stck + stack->size - 1);
+ if ((((struct opstack__ *) ch2)->t & 0xE0) == 0x60) {
+ /* wrong number of parameters */
+ if ((((struct opstack__ *) ch2)->t & 0x1f) > 1)
+ errset(PARCNTERROR);
+ if (!err) {
+ sfpopstack(NULL);
+ if (stack->size)
+ stack->stck =
+ (struct opstack__ *) realloc(stack->stck,
+ (stack->
+ size) *
+ sizeof(struct
+ opstack__));
+ };
+ };
+ break;
+ /* n */
+ case 'n':
+ ch1 = ech;
+ break;
+ };
+ ech += 1;
+ };
+
+ if (!err) {
+ if (ch1) {
+#ifdef SFFE_DEVEL
+ printf("%c", *ch1);
+#endif
+ arg += 1;
+ }
+
+ while (stack) { /*clean up stack */
+ while (stack->size) {
+ stack->size -= 1;
+#ifdef SFFE_DEVEL
+ printf("%c", stack->stck[stack->size].c);
+#endif
+ insertfnc(NULL);
+ p->oprs[ui1].arg = (sfarg *) arg;
+ p->oprs[ui1].f = stack->stck[stack->size].f;
+ ui1 += 1;
+ arg += 1;
+ };
+ free(stack->stck);
+ stmp = stack->prev;
+ free(stack);
+ stack = stmp;
+ };
+
+ /* set up formula call stack */
+ (p->args)->parg = NULL;
+ for (ui1 = 1; ui1 < p->argCount; ui1 += 1)
+ (p->args + ui1)->parg = (p->args + ui1 - 1);
+
+#ifdef SFFE_DEVEL
+ printf("\n| numbers :");
+ for (ui1 = 0; ui1 < p->argCount; ui1 += 1) {
+ if ((p->args + ui1)->value)
+ printf(" %g%+gI", real((*(p->args + ui1)->value)),
+ imag((*(p->args + ui1)->value)));
+ else
+ printf(" [_]");
+ };
+
+ printf("\n| functions fnctbl:");
+ for (ui1 = 0; ui1 < p->oprCount; ui1 += 1)
+ printf(" 0x%.6X [%s]", (int) fnctbl[ui1]->fptr,
+ fnctbl[ui1]->name);
+
+ printf("\n| functions used ptrs:");
+ for (ui1 = 0; ui1 < p->oprCount; ui1 += 1)
+ printf(" 0x%.6X", (int) p->oprs[ui1].f);
+#endif
+ } else { /* prevent memory leaks */
+
+ while (stack) { /* clean up stack */
+ free(stack->stck);
+ stmp = stack->prev;
+ free(stack);
+ stack = stmp;
+ };
+ };
+ /* set up evaluation result pointer (result is stored in last operation return) */
+ p->result = (sfNumber *) (p->oprs + p->oprCount - 1)->arg->value;
+ if (!p->result)
+ err = MEMERROR;
+ };
+
+ if (err) {
+#ifdef SFFE_DEVEL
+ /* in debug mode report errors on stdout */
+ printf("Parser error : ");
+ switch (err) {
+ case MEMERROR:
+ printf(" MEMORY ERROR!!");
+ break;
+ case UNBALANCEDBRACKES:
+ printf(" UNBALANCED BRACKETS!! : %s\n", ch1);
+ break;
+ case INVALIDFUNCTION:
+ printf(" UNKNOWN FUNCTION!! : %s\n", ch1);
+ break;
+ case INAVLIDNUMBER:
+ printf(" NUMBER FORMAT!! : %s\n", ch1);
+ break;
+ case UNKNOWNCONST:
+ printf(" UNKOWN CONST or VAR NAME!! : %s\n", ch1);
+ break;
+ case OPERATOR:
+ printf(" UNKNOWN OPERATOR!! : %s\n", ch1);
+ break;
+ case STACKERROR:
+ printf(" INTERNAL STACK CORRUPTED!! : %s\n", ch1);
+ break;
+ case PARCNTERROR:
+ printf(" FUNCTION PARAMETERS ERROR!! : %s\n", ch1);
+ break;
+ case NO_FUNCTIONS:
+ printf("Formula error ! ARE YOU KIDDING ME ?!? : %s", ch1);
+ break;
+ };
+#endif
+ /* try to store error message */
+ if (p->errormsg)
+ switch (err) {
+ case MEMERROR:
+ sprintf(p->errormsg, "Formula error ! MEMORY ERROR!!");
+ break;
+ case UNBALANCEDBRACKES:
+ sprintf(p->errormsg,
+ "Formula error ! UNBALANCED BRACKETS!! : %s", ch1);
+ break;
+ case INVALIDFUNCTION:
+ sprintf(p->errormsg,
+ "Formula error ! UNKNOWN FUNCTION!! : %s", ch1);
+ break;
+ case INAVLIDNUMBER:
+ sprintf(p->errormsg,
+ "Formula error ! NUMBER FORMAT!! : %s", ch1);
+ break;
+ case UNKNOWNCONST:
+ sprintf(p->errormsg,
+ "Formula error ! UNKOWN CONST or VAR NAME!! : %s",
+ ch1);
+ break;
+ case OPERATOR:
+ sprintf(p->errormsg,
+ "Formula error ! UNKNOWN OPERATOR!! : %s", ch1);
+ break;
+ case STACKERROR:
+ sprintf(p->errormsg,
+ "Formula error ! INTERNAL STACK CORRUPTED!! : %s",
+ ch1);
+ break;
+ case PARCNTERROR:
+ sprintf(p->errormsg,
+ "Formula error ! FUNCTION PARAMETERS ERROR!! : %s",
+ ch1);
+ break;
+ case NO_FUNCTIONS:
+ sprintf(p->errormsg,
+ "Formula error ! ARE YOU KIDDING ME ?!? : %s",
+ ch1);
+ break;
+ };
+ /* if error -> clean up */
+ sffe_clear(&p);
+ };
+
+ /*undefine defines */
+#undef priority
+#undef sfpopstack
+#undef insertfnc
+#undef code
+#undef errset
+#undef MEMERROR
+#undef UNBALANCEDBRACKES
+#undef INVALIDFUNCTION
+#undef INAVLIDNUMBER
+#undef UNKNOWNCONST
+#undef OPERATOR
+#undef STACKERROR
+#undef PARCNTERROR
+ free(expcode);
+ free(fnctbl);
+
+#ifdef SFFE_DEVEL
+ printf("\nparse - END\n");
+#endif
+ return err;
+};
+
+#undef sfset
+#undef sfvar
+
+#endif
diff --git a/src/sffe/sffe.pri b/src/sffe/sffe.pri
new file mode 100644
index 0000000..2935585
--- /dev/null
+++ b/src/sffe/sffe.pri
@@ -0,0 +1,23 @@
+DEFINES += SFFE_USING SFFE_CMPLX_ASM
+
+SOURCES += \
+ $$PWD/sffe.c \
+ $$PWD/sffe_cmplx_asm.c \
+ $$PWD/sffe_cmplx_gsl.c
+
+ASM_SOURCES += \
+ $$PWD/asm/cmplx.asm
+
+nasm.input = ASM_SOURCES
+nasm.output = $$PWD/${QMAKE_FILE_BASE}.o
+
+win32 {
+ nasm.commands = nasm -f coff -o $$PWD/${QMAKE_FILE_BASE}.o ${QMAKE_FILE_NAME}
+} else:macx {
+ nasm.commands = nasm -f macho -o $$PWD/${QMAKE_FILE_BASE}.o ${QMAKE_FILE_NAME}
+} else {
+ nasm.commands = nasm -f elf -o $$PWD/${QMAKE_FILE_BASE}.o ${QMAKE_FILE_NAME}
+}
+
+
+QMAKE_EXTRA_COMPILERS += nasm
diff --git a/src/sffe/sffe_cmplx_asm.c b/src/sffe/sffe_cmplx_asm.c
new file mode 100644
index 0000000..88a008d
--- /dev/null
+++ b/src/sffe/sffe_cmplx_asm.c
@@ -0,0 +1,331 @@
+/*/////////////////////////////////////////////////////////////////////////////////////
+// project : sFFe ( SegFault (or Segmentation Fault :) ) formula evalutaor )
+// author : Mateusz Malczak ( mateusz@malczak.info )
+// wpage : www.segfaultlabs.com/projects/sffe
+///////////////////////////////////////////////////////////////////////////////////////
+// special build for XaoS, for more info visit
+// http://www.segfaultlabs.com/projects/sfXaos
+/////////////////////////////////////////////////////////////////////////////////////*/
+
+#include <config.h>
+#ifdef SFFE_CMPLX_ASM
+
+#include <math.h>
+#include "sffe.h"
+#include "sffe_cmplx_asm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+ const sffunction sfcmplxfunc[sffnctscount] = {
+ /* nie uwzgledniaj w wyszukaniu funkcji */
+ {sfpow, 2, "^\0"}, {sfadd, 2, "+\0"}, {sfsub, 2, "-\0"}, {sfmul, 2,
+ "*\0"},
+ {sfdiv, 2, "/\0"},
+ /* ponizej uwzgledniaj w wyszukaniu funkcji */
+ {sfsin, 1, "SIN\0"}, {sfcos, 1, "COS\0"}, {sftan, 1, "TAN\0"},
+ {sfcot, 1, "COT\0"},
+ {sfasin, 1, "ASIN\0"}, {sfacos, 1, "ACOS\0"}, {sfatan, 1,
+ "ATAN\0"}, {sfacot,
+ 1,
+ "ACOT\0"},
+ {sfatan2, 2, "ATAN2\0"},
+ {sfsinh, 1, "SINH\0"}, {sfcosh, 1, "COSH\0"}, {sftanh, 1,
+ "TANH\0"}, {sfcoth,
+ 1,
+ "COTH\0"},
+ {sfexp, 1, "EXP\0"}, {sflog, 1, "LOG\0"}, {sflog10, 1, "LOG10\0"},
+ {sflog2, 1, "LOG2\0"},
+ {sflogN, 2, "LOGN\0"}, {sflogCN, 2, "LOGCN\0"},
+ /*power functions */
+ {sfpow, 2, "POW\0"}, {sfpowi, 2, "POWI\0"}, {sfpowd, 2, "POWD\0"},
+ {sfpowdc, 2, "POWDC\0"},
+ {sfsqr, 1, "SQR\0"}, {sfsqrt, 1, "SQRT\0"}, {sfrtni, 3, "RTNI"},
+ {sfinv, 1, "INV\n"},
+ {sfceil, 1, "CEIL\0"}, {sffloor, 1, "FLOOR\0"}, {sfabs, 1,
+ "ABS\0"}, {sfrabs,
+ 1,
+ "RABS\0"},
+ {sfre, 1, "RE\0"}, {sfim, 1, "IM\0"},
+ {NULL, 1, "RAD\0"}, {NULL, 1, "DEG\0"},
+ {NULL, 1, "SIGN\0"}, {NULL, 1, "TRUNC\0"}, {sfrand, 1, "RAND\0"}
+ };
+
+ const char sfcnames[sfvarscount][5] =
+ { "PI\0", "PI_2\0", "PI2\0", "E\0", "I\0", "RND\0" };
+
+ const cfptr sfcvals[sfvarscount] =
+ { sfcPI, sfcPI2, sfc2PI, sfcE, sfcI, sfcRND };
+
+
+ cmplx cset(double r, double i) {
+ cmplx c;
+ c.r = r;
+ c.i = i;
+ return c;
+ };
+
+ cmplx cadd(const cmplx c1, const cmplx c2) {
+ cmplx r;
+ r.r = c1.r + c2.r;
+ r.i = c1.i + c2.i;
+ return r;
+ };
+
+ cmplx csub(const cmplx c1, const cmplx c2) {
+ cmplx r;
+ r.r = c1.r - c2.r;
+ r.i = c1.i - c2.i;
+ return r;
+ };
+
+ cmplx cmul(const cmplx c1, const cmplx c2) {
+ cmplx r;
+ r.r = c1.r * c2.r - c1.i * c2.i;
+ r.i = c1.r * c2.i + c1.i * c2.r;
+ return r;
+ };
+
+ cmplx cdiv(const cmplx c1, const cmplx c2) {
+ double d = (c2.r * c2.r + c2.i * c2.i);
+ cmplx r;
+ r.r = (c1.r * c2.r + c1.i * c2.i) / d;
+ r.i = (-c1.i * c2.r + c1.r * c2.i) / d;
+ return r;
+ };
+
+ sfarg *sfadd(sfarg * const p) { /* + */
+ sfvalue(p) = cadd(sfvalue(sfaram2(p)), sfvalue(sfaram1(p)));
+ return sfaram2(p);
+ };
+
+ sfarg *sfsub(sfarg * const p) { /* - */
+ sfvalue(p) = csub(sfvalue(sfaram2(p)), sfvalue(sfaram1(p)));
+ return sfaram2(p);
+ };
+
+ sfarg *sfmul(sfarg * const p) { /* * */
+ sfvalue(p) = cmul(sfvalue(sfaram2(p)), sfvalue(sfaram1(p)));
+ return sfaram2(p);
+ };
+
+ sfarg *sfdiv(sfarg * const p) { /* / */
+ sfvalue(p) = cdiv(sfvalue(sfaram2(p)), sfvalue(sfaram1(p)));
+ return sfaram2(p);
+ };
+
+
+ sfarg *sfsin(sfarg * const p) { /* sin */
+ sfvalue(p) = sffecsin(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sfcos(sfarg * const p) { /* cos */
+ sfvalue(p) = sffeccos(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sftan(sfarg * const p) { /* tan */
+ sfvalue(p) = sffectan(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sfcot(sfarg * const p) { /* ctan */
+ sfvalue(p) = sffeccot(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+
+ sfarg *sfasin(sfarg * const p) { /* asin */
+ //sfvalue(p) = asin( sfvalue( sfaram1(p) ) );
+ return sfaram1(p);
+ };
+
+ sfarg *sfacos(sfarg * const p) { /* acos */
+ //sfvalue(p) = acos( sfvalue( sfaram1(p) ) );
+ return sfaram1(p);
+ };
+
+ sfarg *sfatan(sfarg * const p) { /* atan */
+// sfvalue(p) = atan( sfvalue( sfaram1(p) ) );
+ return sfaram1(p);
+ };
+
+ sfarg *sfacot(sfarg * const p) { /* actan */
+// sfvalue(p) = 1.0/atan( sfvalue( sfaram1(p) ) );
+ return sfaram1(p);
+ };
+
+ sfarg *sfatan2(sfarg * const p) { /* atan2 */
+ //sfvalue(p) = atan2( sfvalue( sfaram2(p) ), sfvalue( sfaram1(p) ) );
+ return sfaram2(p);
+ };
+
+
+ sfarg *sfsinh(sfarg * const p) { /* sinh */
+ sfvalue(p) = sffecsinh(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sfcosh(sfarg * const p) { /* cosh */
+ sfvalue(p) = sffeccosh(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sftanh(sfarg * const p) { /* tanh */
+ sfvalue(p) = sffectanh(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sfcoth(sfarg * const p) { /* ctanh */
+ sfvalue(p) = sffeccoth(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+
+ sfarg *sfexp(sfarg * const p) { /* exp */
+ sfvalue(p) = sffecexp(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sflog(sfarg * const p) { /* log */
+ sfvalue(p) = sffecln(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sflog2(sfarg * const p) { /* log2 */
+ sfvalue(p) = sffeclog2(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sflog10(sfarg * const p) { /* log2 */
+ sfvalue(p) = sffeclog(sfvalue(sfaram1(p)), 10);
+ return sfaram1(p);
+ };
+
+ sfarg *sflogN(sfarg * const p) { /* logN */
+ sfvalue(p) = sffeclog(sfvalue(sfaram1(p)), sfvalue(sfaram2(p)).r);
+ return sfaram2(p);
+ };
+
+ sfarg *sflogCN(sfarg * const p) { /* logCN */
+ sfvalue(p) =
+ cdiv(sffecln(sfvalue(sfaram2(p))),
+ sffecln(sfvalue(sfaram1(p))));
+ return sfaram2(p);
+ };
+
+ sfarg *sfpow(sfarg * const p) { /* csflx pow */
+ sfvalue(p) = sffeccpow(sfvalue(sfaram2(p)), sfvalue(sfaram1(p)));
+ return sfaram2(p);
+ };
+
+ sfarg *sfpowi(sfarg * const p) { /* int pow */
+ sfvalue(p) =
+ sffecpowi(sfvalue(sfaram2(p)), (int) (sfvalue(sfaram1(p)).r));
+ return sfaram2(p);
+ };
+
+ sfarg *sfpowd(sfarg * const p) { /* double pow */
+ sfvalue(p) = sffecpowd(sfvalue(sfaram2(p)), sfvalue(sfaram1(p)).r);
+ return sfaram2(p);
+ };
+
+ sfarg *sfpowdc(sfarg * const p) { /* double to csflx pow */
+ sfvalue(p) = sffecpowc(sfvalue(sfaram2(p)).r, sfvalue(sfaram1(p)));
+ return sfaram2(p);
+ };
+
+ sfarg *sfsqr(sfarg * const p) { /* sqr */
+ sfvalue(p) = cmul(sfvalue(sfaram1(p)), sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sfsqrt(sfarg * const p) { /* sqrt */
+ sfvalue(p) = sffecsqrt(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sfrtni(sfarg * const p) /* rtni *///cos tu nie tak jak powinno byc ;(
+ {
+ sfvalue(p) =
+ sffecrtni(sfvalue(sfaram3(p)), (int) (sfvalue(sfaram2(p)).r),
+ (int) (sfvalue(sfaram1(p)).r));
+ return sfaram3(p);
+ };
+
+ sfarg *sfinv(sfarg * const p) { /* cinv */
+ sfvalue(p) = sffecinv(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sfceil(sfarg * const p) { /* ceil */
+ //sfvalue(p) = ceil( sfvalue( sfaram1(p) ) );
+ return sfaram1(p);
+ };
+
+ sfarg *sffloor(sfarg * const p) { /* floor */
+ //sfvalue(p) = floor( sfvalue( sfaram1(p) ) );
+ return sfaram1(p);
+ };
+
+ sfarg *sfabs(sfarg * const p) { /* abs - |z| */
+ sfvalue(p).r = sffecabs(sfvalue(sfaram1(p)));
+ sfvalue(p).i = 0;
+ return sfaram1(p);
+ };
+
+ sfarg *sfrabs(sfarg * const p) { /* abs - real numbers */
+ sfvalue(p).r = sfvalue(sfaram1(p)).r;
+ if (sfvalue(p).r < 0)
+ sfvalue(p).r = -sfvalue(p).r;
+ sfvalue(p).i = 0;
+ return sfaram1(p);
+ };
+
+ sfarg *sfre(sfarg * const p) { /* RE */
+ sfvalue(p).r = sfvalue(sfaram1(p)).r;
+ sfvalue(p).i = 0;
+ return sfaram1(p);
+ };
+
+ sfarg *sfim(sfarg * const p) { /* IM */
+ sfvalue(p).r = sfvalue(sfaram1(p)).i;
+ sfvalue(p).i = 0;
+ return sfaram1(p);
+ };
+
+ sfarg *sfrand(sfarg * const p) { /* rand */
+ sfvalue(p).r =
+ sfvalue(sfaram1(p)).r * (double) rand() / (double) RAND_MAX;
+ sfvalue(p).i = 0;
+ return sfaram1(p);
+ };
+
+//const eval
+ void sfcPI(sfNumber * cnst) {
+ *cnst = cset(4 * atan(1), 0);
+ };
+ void sfcPI2(sfNumber * cnst) {
+ *cnst = cset(2 * atan(1), 0);
+ };
+ void sfc2PI(sfNumber * cnst) {
+ *cnst = cset(8 * atan(1), 0);
+ };
+ void sfcE(sfNumber * cnst) {
+ *cnst = cset(exp(1), 0);
+ };
+ void sfcI(sfNumber * cnst) {
+ *cnst = cset(0, 1);
+ };
+ void sfcRND(sfNumber * cnst) {
+ *cnst = cset((double) rand() / (double) RAND_MAX, 0);
+ };
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/sffe/sffe_cmplx_gsl.c b/src/sffe/sffe_cmplx_gsl.c
new file mode 100644
index 0000000..6006663
--- /dev/null
+++ b/src/sffe/sffe_cmplx_gsl.c
@@ -0,0 +1,294 @@
+/*/////////////////////////////////////////////////////////////////////////////////////
+// project : sFFe ( SegFault (or Segmentation Fault :) ) formula evalutaor )
+// author : Mateusz Malczak ( mateusz@malczak.info )
+// wpage : www.segfaultlabs.com/projects/sffe
+///////////////////////////////////////////////////////////////////////////////////////
+// special build for XaoS, for more info visit
+// http://www.segfaultlabs.com/projects/sfXaos
+/////////////////////////////////////////////////////////////////////////////////////*/
+
+#include <config.h>
+#ifdef SFFE_CMPLX_GSL
+
+#include "sffe.h"
+#include "sffe_cmplx_gsl.h"
+#include <gsl/gsl_complex.h>
+#include <gsl/gsl_complex_math.h>
+#include <math.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ const sffunction sfcmplxfunc[sffnctscount] = {
+ /* nie uwzgledniaj w wyszukaniu funkcji */
+ {sfpow, 2, "^\0"}, {sfadd, 2, "+\0"}, {sfsub, 2, "-\0"}, {sfmul, 2,
+ "*\0"},
+ {sfdiv, 2, "/\0"},
+ /* ponizej uwzgledniaj w wyszukaniu funkcji */
+ {sfsin, 1, "SIN\0"}, {sfcos, 1, "COS\0"}, {sftan, 1, "TAN\0"},
+ {sfcot, 1, "COT\0"},
+ {sfasin, 1, "ASIN\0"}, {sfacos, 1, "ACOS\0"}, {sfatan, 1,
+ "ATAN\0"}, {sfacot,
+ 1,
+ "ACOT\0"},
+ {sfatan2, 2, "ATAN2\0"},
+ {sfsinh, 1, "SINH\0"}, {sfcosh, 1, "COSH\0"}, {sftanh, 1,
+ "TANH\0"}, {sfcoth,
+ 1,
+ "COTH\0"},
+ {sfexp, 1, "EXP\0"}, {sflog, 1, "LOG\0"}, {sflog10, 1, "LOG10\0"},
+ {sflog2, 1, "LOG2\0"},
+ {sflogN, 2, "LOGN\0"}, {sflogN, 2, "LOGCN\0"},
+ /*power functions */
+ {sfpow, 2, "POW\0"}, {sfpowd, 2, "POWD\0"}, {sfpow, 2, "POWI\0"},
+ {sfpow, 2, "POWDC\0"},
+ {sfsqr, 1, "SQR\0"}, {sfsqrt, 1, "SQRT\0"}, {sfrtni, 3, "RTNI"},
+ {sfinv, 1, "INV\n"},
+ {sfceil, 1, "CEIL\0"}, {sffloor, 1, "FLOOR\0"}, {sfabs, 1,
+ "ABS\0"}, {sfrabs,
+ 1,
+ "RABS\0"},
+ {sfre, 1, "RE\0"}, {sfim, 1, "IM\0"},
+ {NULL, 1, "RAD\0"}, {NULL, 1, "DEG\0"},
+ {NULL, 1, "SIGN\0"}, {NULL, 1, "TRUNC\0"}, {sfrand, 1, "RAND\0"}
+ };
+
+ const char sfcnames[sfvarscount][5] =
+ { "PI\0", "PI_2\0", "PI2\0", "E\0", "I\0", "RND\0" };
+
+ const cfptr sfcvals[sfvarscount] =
+ { sfcPI, sfcPI2, sfc2PI, sfcE, sfcI, sfcRND };
+
+ sfarg *sfadd(sfarg * const p) { /* + */
+ sfvalue(p) =
+ gsl_complex_add(sfvalue(sfaram2(p)), sfvalue(sfaram1(p)));
+ return sfaram2(p);
+ };
+
+ sfarg *sfsub(sfarg * const p) { /* - */
+ sfvalue(p) =
+ gsl_complex_sub(sfvalue(sfaram2(p)), sfvalue(sfaram1(p)));
+ return sfaram2(p);
+ };
+
+ sfarg *sfmul(sfarg * const p) { /* * */
+ sfvalue(p) =
+ gsl_complex_mul(sfvalue(sfaram2(p)), sfvalue(sfaram1(p)));
+ return sfaram2(p);
+ };
+
+ sfarg *sfdiv(sfarg * const p) { /* / */
+ sfvalue(p) =
+ gsl_complex_div(sfvalue(sfaram2(p)), sfvalue(sfaram1(p)));
+ return sfaram2(p);
+ };
+
+
+ sfarg *sfsin(sfarg * const p) { /* sin */
+ sfvalue(p) = gsl_complex_sin(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sfcos(sfarg * const p) { /* cos */
+ sfvalue(p) = gsl_complex_cos(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sftan(sfarg * const p) { /* tan */
+ sfvalue(p) = gsl_complex_tan(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sfcot(sfarg * const p) { /* ctan */
+ sfvalue(p) = gsl_complex_cot(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+
+ sfarg *sfasin(sfarg * const p) { /* asin */
+ sfvalue(p) = gsl_complex_arcsin(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sfacos(sfarg * const p) { /* acos */
+ sfvalue(p) = gsl_complex_arccos(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sfatan(sfarg * const p) { /* atan */
+ sfvalue(p) = gsl_complex_arctan(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sfacot(sfarg * const p) { /* actan */
+ sfvalue(p) = gsl_complex_arccot(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sfatan2(sfarg * const p) { /* atan2 */
+ return sfaram2(p);
+ };
+
+ sfarg *sfsinh(sfarg * const p) { /* sinh */
+ sfvalue(p) = gsl_complex_sinh(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sfcosh(sfarg * const p) { /* cosh */
+ sfvalue(p) = gsl_complex_cosh(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sftanh(sfarg * const p) { /* tanh */
+ sfvalue(p) = gsl_complex_tanh(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sfcoth(sfarg * const p) { /* ctanh */
+ sfvalue(p) = gsl_complex_coth(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+
+ sfarg *sfexp(sfarg * const p) { /* exp */
+ sfvalue(p) = gsl_complex_exp(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sflog(sfarg * const p) { /* log */
+ sfvalue(p) = gsl_complex_log(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sflog10(sfarg * const p) { /* log10 */
+ sfvalue(p) = gsl_complex_log10(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sflog2(sfarg * const p) { /* log2 */
+ sfNumber base;
+ real(base) = 2;
+ imag(base) = 0;
+ sfvalue(p) = gsl_complex_log_b(sfvalue(sfaram1(p)), base);
+ return sfaram1(p);
+ };
+
+ sfarg *sflogN(sfarg * const p) { /* logN */
+ sfvalue(p) =
+ gsl_complex_log_b(sfvalue(sfaram1(p)), sfvalue(sfaram2(p)));
+ return sfaram2(p);
+ };
+
+
+ sfarg *sfpow(sfarg * const p) { /* cmplx pow */
+ sfvalue(p) =
+ gsl_complex_pow(sfvalue(sfaram2(p)), sfvalue(sfaram1(p)));
+ return sfaram2(p);
+ };
+
+ sfarg *sfpowd(sfarg * const p) { /* int pow */
+ sfvalue(p) =
+ gsl_complex_pow_real(sfvalue(sfaram2(p)),
+ GSL_REAL(sfvalue(sfaram1(p))));
+ return sfaram2(p);
+ };
+
+ sfarg *sfsqr(sfarg * const p) { /* sqr */
+ sfvalue(p) =
+ gsl_complex_pow(sfvalue(sfaram1(p)), sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sfsqrt(sfarg * const p) { /* sqrt */
+ sfvalue(p) = gsl_complex_sqrt(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sfrtni(sfarg * const p) { /* rtni */
+ double nrz =
+ pow(gsl_complex_abs(sfvalue(sfaram3(p))),
+ 1.0 / (double) (int) real(sfvalue(sfaram2(p))));
+ double alfi =
+ (gsl_complex_arg(sfvalue(sfaram3(p))) +
+ 8 * atan(1.0) * (double) (int) real(sfvalue(sfaram1(p)))) /
+ (double) (int) real(sfvalue(sfaram2(p)));
+
+ cmplxset(sfvalue(sfaram3(p)), nrz * cos(alfi), nrz * sin(alfi));
+ return sfaram3(p);
+ };
+
+ sfarg *sfinv(sfarg * const p) { /* cinv */
+ sfvalue(p) = gsl_complex_inverse(sfvalue(sfaram1(p)));
+ return sfaram1(p);
+ };
+
+ sfarg *sfceil(sfarg * const p) { /* ceil */
+ //sfvalue(p) = ceil( sfvalue( sfaram1(p) ) );
+ return sfaram1(p);
+ };
+
+ sfarg *sffloor(sfarg * const p) { /* floor */
+ //sfvalue(p) = floor( sfvalue( sfaram1(p) ) );
+ return sfaram1(p);
+ };
+
+ sfarg *sfabs(sfarg * const p) { /* abs - |z| */
+ GSL_REAL(sfvalue(p)) = gsl_complex_abs(sfvalue(sfaram1(p)));
+ GSL_IMAG(sfvalue(p)) = 0.0;
+ return sfaram1(p);
+ };
+
+ sfarg *sfrabs(sfarg * const p) { /* abs - real numbers */
+ GSL_REAL(sfvalue(p)) = GSL_REAL(sfvalue(sfaram1(p)));
+ if (GSL_REAL(sfvalue(p)) < 0)
+ GSL_REAL(sfvalue(p)) = -GSL_REAL(sfvalue(p));
+ GSL_IMAG(sfvalue(p)) = 0;
+ return sfaram1(p);
+ };
+
+ sfarg *sfre(sfarg * const p) { /* RE */
+ GSL_REAL(sfvalue(p)) = GSL_REAL(sfvalue(sfaram1(p)));
+ GSL_IMAG(sfvalue(p)) = 0.0;
+ return sfaram1(p);
+ };
+
+ sfarg *sfim(sfarg * const p) { /* IM */
+ GSL_REAL(sfvalue(p)) = GSL_IMAG(sfvalue(sfaram1(p)));
+ GSL_IMAG(sfvalue(p)) = 0.0;
+ return sfaram1(p);
+ };
+
+ sfarg *sfrand(sfarg * const p) { /* rand */
+ GSL_REAL(sfvalue(p)) =
+ GSL_REAL(sfvalue(sfaram1(p))) * (double) rand() /
+ (double) RAND_MAX;
+ GSL_IMAG(sfvalue(p)) = 0;
+ return sfaram1(p);
+ };
+
+//const eval
+ void sfcPI(sfNumber * cnst) {
+ GSL_SET_COMPLEX(cnst, 4 * atan(1), 0);
+ };
+ void sfcPI2(sfNumber * cnst) {
+ GSL_SET_COMPLEX(cnst, 2 * atan(1), 0);
+ };
+ void sfc2PI(sfNumber * cnst) {
+ GSL_SET_COMPLEX(cnst, 8 * atan(1), 0);
+ };
+ void sfcE(sfNumber * cnst) {
+ GSL_SET_COMPLEX(cnst, exp(1), 0);
+ };
+ void sfcI(sfNumber * cnst) {
+ GSL_SET_COMPLEX(cnst, 0, 1);
+ };
+ void sfcRND(sfNumber * cnst) {
+ GSL_SET_COMPLEX(cnst, rand(), 0);
+ };
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif