For loop in Julia. Syntax confusion - for-loop

I am a complete noob in Julia and its syntax. I am trying to follow this article on semi-definite-programming on Julia.
I would apprecieate if someone can help me figure out what the for loop in In[4] actually does:
for i in 1:m
A[:, (i-1)*n+1:i*n] .= random_mat_create(n)
b[i] = tr(A[:, (i-1)*n+1:i*n]*X_test)
end
To my understanding it should create a vector of matrices A (m of those) as well as an m-dimensional vector b. I am totally confused though on the indexing of A and the indexing of b.
I would like an explanation of the :, (i-1)*n+1:i*n part of this code. The reason I ask here is because I also dont know what to Google or what to search for in Julia documentation.

(i-1)*n+1:i*n creates a range from (i-1)*n + 1 to i*n. For example, if i=2 and n=10, this range becomes 11:20, so A[:, (i-1)*n+1:i*n] will grab all the rows of A (that's what : does), and columns 11-20.

There are two operations there that are not clear to you:
: operator. Consider a Matrix a = zeros(3,3). You could use array slicing operator (similarly to numpy or Matlab) to select the entire second columns as: a[1:end,2]. However, when selecting everything from start to the end those two values can be omitted and hence you can write a[:,2] (this always looked the easiest way for me to remember that)
. (dot) operator. Julia is very careful about what gets vectorized and what not. In numpy or R, vectorizing operations happens kind of always automatically. In Julia you have the control - but with the control comes the responsibility. Hence trying to assign values to the second column by writing a[:, 2] = 5.0 will throw an error because there is vector on the right and a scalar on the left. If you want to vectorize you need to tell that to Julia. Hence the dot operator .= means "perform element-wise assignment". Note that any Julia function or operator, even your own functions can be decorated by such dot .. Since this is a very important language feature have a look at https://docs.julialang.org/en/v1/manual/arrays/#Broadcasting

Related

Sparse matrix to speed up octave

I have a loop where "i" depends on "i-1" value, so I cannot vectorize it.
I've read that I can use a sparse matrix in order to vectorize it and so to speed up my code, but I don't understand how this work.
Any help?
Thanks
You are referring to this technique, as referenced from this (rather old) how to speed up octave article.
I'll rephrase the gist here in case the link dies in the future.
Suppose you have the following loop:
p1(1) = 0;
for i = 2 : N
t = t + dt;
p1(i) = p1(i - 1) + dt * 2 * t;
endfor
You note here that, purely from a mathematical point of view, the last step in the loop could be rephrased as:
-1 * p1(i - 1) + 1 * p1(i) = dt * 2 * t
This makes it possible to recast the problem as a sparse matrix solve, by thinking of p1 as the vector of unknowns, and each iteration of the loop as a row in a (sparse) system of equations. E.g.:
Given that t is a known vector, this makes the above a straightforward problem that can be solved via a simple matrix division operation, which is guaranteed to be fast.
Having said that, presumably this 'trick' is only useful if you are able to recast the problem in this manner in the first place. Presumably this will only be the case for linear problems of your unknown. I don't think this can necessarily be used for more complicated loops.
Also, as Cris has mentioned in the comments, if this method does not work for you, there's a chance you can optimize your loop in other ways (or even that the loop solution may not necessarily be slow in the first place).
By the way, in theory, Octave provides jit-speedup like matlab does, though unlike matlab you need to enable it explicitly (in the sense that you need to compile your octave with jit options, which tends not to be the default), and my personal experience is that this is mostly experimental and may not do much except in the simplest of loops (see this post).

Lua: What is typical approach for using calculated values in a for loop?

What is the typical approach in LUA (before the introduction of integers in 5.3) for dealing with calculated range values in for loops? Mathematical calculations on the start and end values in a numerical for loop put the code at risk of bugs, possibly nasty latent ones as this will only occur on certain values and/or with changes to calculation ordering. Here's a concocted example of a loop not producing the desire output:
a={"a","b","c","d","e"}
maybethree = 3
maybethree = maybethree / 94
maybethree = maybethree * 94
for i = 1,maybethree do print(a[i]) end
This produces the unforuntate output of two items rather than the desired three (tested on 5.1.4 on 64bit x86):
a
b
Programmers unfamiliar with this territory might be further confused by print() output as that prints 3!
The application of a rounding function to the nearest whole number could work here. I understand the approximatation with FP and why this fails, I'm interested in what the typical style/solution is for this in LUA.
Related questions:
Lua for loop does not do all iterations
Lua: converting from float to int
The solution is to avoid this reliance on floating-point math where floating-point precision may become an issue. Or, more realistically, just be aware of when you are using FP and be mindul of the precision issue. This isn’t a Lua problem that requires a Lua-specific solution.
maybethree is a misnomer: it is never three. Your code above is deterministic. It will always print just a and b. Since the maybethree variable is less than three, of course the for loop would not execute 3 times.
The print function is also behaving as defined/expected. Use string.format to show thr FP number in all its glory:
print(string.format("%1.16f", maybethree)) -- 2.9999999999999996
Still need to use calculated values to control your for loop? Then you already mentioned the answer: implement a rounding function.

Maple: How to define new elements of a matrix?

In Maple, I have a matrix N and its elements N[i,j], If I modify the elements of this matrix as follows for example
>for j from 1 to 4 do
>print(F[i,j]=(diff(N[i,j],x)));
>od;od;
where the matrix elements are functions of x.
I've wanted to define new matrix elements
>BA[i,j]:=(diff(N[i,j],x)));
but I can't do this with Maple, through the above command. Can someone help me ?
Better than using a loop is simply BA:= diff~(N,x). The ~ can be appended to any operator to mean "apply the operator to each member of the container and return a new container containing the modified members."
Also, be careful about using print. Its only purpose is to print stuff on the screen from the middle (not the end) of a computation. It can't be used to change any stored values. Good programs use print very sparingly, if at all. The end result of a computation is displayed automatically, without needing a print command.

