Is the stack limit of 5287 in AS3 variable or predefined? - actionscript-3

I ran a test just now:
function overflow(stack:int = 0):void
{
if(stack < 5290)
{
trace(stack);
overflow(stack + 1);
}
}
overflow();
This always throws a StackOverflow error after 5287 calls.
Error #1023: Stack overflow occurred.
Is this limit variable (depending on machine specs, environment, etc) or is that a flat value defined somewhere? If I change the if statement to less than 5287, I don't get the error.

Obviously it's variable. Since all the calculations you really do are located in stack (disassembly report codes show pushbyte instructions and other stuff that's working with stack, as non-operand arithmetics), this value only reports how many function contexts can be put into the stack until it overflows.
I have decided to run some tests for recursion thresholds as based on this article that was referenced in baris's comment. The results were pretty embarrassing. Test environment: FlashDevelop 3.3.4 RTM, Flash player debugger 10.1.53.64, flash compile mode: release. "Debug" mode didn't change numbers cardinally, checked that too.
Locals number Iterations (static int) Iterations (Math.random())
0 5306
1 4864 4856
2 4850 4471
3 4474 4149
4 4153 3870
5 3871 3868
6 3869 3621
7 3620 3404
8 3403 3217
9 3210 3214
10 3214 3042
11 3042 3045
10 mixed 3042 1 value was assigned Math.random() and 9 - static int
10 advancedRandom 2890 1 value was assigned a custom random with 1 parameter
Note, all of these values vary within a margin of ten between subsequent executions. The "static int" and "Math.random()" are designations of what is assigned to locals wihin the recursively called function. This, however, leads me to assume the following:
Including function calls into the recursive function adds to function context
Memory for locals is assigned along with its type, in chunks of more than 8 bytes, because adding a local does not always decrease recursion limit
Adding more than one call to a certain function does not add more memory to function context
The "memory chunk" is most likely 16 bytes long, because this value is 2^N, an addition of one int or Number local does not always decrease recursion, and this is more than 8, as a raw value of a Number variable takes 8 bytes, being a double-precision floating-point.
Assuming #4 is correct, the best value for function context size appeared to be 172 bytes, with total stack size being 912632 bytes. This largely confirms my initial assumption that the stack size is actually 1 megabyte in Flash 10. Flash 11 showed me a bit higher numbers when I have tried opening the test SWF in its debugger, but I didn't make extensive tests with it.

Hm, this is interesting. I took a look at the link that Barış gave. It seems like it might be to be with 'method complexity' after all, but I am not sure how to further test it. I am using Flash CS5, publishing for Flash Player 10, Actionscript 3 (of course).
Original:
function overflow(stack:int = 0):void {
if(stack < 5290){
trace(stack);
overflow(stack + 1);
}
}
// gives 5287
Now adding a single Math.random() call to the overflow() method:
function overflow(stack:int = 0):void {
Math.random();
if(stack < 5290){
trace(stack);
overflow(stack + 1);
}
}
// gives 4837
Adding multiple Math.random() calls make no difference, nor does storing it in a local variable or adding another parameter to the overflow() method to 'carry' that random generated value
function overflow(stack:int = 0):void {
Math.random();
Math.random();
if(stack < 5290){
trace(stack);
overflow(stack + 1);
}
}
// still gives 4837
At this point I tried different Math calls, such as:
// just the change to that 1 line:
Math.pow() // gives 4457
Math.random(), Math.sqrt(), Math.tan(), Math.log() // gives 4837
Interestingly, it doesn't seem to matter what you pass in to the Math class, but it remains constant:
Math.sqrt(5) vs Math.sqrt(Math.random()) // gives 4837
Math.tan(5) vs Math.tan(Math.random()) // gives 4837
Math.pow(5, 7) vs Math.pow(Math.random(), Math.random()) // 4457
Until I chained 3 of them:
Math.tan(Math.log(Math.random())); // gives 4457
It looks like two Math calls from that 'group' is "equal" to one Math.pow() call? =b Mixing Math.pow() and something else doesn't seem to decrease the value though:
Math.pow(Math.random(), Math.random()); // gives 4457
However, chaining two Math.pow()'s:
Math.pow(Math.pow(Math.random(), Math.random()), Math.random()); // 4133
I could go on and on, but I wonder if there is some pattern:
Results: 5287, 4837, 4457, 4133
Differences: 450 380 324

