CoffeeScript 2 Dimensional Array Usage - coffeescript

I feel like I'm missing something with CoffeeScript and 2 dimensional arrays. I'm simply attempting to make a grid of spaces (think checkers). After some searching and a discovery with the arrays.map function, I came up with this:
#spaces = [0...20].map (x)->
[0...20].map (y) ->
new Elements.Space()
And this seems to work great, I have a nice 2 dimensional array with my Space object created in each. But now I want to send the created space constructor the x,y location. Because I'm two layers deep, I lost the x variable when I entered the map function for y.
Ideally I would want to do something like:
#spaces = [0...20].map (x)->
[0...20].map (y) ->
new Elements.Space(x, y)
or something that feels more natural to me like:
for row in rows
for column in row
#spaces[row][column] = new Elements.Space(row, column)
I'm really open to any better way of doing this. I know how I would do it in standard JavaScript, but really would like to learn how to do it in CoffeeScript.

Your first attempt with map is a valid way to do it. You don't actually lose x, because closures. So there's nothing wrong with your second code block:
#spaces = [0...20].map (x)->
[0...20].map (y) ->
new Elements.Space(x, y)
The for loop version of this is also pretty simple:
#spaces = for x in [0...20]
for y in [0...20]
new Elements.Space(x, y)
Remember, everything is an expression. So this works (and might be a bit clearer than the map version).

Related

Equivalent for (:) for slices of higher dimension matrices

Context
You have a 3D variable A
rng('default')
A = randi(100,5,7,3);
Problem
You want to get a column vector with all the values of a given slice along the third dimension of A, e.g.
Tmp = A(:,:,2);
out = Tmp(:);
Question
Is there a built in way to do this directly without having to use a temporary variable or a function (i.e. with a combination of brackets, ...)? The closest to what I look for I have found yet would be
out = reshape(A(:,:,2),[],1)
Which I find a bit "heavy". I was looking for something like (A(:,:,2))(:) but it doesn't work in MATLAB.
The fact that they added the input all in functions like any would suggest that there is not but I figured I'd still ask

Declaring a functional recursive sequence in Matlab