How to implement a part of histogram equalization in matlab without using for loops and influencing speed and performance

Suppose that I have these Three variables in matlab Variables
I want to extract diverse values in NewGrayLevels and sum rows of OldHistogram that are in the same rows as one diverse value is.
For example you see in NewGrayLevels that the six first rows are equal to zero. It means that 0 in the NewGrayLevels has taken its value from (0 1 2 3 4 5) of OldGrayLevels. So the corresponding rows in OldHistogram should be summed.
So 0+2+12+38+113+163=328 would be the frequency of the gray level 0 in the equalized histogram and so on.
Those who are familiar with image processing know that it's part of the histogram equalization algorithm.
Note that I don't want to use built-in function "histeq" available in image processing toolbox and I want to implement it myself.
I know how to write the algorithm with for loops. I'm seeking if there is a faster way without using for loops.
The code using for loops:
for k=0:255
Condition = NewGrayLevels==k;
ConditionMultiplied = Condition.*OldHistogram;
NewHistogram(k+1,1) = sum(ConditionMultiplied);
end
I'm afraid if this code gets slow for high resolution big images.Because the variables that I have uploaded are for a small image downloaded from the internet but my code may be used for sattellite images.
I know you say you don't want to use histeq, but it might be worth your time to look at the MATLAB source file to see how the developers wrote it and copy the parts of their code that you would like to implement. Just do edit('histeq') or edit('histeq.m'), I forget which.
Usually the MATLAB code is vectorized where possible and runs pretty quick. This could save you from having to reinvent the entire wheel, just the parts you want to change.
I can't think a way to implement this without a for loop somewhere, but one optimisation you could make would be using indexing instead of multiplication:
for k=0:255
Condition = NewGrayLevels==k; % These act as logical indices to OldHistogram
NewHistogram(k+1,1) = sum(OldHistogram(Condition)); % Removes a vector multiplication, some additions, and an index-to-double conversion
end
Edit:
On rereading your initial post, I think that the way to do this without a for loop is to use accumarray (I find this a difficult function to understand, so read the documentation and search online and on here for examples to do so):
NewHistogram = accumarray(1+NewGrayLevels,OldHistogram);
This should work so long as your maximum value in NewGrayLevels (+1 because you are starting at zero) is equal to the length of OldHistogram.
Well I understood that there's no need to write the code that #Hugh Nolan suggested. See the explanation here:
%The green lines are because after writing the code, I understood that
%there's no need to calculate the equalized histogram in
%"HistogramEqualization" function and after gaining the equalized image
%matrix you can pass it to the "ExtractHistogram" function
% (which there's no loops in it) to acquire the
%equalized histogram.
%But I didn't delete those lines of code because I had tried a lot to
%understand the algorithm and write them.
For more information and studying the code, please see my next question.

Vectorization of matlab code

i'm kinda new to vectorization. Have tried myself but couldn't. Can somebody help me vectorize this code as well as give a short explaination on how u do it, so that i can adapt the thinking process too. Thanks.
function [result] = newHitTest (point,Polygon,r,tol,stepSize)
%This function calculates whether a point is allowed.
%First is a quick test is done by calculating the distance from point to
%each point of the polygon. If that distance is smaller than range "r",
%the point is not allowed. This will slow down the algorithm at some
%points, but will greatly speed it up in others because less calls to the
%circleTest routine are needed.
polySize=size(Polygon,1);
testCounter=0;
for i=1:polySize
d = sqrt(sum((Polygon(i,:)-point).^2));
if d < tol*r
testCounter=1;
break
end
end
if testCounter == 0
circleTestResult = circleTest (point,Polygon,r,tol,stepSize);
testCounter = circleTestResult;
end
result = testCounter;
Given the information that Polygon is 2 dimensional, point is a row vector and the other variables are scalars, here is the first version of your new function (scroll down to see that there are lots of ways to skin this cat):
function [result] = newHitTest (point,Polygon,r,tol,stepSize)
result = 0;
linDiff = Polygon-repmat(point,size(Polygon,1),1);
testLogicals = sqrt( sum( ( linDiff ).^2 ,2 )) < tol*r;
if any(testLogicals); result = circleTest (point,Polygon,r,tol,stepSize); end
The thought process for vectorization in Matlab involves trying to operate on as much data as possible using a single command. Most of the basic builtin Matlab functions operate very efficiently on multi-dimensional data. Using for loop is the reverse of this, as you are breaking your data down into smaller segments for processing, each of which must be interpreted individually. By resorting to data decomposition using for loops, you potentially loose some of the massive performance benefits associated with the highly optimised code behind the Matlab builtin functions.
The first thing to think about in your example is the conditional break in your main loop. You cannot break from a vectorized process. Instead, calculate all possibilities, make an array of the outcome for each row of your data, then use the any keyword to see if any of your rows have signalled that the circleTest function should be called.
NOTE: It is not easy to efficiently conditionally break out of a calculation in Matlab. However, as you are just computing a form of Euclidean distance in the loop, you'll probably see a performance boost by using the vectorized version and calculating all possibilities. If the computation in your loop were more expensive, the input data were large, and you wanted to break out as soon as you hit a certain condition, then a matlab extension made with a compiled language could potentially be much faster than a vectorized version where you might be performing needless calculation. However this is assuming that you know how to program code that matches the performance of the Matlab builtins in a language that compiles to native code.
Back on topic ...
The first thing to do is to take the linear difference (linDiff in the code example) between Polygon and your row vector point. To do this in a vectorized manner, the dimensions of the 2 variables must be identical. One way to achieve this is to use repmat to copy each row of point to make it the same size as Polygon. However, bsxfun is usually a superior alternative to repmat (as described in this recent SO question), making the code ...
function [result] = newHitTest (point,Polygon,r,tol,stepSize)
result = 0;
linDiff = bsxfun(#minus, Polygon, point);
testLogicals = sqrt( sum( ( linDiff ).^2 ,2 )) < tol*r;
if any(testLogicals); result = circleTest (point,Polygon,r,tol,stepSize); end
I rolled your d value into a column of d by summing across the 2nd axis (note the removal of the array index from Polygon and the addition of ,2 in the sum command). I then went further and evaluated the logical array testLogicals inline with the calculation of the distance measure. You will quickly see that a downside of heavy vectorisation is that it can make the code less readable to those not familiar with Matlab, but the performance gains are worth it. Comments are pretty necessary.
Now, if you want to go completely crazy, you could argue that the test function is so simple now that it warrants use of an 'anonymous function' or 'lambda' rather than a complete function definition. The test for whether or not it is worth doing the circleTest does not require the stepSize argument either, which is another reason for perhaps using an anonymous function. You can roll your test into an anonymous function and then jut use circleTest in your calling script, making the code self documenting to some extent . . .
doCircleTest = #(point,Polygon,r,tol) any(sqrt( sum( bsxfun(#minus, Polygon, point).^2, 2 )) < tol*r);
if doCircleTest(point,Polygon,r,tol)
result = circleTest (point,Polygon,r,tol,stepSize);
else
result = 0;
end
Now everything is vectorised, the use of function handles gives me another idea . . .
If you plan on performing this at multiple points in the code, the repetition of the if statements would get a bit ugly. To stay dry, it seems sensible to put the test with the conditional function into a single function, just as you did in your original post. However, the utility of that function would be very narrow - it would only test if the circleTest function should be executed, and then execute it if needs be.
Now imagine that after a while, you have some other conditional functions, just like circleTest, with their own equivalent of doCircleTest. It would be nice to reuse the conditional switching code maybe. For this, make a function like your original that takes a default value, the boolean result of the computationally cheap test function, and the function handle of the expensive conditional function with its associated arguments ...
function result = conditionalFun( default, cheapFunResult, expensiveFun, varargin )
if cheapFunResult
result = expensiveFun(varargin{:});
else
result = default;
end
end %//of function
You could call this function from your main script with the following . . .
result = conditionalFun(0, doCircleTest(point,Polygon,r,tol), #circleTest, point,Polygon,r,tol,stepSize);
...and the beauty of it is you can use any test, default value, and expensive function. Perhaps a little overkill for this simple example, but it is where my mind wandered when I brought up the idea of using function handles.

Resources