> "Michael Haufe (TNO)" wrote in message
> news:4a1c28ea-447b-4e9b...@googlegroups.com...
>> On Saturday, June 11, 2016 at 12:52:43 PM UTC-5, Chris M. Thomasson
>> wrote:
>> I created a little complex number library for some new
>> fractal encryption techniques I am going to put online.
>> I am a bit worried about all of the arrays I am using in
>> the following code:
>> ______________________________
>> "use strict";
[...]
>> function ct_complex_mul(c0, c1)
>> {
>> return [c0[0] * c1[0] - c0[1] * c1[1],
>> c0[0] * c1[1] + c0[1] * c1[0]];
>> }
[...]
>> function ct_complex_pow(c, p)
>> {
>> var l = ct_complex_abs(c);
>> var s = Math.pow(l, p);
>> var a = Math.atan2(c[1], c[0]) * p;
>>
>> return [Math.cos(a) * s, Math.sin(a) * s];
>> }
>>
>> function ct_complex_roots(c, p)
>> {
>> var l = ct_complex_abs(c);
>> var s = Math.pow(l, 1.0 / p);
>> var a = Math.atan2(c[1], c[0]) / p;
>>
>> var n = Math.ceil(Math.abs(p));
>> var as = (Math.PI * 2) / p;
>> var roots = [];
>>
>> for (var i = 0; i < n; ++i)
>> {
>> roots.push([Math.cos(a + as * i) * s,
>> Math.sin(a + as * i) * s]);
>> }
>>
>> return roots;
>> }
>> ______________________________
>>
>>
>> If I call any of the functions above in a large
>> iteration, will memory start to explode and stress
>> out the garbage collector?
[...]
> Potentially, yes.
Yup. I agree. Its behaving okay for some stuff, but
I do not trust it under prolonged sustained load.
> You want to avoid the intermediate data structures
> obviously, but the question is how? Sadly since
> JavaScript uses CBV evaluation semantics, you won't
> get any help there [1]. Which means it's up to you
> to do some creative thinking in your data structures.
Agreed. For instance, intrusive function design should
work well here. Lets focus on converting the functional
complex multiplication function:
_______________________________________
>> function ct_complex_mul(c0, c1)
>> {
>> return [c0[0] * c1[0] - c0[1] * c1[1],
>> c0[0] * c1[1] + c0[1] * c1[0]];
>> }
_______________________________________
into an intrusive form:
_______________________________________
function ct_complex_mul(c0, c1)
{
var x = c0[0] * c1[0] - c0[1] * c1[1];
c0[1] = c0[0] * c1[1] + c0[1] * c1[0];
c0[0] = x;
return c0;
}
_______________________________________
Now, this will modify (c0), effectively turning it into
an input/output parameter. To call it in a loop could
look like:
_______________________________________
function foo_with_intrusive()
{
var z = [1, 1];
var c = [2, 2];
for (var i = 0; i < 10; ++i)
{
z = ct_complex_mul(z, c);
}
}
_______________________________________
Also, we can do this another way that involves an explicit
output parameter to the function. Something like:
_______________________________________
function ct_complex_mul(c0, c1, out)
{
out[0] = c0[0] * c1[0] - c0[1] * c1[1];
out[1] = c0[0] * c1[1] + c0[1] * c1[0];
return out;
}
_______________________________________
To call it in a loop could look like:
_______________________________________
function foo_with_out()
{
var out = [0, 0];
var z = [1, 1];
var c = [2, 2];
for (var i = 0; i < 10; ++i)
{
out = ct_complex_mul(z, c);
z[0] = out[0];
z[1] = out[1];
}
}
_______________________________________
Notice that both approaches have caveats, but both of them
will not have a chance to create a shi% load of objects!
Do you have some better ideas here?
> Looking at what you have thus far, I don't think
> there is much you can do to improve things at this
> level of discourse, at best I think you might get a
> constant factor speedup at the significant expense
> of readability. (Bit fiddling and Math.foo()
> alternatives...)
FWIW, check out this sqrt estimation algorithm:
http://forums.parallax.com/discussion/147522/dog-leg-hypotenuse-approximation
;^)
> I think what I would do is evaluate how the application
> is developing and at that stage try to discover some
> form of higher level rules that you can exploit. For
> example, for manipulating sums:
> 1 + 2 + 3 + ... + n = (n*(n+1)) / 2
Indeed.
> Another thought is to switch to polar coordinates
> instead of Cartesian coordinates as it would simplify
> multiplication and division at least. With fractal based
> work this might be more intuitive anyway, yes?
Right. However, I think that converting Polar into Cartesian
in order to add/subtract is the simplest route correct?