I'd like to declare first of all, that I'm a mathematician. This might be a stupid stupid question; but I've gone through all the matlab tutorials--they've gotten me nowhere. I imagine I could code this in C (it'd be exhausting); but I need matlab for this particular function. And I don't get exactly how to do it.
Here is the pasted Matlab code of where I'm running into trouble:
function y = TAU(z,n)
y=0;
for i =[1,n]
y(z) = log(beta(z+1,i) + y(z+1)) - beta(z,i);
end
end
(beta is an arbitrary "float" to "float" function with an index i.)
I'm having trouble declaring y as a function, in which we call the function at a different argument. I want to define y_n(z) with something something y_{n-1}(z+1). This is all done in a recursive process to create the function. I really feel like I'm missing something stupid.
As a default function it assigns y to be an array (or whatever you call the default index assignment). But I don't want an array. I want y to be assigned as a "function" class (i.e. takes "float" to "float"). And then I'm defining a sequence of y_n : "float" to "float". So that z to z+1 is a map on "float" to "float".
I don't know if I'm asking too much of matlab...
Help a poor mathematician who hasn't coded since the glory days of X-box mods.
...Please don't tell me I have to go back to Pari-GP/C drawing boards over something so stupid.
Please help!
EDIT: At rahnema1 & mimocha's request, I'll describe the math, and of what I am trying to do with my program. I can't see how to implement latex in here. So I'll write the latex code in a generator and upload a picture. I'm not so sure if there even is a work around to what I want to do.
As to the expected output. We'd want,
beta(z+1,i) + TAU(z+1,i) = exp(beta(z,i) + TAU(z,i+1))
And we want to grow i to a fixed value n. Again, I haven't programmed in forever, so I apologize if I'm speaking a little nonsensically.
EDIT2:
So, as #rahnema1 suggests; I should produce a reproducible example. In order to do this, I'll write the code for my beta function. It's surprisingly simple. This is for the case where the "multiplier" variable is set to log(2); but you don't need to worry about any of that.
function f = beta(z,n)
f=0;
for i = 0:n-1
f = exp(f)/(1+exp(log(2)*(n-i-z)));
end
end
This will work fine for z a float no greater than 4. Once you make z larger it'll start to overflow. So for example, if you put in,
beta(2,100)
1.4242
beta(3,100)
3.3235
beta(3,100) - exp(beta(2,100))/(1/4+1)
0
The significance of the 100, is simply how many iterations we perform; it converges fast so even setting this to 15 or so will still produce the same numerical accuracy. Now, the expected output I want for TAU is pretty straight forward,
TAU(z,1) = log(beta(z+1,1)) - beta(z,1)
TAU(z,2) = log(beta(z+1,2) + TAU(z+1,1)) - beta(z,2)
TAU(z,3) = log(beta(z+1,3) + TAU(z+1,2)) - beta(z,3)
...
TAU(z,n) = log(beta(z+1,n) + TAU(z+1,n-1)) -beta(z,n)
I hope this helps. I feel like there should be an easy way to program this sequence, and I must be missing something obvious; but maybe it's just not possible in Matlab.
At mimocha's suggestion, I'll look into tail-end recursion. I hope to god I don't have to go back to Pari-gp; but it looks like I may have to. Not looking forward to doing a deep dive on that language, lol.
Thanks, again!
Is this what you are looking for?
function out = tau(z,n)
% Ends recursion when n == 1
if n == 1
out = log(beta(z+1,1)) - beta(z,1);
return
end
out = log(beta(z+1,n) + tau(z+1,n-1)) - beta(z,n);
end
function f = beta(z,n)
f = 0;
for i = 0:n-1
f = exp(f) / (1 + exp(log(2)*(n-i-z)));
end
end
This is basically your code from the most recent edit, but I've added a simple catch in the tau function. I tried running your code and noticed that n gets decremented infinitely (no exit condition).
With the modification, the code runs successfully on my laptop for smaller integer values of n, where 1e5 > n >= 1; and for floating values of z, real and complex. So the code will unfortunately break for floating values of n, since I don't know what values to return for, say, tau(1,0) or tau(1,0.9). This should easily be fixable if you know the math though.
However, many of the values I get are NaNs or Infs. So I'm not sure if your original problem was Out of memory error (infinite recursion), or values blowing up to infinity / NaN (numerical stability issue).
Here is a quick 100x100 grid calculation I made with this code.
Then I tested on negative values of z, and found the imaginary part of the output to looks kinda cool.
Not to mention I'm slightly geeking out over the fact that pi is showing up in the imaginary part as well :)
tau(-0.3,2) == -1.45179335740446147085 +3.14159265358979311600i

How can I use cellarrays instead of dynamic variables in matlab?

I have the following problem:
I have two arrays called Variable_1 and Variable_2 (same size 8x3, only different values). I need to make calculations with the values inside the array and store the result in a new array. The calculation is the same for both arrays.
Right now, I solved it with 2 for-loops.
for i = 1:size(Variable_1,1)
Calculation_1 = 5 * Variable_1(i,1);
Result_1(i,:) = Calculation_1;
end
for i = 1:size(Variable_2,1)
Calculation_2 = 5 * Variable_2(i,1);
Result_2(i,:) = Calculation_2;
end
I want to get rid of two separate for-loops and do it with one loop or a loop in a loop. The name "Variable_x" needs to be kinda dynamical. It is different for every run in the outer for-loop. First, it is Variable_1 and matlab has to look in the array "Variable_1" at position i. Later, it is Variable_2 and it has to look in another array, here called "Variable_2".
I know that I shouldn't use dynamic variables and however I didn't found a solution anyway. Maybe it works with Cellarrays but I dont't know exactly how I use them in this specific case.
It is kinda hard to explain, so feel free to ask questions if you have one. I am really looking forward for any suggestions.

I am having trouble creating function handles. I want to embed a maximizing function within a minimizing function

The following code won't work, but this is the idea I'm trying to get at.
c = #(x)constraints;
%this is where I would initialize sum as 0 but not sure how...
for i = 1:length(c)
sum = #(x)(sum(x) + (min(c(x)(i),0))^2);
end
penFunc = #(x)(funcHandle(x) + sig*sum(x));
where constraints and funcHandle are functions of x. This entire code would iterate for a sequence of sig's.
Obviously c(x)(i) isn't functional. I'm trying to write the function where the minimum of c(x) at i (c(x) is a vector) or 0 is taken and then squared.
I know I could calculate c(x) and then analyze it at each i, but I eventually want to pass penFunc as a handle to another function which calculates the minimum of penFunc, so I need to keep it as a function.
I confess I don't understand entirely what you're trying to achieve, but it appears you're trying to create a function handle of an anonymous function with a changing value sum that you precompute. MATLAB anonymous functions do allow you to do this.
It appears there might be some confusion with anonymous functions here. To start with, the line:
c = #(x)constraints;
is probably supposed to be something else, unless you really want c to be a function handle. The # at the start of the line declares a new anonymous function, when I think you just want to call the existing function constraints. It appears you really want c to be an array of constraints coming from the constraints function, in which case I think you mean to say
c = constraints(x);
Then we get to the sum, which I can't tell if you want as a vector or as a single sum. To start with, let's not name it 'sum', since that's the name of a built-in MATLAB function. Let's call it 'sumval'. If it's just a single value, then it's easy (it's easy both ways, but let's do this.) Start before the for loop with sumval=0; to initialize it, then the loop would be:
sumval = 0;
for i = 1:length(c)
sumval = sumval + (min(c(i),0))^2);
end
All four lines could be vectorized if you like to:
c(c>0) = 0; %Replace all positive values with 0
sumval = sum(c.^2); % Use .^ to do a element by element square.
The last line is obviously where you make your actual function handle, and I'm still not quite sure what is desired here. If sig is a function, then perhaps you really meant to have:
penFunc = #(x)(funcHandle(x) + sig*sumval);
But I'm not sure. If you wanted sum to be a vector, then how we specified it here wouldn't work.
Notice that it is indeed fine to have penFunc be an anonymous function with a variable within it (namely sumval), but it will continue to use the value of sumval that existed at the time of the function handle declaration.
So really the issues are A) the creation of c, which I don't think you meant to be a function handle, and B) the initialization of sum, which should probably be sumval (to not interact with MATLAB's own function), and which probably shouldn't declare a new function handle.

