How to not shadow variable in inner block in Julia? - julia

The code below, finding price differences is not working. Because previous_price variable is shadowed.
prices = [1, 2, 3, 2, 4]
diffs, previous_price = [], prices[1]
for price in prices
diff = round(price / previous_price; digits = 2)
push!(diffs, diff)
previous_price = price
end
Possible workaround is to put it in a container, but maybe there is a better way?
prices = [1, 2, 3, 2, 4]
diffs, previous_price = [], [prices[1]]
for price in prices
diff = round(price / previous_price[1]; digits = 2)
push!(diffs, diff)
previous_price[1] = price
end

This is because while local scopes can rebind names of parent local scopes, they cannot rebind names of parent global scopes without an explicit global annotation. Instead, an assignment statement x = <...> will create a new local binding, which causes the error you are seeing.
Therefore, several possible solutions to your problem include:
Make the outer scope a local scope
This is the solution I would recommended. In general, it is best to work in local scopes because functions, loops, etc. are in local scopes, and you may want to turn your code from a script to a library and make it a function in the future. The easiest way to create a local scope is to use let.
julia> let
prices = [1, 2, 3, 2, 4]
diffs, previous_price = [], prices[1]
for price in prices
diff = round(price / previous_price; digits = 2)
push!(diffs, diff)
previous_price = price
end
diffs
end
5-element Array{Any,1}:
1.0
2.0
1.5
0.67
2.0
Note that this is easily converted into a function that takes prices as an argument and returns diffs! In general, such solutions are preferred, because they are most reusable.
Make the local scope refer to the global prices
This is not a recommended solution, because mutating global variables is inefficient and does not compose well (i.e. if you wanted to call this routine multiple times from multiple places, perhaps in different threads, they may clash with the same global variable previous_price!)
julia> prices = [1, 2, 3, 2, 4]
5-element Array{Int64,1}:
1
2
3
2
4
julia> diffs, previous_price = [], prices[1]
(Any[], 1)
julia> for price in prices
global previous_price
diff = round(price / previous_price; digits = 2)
push!(diffs, diff)
previous_price = price
end
julia> diffs
5-element Array{Any,1}:
1.0
2.0
1.5
0.67
2.0
Note the introduction of the global previous_price line, which forces the inner previous_price binding to be the global binding.
Use a Ref
This solution is also not recommended in most cases, but I am including it as it is the solution you propose, but with a more appropriate container type. A Ref is sort of like a pointer: it allows you to change the object it contains without rewriting the binding itself. This means that there is no longer any assignment to previous_price in the for loop, and hence it now binds to the outer previous_price, which in this case is global. The code is the same as your possible workaround but it is more efficient and more clear what is going on.
prices = [1, 2, 3, 2, 4]
diffs, previous_price = [], Ref(prices[1])
for price in prices
diff = round(price / previous_price[]; digits = 2)
push!(diffs, diff)
previous_price[] = price
end
Note that Refs are accessed with [], instead of with [1] as your one-element vector is.

Related

Reclassify all pixel values in all of the images in an image collection - GEE

I am new to GEE so the answer to this question may be simple to most of you. I am looking for a way to reclassify pixel values in all of the images in an image collection. I'm working with the Monthly History data from the Global Surface Water dataset and targeting the months March-May. As it currently is, water pixels have a value of 2, non-water pixels are 1, and non-sampled pixels (no data) are 0. I would like to reclassify such that water = 1, not water = 0, and everything else is masked. My code is below:
var dataset = ee.ImageCollection('JRC/GSW1_2/MonthlyHistory')
.filterBounds(roi)
.map(function(image){return image.clip(roi)})
.filter(ee.Filter.calendarRange(3, 5, 'month'));
print(dataset);
This is the part that doesn't work...
var reclassified = function(img) {
return img.remap(([2, 1], [1, 0]), 'water');
};
var new_ds = dataset.map(reclassified)
print(new_ds);
You have an extra set of parentheses here:
return img.remap(([2, 1], [1, 0]), 'water');
^ ^
The effect of this mistake is to proceed as if you had written img.remap([1, 0], 'water'), which fails because 'water' can't be turned into a list.
There is another problem: when you're not using the named parameters form, you have to write all the arguments up to the last optional one you want to specify. The parameter list is remap(from, to, defaultValue, bandName), so you need to write a defaultValue even though you don't need it. In Earth Engine API calls, you can use null for any optional parameter you don't want to specify:
return img.remap([2, 1], [1, 0], null, 'water');
Or, you can use named arguments for the same result:
return img.remap({
from: [2, 1],
to: [1, 0],
bandName: 'water'
});
Or, since in this particular case your image contains only one band, you can leave out the bandName entirely:
return img.remap([2, 1], [1, 0]);