Musst be variable! Just compiled your sample and i get to 5274 before stack overflow.
#baris thats for the mxmlc compiler
+1 for stack overflow question ^^

Related

Composite trapezoid rule not running in Octave

I have the following code in Octave for implementing the composite trapezoid rule and for some reason the function only stalls whenever I execute it in Octave on f = #(x) x^2, a = 0, b = 4, TOL = 10^-6. Whenever I call trapezoid(f, a, b, TOL), nothing happens and I have to exit the Terminal in order to do anything else in Octave. Here is the code:
% INPUTS
%
% f : a function
% a : starting point
% b : endpoint
% TOL : tolerance
function root = trapezoid(f, a, b, TOL)
disp('test');
max_iterations = 10000;
disp(max_iterations);
count = 1;
disp(count);
initial = (b-a)*(f(b) + f(a))/2;
while count < max_iterations
disp(initial);
trap_0 = initial;
trap_1 = 0;
trap_1_midpoints = a:(0.5^count):b;
for i = 1:(length(trap_1_midpoints)-1)
trap_1 = trap_1 + (trap_1_midpoints(i+1) - trap_1_midpoints(i))*(f(trap_1_midpoints(i+1) + f(trap_1_midpoints(i))))/2;
endfor
if abs(trap_0 - trap_1) < TOL
root = trap_1;
return;
endif
intial = trap_1;
count = count + 1;
disp(count);
endwhile
disp(['Process ended after ' num2str(max_iterations), ' iterations.']);
I have tried your function in Matlab.
Your code is not stalling. It is rather that the size of trap_1_midpoints increases exponentionaly. With that the computation time of trap_1 increases also exponentionaly. This is what you experience as stalling.
I also found a possible bug in your code. I guess the line after the if clause should be initial = trap_1. Check the missing 'i'.
With that, your code still takes forever, but if you increase the tolerance (e.g. to a value of 1) your code return.
You could try to vectorize the for loop for speed up.
Edit: I think inside your for loop, a ) is missing after f(trap_1_midpoints(i+1).
After count=52 or so, the arithmetic sequence trap_1_midpoints is no longer representable in any meaningful fashion in floating point numbers. After count=1075 or similar, the step size is no longer representable as a positive floating point double number. That all is to say, the bound max_iterations = 10000 is ludicrous. As explained below, all computations after count=20 are meaningless.
The theoretical error for stepsize h is O(T·h^2). There is a numerical error accumulation in the summation of O(T/h) numbers that is of that size, i.e., O(mu/h) with mu=1ulp=2^(-52). Which in total means that the lowest error of the numerical integration can be expected around h=mu^(1/3), for double numbers thus h=1e-5 or in the algorithm count=17. This may vary with interval length and how smooth or wavy the function is.
One can expect the behavior that the error divides by four while halving the step size only for step sizes above this boundary 1e-5. This also means that abs(trap_0 - trap_1) is a reliable measure for the error of trap_0 (and abs(trap_0 - trap_1)/3 for trap_1) only inside this range of step sizes.
The error bound TOL=1e-6 should be met for about h=1e-3, which corresponds to count=10. If the recursion does not stop for count = 14 (which should give an error smaller than 1e-8) then the method is not accurately implemented.

Trying to find a way to construct Julia `generator`

I'm new to Julia.
I mainly program in python.
In python,
if you want to iterate over a large set of values,
it is typical to construct a so-called generator to save memory usage.
Here is one example code:
def generator(N):
for i in range(N):
yield i
I wonder if there is anything alike in Julia.
After reading julia manual,
#task macro seems to have the same (or similar) functionality as generator in python.
However,
after some experiments,
the memory usage seems to be larger than usual array in julia.
I use #time in IJulia to see the memory usage.
Here is my sample code:
[Update]: Add the code for generator method
(The generator method)
function generator(N::Int)
for i in 1:N
produce(i)
end
end
(generator version)
function fun_gener()
sum = 0
g = #task generator(100000)
for i in g
sum += i
end
sum
end
#time fun_gener()
elapsed time: 0.420731828 seconds (6507600 bytes allocated)
(array version)
function fun_arry()
sum = 0
c = [1:100000]
for i in c
sum += i
end
sum
end
#time fun_arry()
elapsed time: 0.000629629 seconds (800144 bytes allocated)
Could anyone tell me why #task will require more space in this case?
And if I want to save memory usage as dealing with a large set of values,
what can I do?
I recommend the "tricked out iterators" blogpost by Carl Vogel, which discusses julia's iterator protocol, tasks and co-routines in some detail.
See also task-aka-coroutines in the julia docs.
In this case you should use the Range type (which defines an iterator protocol):
julia> function fun_arry()
sum = 0
c = 1:100000 # remove the brackets, makes this a Range
for i in c
sum += i
end
sum
end
fun_arry (generic function with 1 method)
julia> fun_arry() # warm up
5000050000
julia> #time fun_arry()
elapsed time: 8.965e-6 seconds (192 bytes allocated)
5000050000
Faster and less memory allocated (just like xrange in python 2).
A snippet from the blogpost:
From https://github.com/JuliaLang/julia/blob/master/base/range.jl, here’s how a Range’s iterator protocol is defined:
start(r::Ranges) = 0
next{T}(r::Range{T}, i) = (oftype(T, r.start + i*step(r)), i+1)
next{T}(r::Range1{T}, i) = (oftype(T, r.start + i), i+1)
done(r::Ranges, i) = (length(r) <= i)
Notice that the next method calculates the value of the iterator in state i. This is different from an Array iterator, which just reads the element a[i] from memory.
Iterators that exploit delayed evaluation like this can have important performance benefits. If we want to iterate over the integers 1 to 10,000, iterating over an Array means we have to allocate about 80MB to hold it. A Range only requires 16 bytes; the same size as the range 1 to 100,000 or 1 to 100,000,000.
You can write a generator method (using Tasks):
julia> function generator(n)
for i in 1:n # Note: we're using a Range here!
produce(i)
end
end
generator (generic function with 2 methods)
julia> for x in Task(() -> generator(3))
println(x)
end
1
2
3
Note: if you replace the Range with this, the performance is much poorer (and allocates way more memory):
julia> #time fun_arry()
elapsed time: 0.699122659 seconds (9 MB allocated)
5000050000
This question was asked (and answered) quite a while ago. Since this question is ranked high on google searches, I'd like to mention that both the question and answer are outdated.
Nowadays, I'd suggest checking out https://github.com/BenLauwens/ResumableFunctions.jl for a Julia library with a macro that implements Python-like yield generators.
using ResumableFunctions
#resumable function fibonnaci(n::Int) :: Int
a = 0
b = 1
for i in 1:n-1
#yield a
a, b = b, a+b
end
a
end
for fib in fibonnaci(10)
println(fib)
end
Since its scope is much more limited than full coroutines, it is also an order of magnitude more efficient than pushing values into a channel since it can compile the generator into a FSM. (Channels have replaced the old produce() function mentioned in the question and previous answers).
With that said, I'd still suggest pushing into a channel as your first approach if performance isn't an issue, because resumablefunctions can sometimes be finicky when compiling your function and can occasionally hit some worst-case behaviour. In particular, because it is a macro that compiles to an FSM rather than a function, you currently need to annotate the types of all variables in the Resumablefunction to get good performance, unlike vanilla Julia functions where this is handled by JIT when the function is first called.
I think that Task has been superseded by Channel(). The usage in terms of Ben Lauwens's Fibonacci generator is:
fibonacci(n) = Channel(ctype=Int) do c
a = 1
b = 1
for i in 1:n
push!(c, a)
a, b = b, a + b
end
end
it can be used using
for a in fibonacci(10)
println(a)
end
1
1
2
3
5
8
13
21
34
55

How can I record sound with 16 bits per sample (16 bit depth)?

I try to record PCM sound from flash (using Microphone class). I use org.bytearray.micrecorder.MicRecorder helper class.
In Microphone class I cannot find property like bitDepth or bitsPerSample.
I always get 32 bits.
Is it possible to do?
UPDATE: The asker John812 was able to solve this by using..
bit16_bytes.writeShort( data.readFloat() * 32767 ); see comments below for context
METHOD #2: Based on my experience with using the LoadPCMfromByteArray method
I have something you could try but I've only used it with an actual 32bit WAVE file and played via the LoadPCMFromByteArray command.
The AS3 Microphone Class records 32 bits. You have to write the conversion of samples to a different bit-depth by yourself. I have no idea how many samples you are processing but the general code below shows you how to convert. Note: * 512 means use your actual samples amount (example: * 4096? or * 8192?) If you get the numbers wrong there'll be hiss/distortion so either experiment from small or provide the full details in your question for a more helpful edit/answer.
CONVERT: Assuming your recorded byteArray is called data
public var bit16_bytes : ByteArray; //will hold the 16bit version
public function convert_to16Bit () : void
{
bit16_bytes = new ByteArray(); data.position = 0;
while (bit16_bytes.position < data.length - 4)
//if you get noise/distortion try either: 256, 512, 1024, 2048, 4096 or 8192
{ bit16_bytes.writeShort( data.readInt() * 512 ); } //multiply by samples amount
data = new ByteArray(); //recycle for re-use
bit16_bytes.position = 0; //reset or else E-O-File error
bit16_bytes.readBytes( data ); //copy 16bit back into Data byte-array
}
To run the above function whenever you're ready just add the line convert_to16Bit(); inside whatever function deals with your "recording complete" situation.

AS3: Perform action in intervals based on incrementing int

So as not to complicate my question, I won't involve the context, but basically let's say I have a variable:
var foo:int;
And 'foo' is constantly incrementing, how would I be able to perform a function every 300 increments (300,600,900, etc) of 'foo'?
Cheers
EDIT: Also worth mentioning, the number can occasionally skip numbers as it is a rounded version of a decimal number that is incrementing
What about making it a private variable and only acces it using these accessor methods:
function getFoo():int {
return foo;
}
function setFoo(newFoo:int):void {
if (newFoo % 300 > foo % 300) performAction();
foo = newFoo;
}
You could also add convenience methods like incrementFoo(increment:int) of course.
Sorry for possible syntax errors. I haven't used AS3 for quite a while.

Matlab | Matrix Function of Several Variables

I'm working on Matlab and I need to define a matrix function that depends on several variables.
For example, I have this vectors:
t=[1,2,3,4,5,6,7,8,9,10]
y=[1,2,3,4,5,6,7,8,9,10]
That can contain any real numbers or have any length (same length for t and y, I called it NumData).
I have a function that depends on some parameters P1, P2,...,P5. What I want to do is to form a Matrix (NumData x 5) that depends of p, a vector of parameters:
I don't know how to step further. I thought of define a Matrix:
Matrix = ones(NumData,NumParameters)
But when I try to assign, for example
Matrix(1,3) = p(1)+3*p(2)
I got an error.
I tried to define:
Matrix(1,3)=#(p) p(1)+3*p(2)
But it's useless...
I tried to define the matrix in code, like this:
J=#(p) [1 1 1 exp(-p(5)) -p(4)*exp(-p(5))
1 2 4 exp(-2*p(5)) -p(4)*exp(-2*p(5))
1 3 9 exp(-3*p(5)) -p(4)*exp(-3*p(5))
1 4 16 exp(-4*p(5)) -p(4)*exp(-4*p(5))
1 5 25 exp(-5*p(5)) -p(4)*exp(-5*p(5))]
but it isn't good because this is for a specific case...
My main goal is to form J from t vector, and that J depends on the vector parameter p so I can evaluate later
A= J(1,2,1,2,2)
for example, and then factorize A as QR.
Do you have any suggestions? Or I am asking too much for Matlab?
I'm not 100% sure of what you are trying to do, but let me give you some examples of things that will work, in the hopes that it can help you a bit.
p=[1 2 3 4 5];
M=zeros(3,2);
M=[p(1) p(2) p(5); p(3)/p(2) p(5)^p(2) exp(p(3))]