MATLAB: sum of one row

I am trying to streamline my code. I have a 2-column array from which I'd like to extract the averages of the columns and store them as X and Y.
I tried using the following code:
[x y] = mean(theArray);
...However, this returns
??? Error using ==> mean
Too many output arguments.
For now, I have settled with the three lines:
coords = mean(theArray);
x = coords(1);
y = coords(2);
I'm sure there must be a much simpler way of doing this in less than three lines. My code is running an eye tracking device at 1000Hz and I want to avoid any unnecessary processing...
Any wisdom gratefully received
In two lines:
x = mean(theArray(:,1));
y = mean(theArray(:,2));
Your code is already pretty darn simple. You can do it in a one-liner, using this or similar in-line array rearranging code.
[x,y] = deal(mean(theArray(:,1)), mean(theArray(:,2)));
But in efficiency terms your original three liner is probably better. Splitting the array out before the mean call will allocate more memory and costs an extra mean() call. You could get it down to two lines without the extra memory and mean().
tmp = mean(theArray);
[x,y] = deal(tmp(1), tmp(2));
But that really just accomplishes the same thing as your original code, paying an additional function call at run time to save a line on paper.
Throw your code in the Matlab profiler with profile on and see if you actually have a problem before trying to optimize. I'll bet none of these are distinguishable in practice, in which case you can stick with whatever's most readable.