Understand Function capturing through map and reduce

I 'am beginner in Elixir language , so In the blow example
iex> Enum.reduce([1, 2, 3], 0, &+/2)
6
iex> Enum.map([1, 2, 3], &(&1 * 2))
[2, 4, 6]
In the reduce method I understand that we capture the second arg and we add to it the list values until we reach the end of the List .
but in the map method I can't understand how the capturing works?
reference
http://elixir-lang.org/getting-started/recursion.html
map/2 and reduce/2 are two different functions.
map/2 takes some values and a function that takes a single value and applies that function to each element in the collection, effectively transforming it into a list.
reduce/2 takes some values and a function that takes 2 arguments. The first argument of that function is the element in your collection, while the second is an accumulator. So the function reduces your collection down to a single value.
Using the syntax &+/2, this does not capture the second argument. It calls the + function on the two arguments. The /2 is to denote that it has an arity of 2 (it takes 2 arguments). Take the following code as an example.
iex(1)> fun = &+/2
&:erlang.+/2
iex(2)> fun.(1,2)
3
Here, we set the + function to the variable fun. We can then apply that function to our arguments in order to get a value.
The other syntax &(&1 * 2) creates an anonymous function that takes our one and only argument (represented by &1) and multiplies it by 2. The initial & just means that it is an anonymous function.
iex(3)> fun2 = &(&1 * 2)
#Function<6.118419387/1 in :erl_eval.expr/5>
iex(4)> fun2.(5)
10
They are similar concepts, but slightly different.
Basically:
map returns you new list as a result of applying function on each element of the list
reduce returns you result of the computation of applied function over the list - you reduced the whole collection into (most likely) one result eg. integer
In your example:
iex> Enum.reduce([1, 2, 3], 0, &+/2)
# it equals:
0 + 1 # first step, 1 is out of the list now
1 + 2 # second step, 2 is out of the list now
3 + 3 # last step, 3 is out of the list now, return 6
iex> Enum.map([1, 2, 3], &(&1 * 2))
[2, 4, 6]
# apply for each element function fn(x) -> 2 * x end, but with syntactic sugar
There are three different ways to express an anonymous function, when passing it as an argument:
Enum.reduce([1, 2, 3], 0, fn p1, p2 -> p1 + p2 end)
or, using a shorthand and enumerated params:
Enum.reduce([1, 2, 3], 0, &(&1 + &2))
or, explicitly naming the function of the respective arity (2 for reduce, because reduce expects a function of arity 2):
Enum.reduce([1, 2, 3], 0, &+/2)
The latter, while looking cumbersome, is just a common way to write a function name with it’s arity. Kernel.+/2 is a function name here. If you were using your own function as the reducer:
defmodule My, do: def plus(p1, p2), do: p1 + p2
Enum.reduce([1, 2, 3], 0, &My.plus/2)
All three ways described above are 100% equivalent.
JIC: For the mapper those three ways would be:
Enum.map([1, 2, 3], fn p -> p * 2 end)
Enum.map([1, 2, 3], &(&1 * 2))
—
The third notation is not available here, since there is no such a function, that takes a number and returns it’s doubled value. But one might declare her own:
defmodule Arith, do: def dbl(p1), do: p1 * 2
Enum.map([1, 2, 3], &Arith.dbl/1) # map expects arity 1
#⇒ [2, 4, 6]

How to fix this SML code to work as intended?

