Page 5 of 7

Re: Stream FFT and iFFT

PostPosted: Sun Jun 23, 2013 6:51 pm
by digitalwhitebyte
@MyCo

I updated the code(same post), it was wrong, now working,
but the approximation seems to be not good, still too high,
in the meantime I'm trying other solutions.

Re: Stream FFT and iFFT

PostPosted: Mon Jun 24, 2013 12:44 pm
by digitalwhitebyte
Code: Select all
// Range of x [0,1]
// The maximum error is about 8*10^(-10).
x = @ins[0].to_f
y = 2*x-1
atan = 0.0318159928972*y+0.950551425796+3.86835495723/(y+8.05475522951+
    39.4241153441/(y-2.08140771798-0.277672591210/(y-8.27402153865+
    95.3157060344/(y+10.5910515515))))
output 0, atan


Sounds great, except for the 4 division in the main code.
Now I try to take it in ASM, and we shall see what is suitable for the cpu.

Re: Stream FFT and iFFT

PostPosted: Mon Jun 24, 2013 12:58 pm
by martinvicanek
DWB, in your last post you can rearrange the expression so you get only one division of two polynomials. May or may not be faster.

Re: Stream FFT and iFFT

PostPosted: Mon Jun 24, 2013 1:02 pm
by Nubeat7
awesome what you`re doing here guys! i`m a bloody beginner in this area but you really motivate me to read and try to understand all this fourier transforming,

to bring a little part too i optimized mycos window options, maybe here and there it could be done better but most of the stuff should be optimized fine

Re: Stream FFT and iFFT

PostPosted: Mon Jun 24, 2013 2:02 pm
by digitalwhitebyte
martinvicanek wrote:DWB, in your last post you can rearrange the expression so you get only one division of two polynomials. May or may not be faster.


here is where we see your skill. :twisted:
hehe, a little help? :mrgreen:

Re: Stream FFT and iFFT

PostPosted: Mon Jun 24, 2013 5:22 pm
by MyCo
DWBs new atan code is really good. In the 0..1 range I can't measure any error. Outside of that it's not very exact. But maybe we can use trig. identities to flip any input into the 0..1 input range. This should get us very close to a real atan.

@Nubeat: Thanks for your work. I know that this wasn't any fun, that's why I avoided that.

Re: Stream FFT and iFFT

PostPosted: Mon Jun 24, 2013 6:27 pm
by MyCo
here is the simplified version for DWBs atan:
Code: Select all
def atan(x)
   ax = x.abs
   num = 1.93417747861 * (ax**3 - 1.3821888526*ax**2 + 1.2783790120*ax - 2.785730712)
   denum = ax**4 + 2.1451887622*ax**3 + 6.258905830*ax**2 + 3.285923272*ax + 5.86468903
   linear = 0.0636319857944*ax + 0.918735432899
   res = linear + num / denum
   
   res = -res if (x<0)
   return res
end

if (@x.abs>1)
   output(0, ((@x>0) ? 1 : -1)*Math::PI*0.5 - atan(1.0/@x))
else
   output(0, atan(@x))
end


maybe there is a little room for further optimization

Re: Stream FFT and iFFT

PostPosted: Mon Jun 24, 2013 9:37 pm
by MyCo
OK, here is the current setup. I converted everything that I've found into code. DWBs new one is also in there. I've used the trig. identities to make it work full range. The results from this one are the best, although it's not the fastest.

So, any ideas to optimize the code of it? Maybe there are chances to minimize the error, just by rearranging. The Ruby version doesn't have that much error, as the code version. This comes from rounding (Ruby uses double precision), so maybe this rounding error can be reduced.

Re: Stream FFT and iFFT

PostPosted: Tue Jun 25, 2013 2:52 am
by digitalwhitebyte
Code: Select all
// Range [0,1] |error| ~ 3.2e-7
streamin x;
streamout arctan;
float num,denum;

num = 0.05030176425872175099 *
   (-6.9888366207752135 + x) *
(3.14559995508649281e-7 + x) *
        (2.84446368839622429 +
        0.826399783297673451 *
                      x + x*x);
denum = (1 + 0.1471039133652469065841349249  * x +
               0.644464067689154755092299698 * x*x);
arctan = num / denum * -1;


maybe this seems to be a good compromise between accuracy and speed.

Re: Stream FFT and iFFT

PostPosted: Tue Jun 25, 2013 3:24 am
by MyCo
I've done all the conversion stuff (and code optimization) already for your other version. The error is very low, and I've added it to the stream FFT project... where I measure the error of forward and inverse conversion. The max. error there is 88dB so far.

I've attached to current status. The atan2 code is in the "To phase" module, and isn't converted into assembler right now. To test the whole thing, you have to load in a Wave or MP3 into the stream player.