How to implement a decrementing for loop in Julia? - loops

I know that in python I can do something as follows.
for i in range(10, 0, -1):
print(i)
Which will output:
10
9
8
7
6
5
4
3
2
1
I'm very much new to julia and I know I can create normal loops as follows.
for i=1:10
println(i)
end
Intuitively, I tried something like as follows (since I thought it behaved similar to python's range([start], stop[, step]) function).
for i=10:1:-1
println(i)
end
Although it didn't fail, it didn't print anything either. What am I doing wrong?
Is there an intuitive way to loop backwards in julia?

Try this:
julia> for i=10:-1:1
println(i)
end
10
9
8
7
6
5
4
3
2
1
or this
julia> for i=reverse(1:10)
println(i)
end
10
9
8
7
6
5
4
3
2
1
As #phipsgabler noted you can also use:
julia> range(10, 1, step=-1)
10:-1:1
to get the same result again (note though that you have to use 1 as a second index).
From my practice range is usually more useful with with length keyword argument:
julia> range(10, 1, length=10)
10.0:-1.0:1.0
(notice that in this case you get a vector of Float64 not Int)

Related

Read an Array of Arrays separated by blank lines in Julia

I have an array of arrays stored as blocks of tabular data in a textfile. The blocks have different number of rows but the same number of columns. Like this:
7 9
9 9
7 1
1 1
3 3
4 1
And so on.
I would like to read them in Julia and to end with an array of arrays, or an array of 2 dimensional arrays, like this:
a=[ [7, 9; 9 ,9], [7, 1; 1, 1 ; 3 3 ]] ...
I am trying with different ideas with do syntax, but I am being not very succesfull yet.
aux=[]
open("cell.dat") do f
aux=[]
aux2=[]
for line in eachline(f)
if line != ""
aux2=vcat(aux2,line)
else
print("tuabuela")
aux=vcat(aux,aux2)
print(aux, aux2)
aux2=[]
end
end
end
I end with an empty array!
There are many ways to do it. Suppose the file is not huge and you have read your file to String called dat:
dat="""7 9
9 9
7 1
1 1
3 3
4 1"""
In that case you can do:
julia> readdlm.(IOBuffer.(split(dat,"\n\n")))
3-element Vector{Matrix{Float64}}:
[7.0 9.0; 9.0 9.0]
[7.0 1.0; 1.0 1.0; 3.0 3.0]
[4.0 1.0]

Julia's Negative/Complement Indexing like R

Is there a functionality in Julia that's similar to R's negative indexing? In R, the code would be similar to:
x = 1:10
inds = c(1, 5, 7)
x[-inds]
[1] 2 3 4 6 8 9 10
I've found this to be extremely useful in numerous situations, especially for things such as sampling indices to create a testing/training set, but also for subindexing an array to exclude certain rows. So I am hoping there's something simple in Julia that can do the same.
This is similar to #Colin T Bower's answer and also only uses base Julia. Afraid it is not as elegant as your R example.
julia> minus(indx, x) = setdiff(1:length(x), indx)
minus (generic function with 1 method)
julia> x = collect(1:10)
10-element Array{Int64,1}:
1
2
3
4
5
6
7
8
9
10
julia> inds = [1, 5, 7]
3-element Array{Int64,1}:
1
5
7
julia> x[minus(inds, x)]
7-element Array{Int64,1}:
2
3
4
6
8
9
10
Not a feature of the base language, but see for example the package here: https://github.com/mbauman/InvertedIndices.jl

Matlab delete specific elements from an array

I have for example a=[1 2 3 4 5 6 7 8 9 10]; and I have to delete each 2 following numbers from 3.
like at the end it should be a=[1 4 7 10];
How to do this without a for loop.
And also if there is a way to guarantee that at the end the resulting array will have exact number of entries, like here it should be a with 4 entries at the end.
But for example we have b=[1 2 3 4 5 6 7 8 9 ]; and if I want make sure that at the end I still have 4 entries in the rest array, so that b can't be equal to [1 4 7] because I need 4 entries for sure.
You can use indexing for this:
A = 1:10;
B = A(1:3:end)
B =
[1 4 7 10]
Or, if you really want to remove elements:
A = 1:10;
A(2:3:end) = [];
A(3:3:end) = [];
For your second question regarding length checking, it's unclear what you're asking. Would an if comparison be enough ?
if numel(A) ~= 4
% ... Handle unexpected values here
end
Best,
As you mentioned in the question and in the comments that you need 4 elements at the end and if elements are less than 4 then you want to include the last element/s of b, the following should work:-
b=[1 2 3 4 5 6 7 8 9]
b_req=b(1:3:end);
temp=length(b_req);
if temp<4 b_req(end+1:4)=b(end-3+temp:end); % for including the elements of b so that total elements are 4 at the end
elseif temp>4 b_req=b_req(1:4); % for removing the extra elements
end
b_req
Output:-
b =
1 2 3 4 5 6 7 8 9
b_req =
1 4 7 9
and
if instead b=[1 2 3 4 5 6 7 8 9 10]; then the same code gives what you require, i.e. b_req = [1 4 7 10]
This code speaks for itself:
a = 1:15; % some vector
% returns every third element after the first one:
third_elemets = a(1:3:end);
% returns the missing elements for the vector to be in size 4 from the end of a
last_elements = a(end-3+length(third_elemets):end);
% take maximum 4 elements from a
logic_ind = true(min(4,length(third_elemets)),1);
% and concatanate them with last_elements (if there are any)
a = [third_elemets(logic_ind) last_elements]
and under the assumption that whenever there are less than 4 elements you simply take the last one(s) - it should always work.

read into arrays in Julia

I'm relatively new to Julia and am looking for an efficient way to read in from a text file and store each "column" in an array (I have 2 columns, but a general solution would be great as well). For instance, I'd like the input
1 2
3 4
5 6
to be read into two arrays, say, x and y, such that x=[1 3 5] and y=[2 4 6]. I have a working solution (might not compile, just free-handed it), but I feel like there is a more efficient way to do this than to hcat and to read the input file line by line. Any suggestions are much appreciated!
Currently, I am doing the following, more or less:
x=[];
y=[];
f=open("filename");
f=readlines(f);
for str in f
s1, s2= split(str, " ");
s1=int(s1);
s2=int(s2);
x=hcat(x, s1);
y=hcat(y, s2);
end
Here's a way.
julia> myarray=int(open(readdlm,"mynums.txt"))
3x2 Array{Int32,2}:
1 2
3 4
5 6
julia> x=myarray[:,1]
3-element Array{Int32,1}:
1
3
5
julia> y=myarray[:,2]
3-element Array{Int32,1}:
2
4
6

Fortran 90 Array - Diamond Shape

I have a dataset, and it looks like this.
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9
This is the desired output: (Nothing is recorded with an X value).
X X 3 X X
X 3 4 5 X
3 4 5 6 7
X 5 6 7 X
X X 7 X X
When it writes, I should get "3, 3, 4, 5, 3, 4, 5, 6, 7, 5, 6, 7, 7" as output.
I have tried a lot of ideas so far and at this moment, nothing seems to be working. My do loops end up creating lots of output and/or it reads the wrong values. I have even tried messing around with different storage modes, but nothing seems to be applicable.
If you had the foresight to declare your array like this
integer, dimension(-2:2,-2:2) :: my-array
that is, with the centre element having index (0,0) then I think this nested loop will output the elements in the order you require:
do row = -2,2
do col = -2+abs(row), 2-abs(row)
write(*,*) my_array(row, col)
end do
end do
If you did not have the foresight to declare your array that way, the arithmetic is a little more fiddly (but no worse than that) so I'll leave it to you. And for a production code you'll want to replace all those 2s with a parameter or a call to ubound or lbound.

Resources