Right now I have an SML function:
method([1,1,1,1,2,2,2,3,3,3]);
returns:
val it = [[2,2,2],[3,3,3]] : int list list
but I need it to return:
val it = [[1,1,1,1],[2,2,2],[3,3,3]] : int list list
This is my current code:
- fun method2(L: int list) =
= if tl(L) = [] then [hd(L)] else
= if hd(tl(L)) = hd(L) then hd(L)::method(tl(L)) else [hd(L)];
- fun method(L: int list) =
= if tl(L) = [] then [] else
= if hd(tl(L)) = hd(L) then method(tl(L)) else
= method2(tl(L))::method(tl(L));
As you can see it misses the first method2 call. Any ideas on how I can fix this? I am completely stumped.
Your problem is here if hd(tl(L)) = hd(L) then method(tl(L)) else. This is saying if the head of the tail is equal to the head, then continue processing, but don't add it to the result list. this will skip the first contiguous chunk of equal values. I would suggest separating the duties of these functions a bit more. The way to do this is to have method2 strip off the next contiguous chunk of values, and return a pair, where the first element will have the contiguous chunk removed, and the second element will have the remaining list. For example, method2([1, 1, 1, 2, 2, 3, 3]) = ([1, 1, 1], [2, 2, 3, 3]) and method2([2, 2, 3, 3]) = ([2, 2], [3, 3]). Now, you can just keep calling method2 until the second part of the pair is nil.
I'm not quite sure what you are trying to do with your code. I would recommend creating a tail recursive helper function which is passed three arguments:
1) The list of lists you are trying to build up
2) The current list you are building up
3) The list you are processing
In your example, a typical call somewhere in the middle of the computation would look like:
helper([[1,1,1,1]], [2,2],[2,3,3,3])
The recursion would work by looking at the head of the last argument ([2,3,3,3]) as well as the head of the list which is currently being built up ([2,2]) and, since they are the same -- the 2 at the end of the last argument is shunted to the list being built up:
helper([[1,1,1,1]], [2,2,2],[3,3,3])
in the next step in the recursion the heads are then compared and found to be different (2 != 3), so the helper function will put the middle list at the front of the list of lists:
helper([[2,2,2], [1,1,1,1]], [3],[3,3])
the middle list is re-initialized to [3] so it will start growing
eventually you reach something like this:
helper([[2,2,2], [1,1,1,1]], [3,3,3],[])
the [3,3,3] is then tacked onto the list of lists and the reverse of this list is returned.
Once such a helper function is defined, the main method checks for an empty list and, if not empty, initializes the first call to the helper function. The following code fleshes out theses ideas -- using pattern-matching style rather than hd and tl (I am not a big fan of using those functions explicitly -- it makes the code too Lisp-like). If this is homework then you should probably thoroughly understand how it works and then translate it to code involving hd and tl since your professor would regard it as plagiarized if you use things you haven't yet studied and haven't made it your own work:
fun helper (xs, ys, []) = rev (ys::xs)
| helper (xs, y::ys, z::zs) =
if y = z
then helper(xs, z :: y :: ys, zs)
else helper((y::ys)::xs,[z],zs);
fun method [] = []
| method (x::xs) = helper([],[x],xs);

Julia list comprehension changes the type

Suppose we have a Vector of tuples (Int64, Int64) in julia:
In [1] xx = [(1, 2), (3, 4), (5, 6)]
typeof(xx) == Vector{(Int64, Int64)}
Out[1] true
Now I want to construct a new vector of the first indices of the tuples.
In [2] indices = [x[1] for x in xx]
typeof(indices)
Out[2] Array{Any, 1}
I expect it to be an Array{Int64, 1} type. How can I fix this?
edit: I am using 0.3.9.
function f()
xx = [(1, 2), (3, 4), (5, 6)]
inds = [ x[1] for x in xx ]
return(inds)
end
y = f()
typeof(y)
The last line of code returns Array{Int64, 1}.
The problem here is that you are working in global scope. For Julia's type inference to be able to do its magic, you need to work in a local scope. In other words, wrap all your code in functions. This rule is very, very, important, but, having come from a MatLab background myself, I can see why people forget it. Just remember, 90% of questions saying "Why is my Julia code slow?" occur because the user was working in global scope, not local scope.
ps, even in local scope, type inference of loop comprehensions can stumble in particularly complex cases. This is a known issue and is being worked on. If you want to provide the compiler with some "help" you can do something like:
inds = Int[ x[1] for x in xx ]
You can also use map and preserve the type:
#passing a lambda that takes the 1st element, and the iterable
inds = map( (x)-> x[1], xx)

How to make recursive nested loops which use loop variables inside?

I need to make a nested loop with an arbitrary depth. Recursive loops seem the right way, but I don't know how to use the loop variables in side the loop. For example, once I specify the depth to 3, it should work like
count = 1
for i=1, Nmax-2
for j=i+1, Nmax-1
for k=j+1,Nmax
function(i,j,k,0,0,0,0....) // a function having Nmax arguments
count += 1
end
end
end
I want to make a subroutine which takes the depth of the loops as an argument.
UPDATE:
I implemented the scheme proposed by Zoltan. I wrote it in python for simplicity.
count = 0;
def f(CurrentDepth, ArgSoFar, MaxDepth, Nmax):
global count;
if CurrentDepth > MaxDepth:
count += 1;
print count, ArgSoFar;
else:
if CurrentDepth == 1:
for i in range(1, Nmax + 2 - MaxDepth):
NewArgs = ArgSoFar;
NewArgs[1-1] = i;
f(2, NewArgs, MaxDepth, Nmax);
else:
for i in range(ArgSoFar[CurrentDepth-1-1] + 1, Nmax + CurrentDepth - MaxDepth +1):
NewArgs = ArgSoFar;
NewArgs[CurrentDepth-1] = i;
f(CurrentDepth + 1, NewArgs, MaxDepth, Nmax);
f(1,[0,0,0,0,0],3,5)
and the results are
1 [1, 2, 3, 0, 0]
2 [1, 2, 4, 0, 0]
3 [1, 2, 5, 0, 0]
4 [1, 3, 4, 0, 0]
5 [1, 3, 5, 0, 0]
6 [1, 4, 5, 0, 0]
7 [2, 3, 4, 0, 0]
8 [2, 3, 5, 0, 0]
9 [2, 4, 5, 0, 0]
10 [3, 4, 5, 0, 0]
There may be a better way to do this, but so far this one works fine. It seems easy to do this in fortran. Thank you so much for your help!!!
Here's one way you could do what you want. This is pseudo-code, I haven't written enough to compile and test it but you should get the picture.
Define a function, let's call it fun1 which takes inter alia an integer array argument, perhaps like this
<type> function fun1(indices, other_arguments)
integer, dimension(:), intent(in) :: indices
...
which you might call like this
fun1([4,5,6],...)
and the interpretation of this is that the function is to use a loop-nest 3 levels deep like this:
do ix = 1,4
do jx = 1,5
do kx = 1,6
...
Of course, you can't write a loop nest whose depth is determined at run-time (not in Fortran anyway) so you would flatten this into a single loop along the lines of
do ix = 1, product(indices)
If you need the values of the individual indices inside the loop you'll need to unflatten the linearised index. Note that all you are doing is writing the code to transform array indices from N-D into 1-D and vice versa; this is what the compiler does for you when you can specify the rank of an array at compile time. If the inner loops aren't to run over the whole range of the indices you'll have to do something more complicated, careful coding required but not difficult.
Depending on what you are actually trying to do this may or may not be either a good or even satisfactory approach. If you are trying to write a function to compute a value at each element in an array whose rank is not known when you write the function then the preceding suggestion is dead flat wrong, in this case you would want to write an elemental function. Update your question if you want further information.
you can define your function to have a List argument, which is initially empty
void f(int num,List argumentsSoFar){
// call f() for num+1..Nmax
for(i = num+1 ; i < Nmax ; i++){
List newArgs=argumentsSoFar.clone();
newArgs.add(i);
f(i,newArgs);
}
if (num+1==Nmax){
// do the work with your argument list...i think you wanted to arrive here ;)
}
}
caveat: the stack should be able to handle Nmax depth function calls
Yet another way to achieve what you desire is based on the answer by High Performance Mark, but can be made more general:
subroutine nestedLoop(indicesIn)
! Input indices, of arbitrary rank
integer,dimension(:),intent(in) :: indicesIn
! Internal indices, here set to length 5 for brevity, but set as many as you'd like
integer,dimension(5) :: indices = 0
integer :: i1,i2,i3,i4,i5
indices(1:size(indicesIn)) = indicesIn
do i1 = 0,indices(1)
do i2 = 0,indices(2)
do i3 = 0,indices(3)
do i4 = 0,indices(4)
do i5 = 0,indices(5)
! Do calculations here:
! myFunc(i1,i2,i3,i4,i5)
enddo
enddo
enddo
enddo
enddo
endsubroutine nestedLoop
You now have nested loops explicitly coded, but these are 1-trip loops unless otherwise desired. Note that if you intend to construct arrays of rank that depends on the nested loop depth, you can go up to rank of 7, or 15 if you have a compiler that supports it (Fortran 2008). You can now try:
call nestedLoop([1])
call nestedLoop([2,3])
call nestedLoop([1,2,3,2,1])
You can modify this routine to your liking and desired applicability, add exception handling etc.
From an OOP approach, each loop could be represented by a "Loop" object - this object would have the ability to be constructed while containing another instance of itself. You could then theoretically nest these as deep as you need to.
Loop1 would execute Loop2 would execute Loop3.. and onwards.

Resources