I was reading the documentation for writing parallel for loops in Julia using #distributed and saw that it is possible to specify a reducer function that acts on the result of each iteration of the loop.
For instance, as it is shown in the next example taken from the documentation, it is possible to sum the result of every single worker:
nheads = #distributed (+) for i = 1:200000000
Int(rand(Bool))
end
Unfortunately I couldn't find any list of which functions can be used as reducers and how to exactly do it. Is there such a list?
You can take any function that takes two arguments so the list is open and can be arbitrarily extended. See e.g.
julia> addprocs(4);
julia> x = #distributed (a,b) -> (a,b, "val") for i in 1:10
i
end
(((((1, 2, "val"), 3, "val"), ((4, 5, "val"), 6, "val"), "val"), (7, 8, "val"), "val"), (9, 10, "val"), "val")
julia> addprocs(4);
julia> x = #distributed (a,b) -> (a,b, "val") for i in 1:10
i
end
((((((((1, 2, "val"), (3, 4, "val"), "val"), 5, "val"), 6, "val"), 7, "val"), 8, "val"), 9, "val"), 10, "val")
However, for the operation to work in typical scenarios the function has a signature fun(::T, ::T)::T where T so that it is guaranteed that the reduction operation can be always performed and preferably the result of reduction does not depend on the order of operations (you can see in the example above that the order of reductions depends on the number of workers and I have chosen a function that does not have this property on purpose).
Related
def bubbleSort(array):
swapped = False
for i in range(len(array)-1,0,-1):
print(i)
for j in range(i):
print(j)
if array[j]>array[j+1]:
array[j], array[j+1] = array[j+1], array[j]
swapped= True
if swapped:
swapped=False
else:
break
print(array)
bubbleSort([5, 2, 1, 3])
How should I interpret this line: for i in range(len(array)-1,0,-1)? I'm particularly confused about the need for the 0 and -1 parameters.
That line has a couple of things happening, which I will give simplified explanations of (I'm assuming this code is written in Python).
First, for i in iterable will loop through iterable, meaning the code in the for loop will repeat as many times as there are elements in iterable, which could be an array, a list, a string etc, and each time it loops, i will be the next element of iterable, starting with the first. For example, for i in [1, 2, 3] will loop 3 times; the first time, i will be equal to 1; the second, 2, etc.
Next, the range function produces an iterable that is a range of numbers, for example from 0-9. With a single argument, range will produce a range from 0 to that number, but stopping just before it, e.g. range(5) will give you [0, 1, 2, 3, 4]. Thus if you were to use for i in range(5), your code would repeat 5 times, with i incrementing from 0 to 4.
With two arguments, the range will start at the first and stop before the second, which must be greater than the first. For example, range(3, 8) would give you [3, 4, 5, 6, 7]. range(8, 3), however, will not work, as the start number is greater than the stop number. This means you cannot count down with only 2 arguments.
The third optional argument for range is the step size; how much you want the numbers to increase or decrease by each step. For example, range(0, 10, 2) will give you the output [0, 2, 4, 6, 8], stopping before 10. Here is where you can produce a descending range, by setting the step argument to a negative number. range(10, 0, -2) will give you [10, 8, 6, 4, 2], again stopping before the second argument, and range(10, 0, -1) will give you the full [10, 9, 8, 7, 6, 5, 4, 3, 2, 1].
Finally, the len(iterable) function will give you the length of whatever you give it, or the number of items contained in say a list. For example len("Hello!") will give you 6, and len([1, 2, 3, 4, 5]) will give you 5.
Putting this all together, the line for i in range(len(array)-1, 0, -1) will do the following:
the code will repeat as many times as there are items in a list, with i taking on each value in the list
that list is a range of numbers
that start number of the range is the length of array minus one
the end of the range is 0
the range is descending, with a step size of -1
Thus if array were ["fish", "banana", "pineapple", "onion"], len(array) will return 4, so you will have for i in range(3, 0, -1), which will loop 3 times, with i being 3, then 2, then 1.
This was a rather simplified answer, so I suggest you find some tutorials on any functions you don't understand.
Recently, I meet two different use cases related to interval:
define interval [start, end) as:
class Inteval {
int start, end;
}
First one, I need to design a data structrue which has following APIs:
void insert(Interval interval);
boolean contain(Interval interval);
void remove(Interval interval);
For example:
I insert [1,4), [3, 6), [9, 12), the internal interval is [1, 6), [9, 12).
If I call contain([2, 5)), it will return true, although there is no seperate interval which can cover [2, 5).
contain([4, 7)) return false
When I remove([10, 11)), the internal interval is [1, 6), [9, 10), [11, 12).
My Question: What is best data structure for above use case? (assume all APIs have the same call frequency)
Second one, I need to design a data structrue which has following APIs:
void insert(Interval interval);
boolean has(Interval interval);
boolean cover(Interval interval);
boolean remove(Interval interval);
For example:
I insert [1,4), [1, 4), [3, 6), [9, 12), the internal interval is [1,4), [1, 4), [3, 6), [9, 12), not [1, 6), [9, 12)(Interval will not merge with each other).
boolean has(Interval interval) means internal intervals have an exactly same one. has([1,4)), return true, has([1,2)), return false.
boolean cover(Interval interval) means there is at least one internal interval can fully cover, not the merge one.
boolean cover([2, 5)) return false, although merging [1, 4) and [3, 6) can cover [2, 5) but neither of them can seperately cover.
boolean cover([2, 3)) return true, cover([3, 4)) return true.
remove(Interval interval) can only remove exactly same interval.
remove([1, 3)) return false remove([1, 5)) return false remove([1, 4)) return true, then internal interval will be [1, 4),[3, 6), [9, 12).
My Question: What is best data structure for second use case? (assume all APIs have the same call frequency)
I'm trying to generate some Kakuros, generate not solve.
I have all rules to generate it, but the firsts results are senseless, those are like squares.
Now I want to skip some branches, 15000 for example, to see the kakuro generated at that point.
I have tried with an Auxiliary Variable, but when it fails, the Kakuro Generator start again.
You can keep a dynamic counter-like predicate in the knowledge base that gets increased every time the main predicate is executed. The value of the counter is changed with assert and retract, i.e., it is not a variable within your main predicate but a globally stored value.
Within your main predicate, if you add the condition that the counter should be higher than some skip value, then you force backtracking over the actual rules for a specified number of iterations.
As an example, consider the built-in predicate permutation/2 which computes permutations of a list (note: tested using SWI-Prolog, other interpreters have different built-in predicates). Example output:
?- permutation([1,2,3,4,5],L).
L = [1, 2, 3, 4, 5] ;
L = [1, 2, 3, 5, 4] ;
L = [1, 2, 4, 3, 5] ;
L = [1, 2, 4, 5, 3] ;
L = [1, 2, 5, 3, 4] ;
L = [1, 2, 5, 4, 3] ;
If you want to skip the first 5 iterations in your query, you can use the following code:
:- dynamic iteration_nr/1.
iteration_nr(0).
get_permutations(L1,L2,Skip) :-
permutation(L1,L2),
iteration_nr(N),
N2 is N+1,
retract(iteration_nr(N)),
asserta(iteration_nr(N2)),
Skip < N2. % force backtracking here if counter < Skip
Example output:
?- get_permutations([1,2,3,4,5],L2,5).
L2 = [1, 2, 5, 4, 3] ;
L2 = [1, 3, 2, 4, 5] ;
L2 = [1, 3, 2, 5, 4]
Note that asserta is used here (i.e., assert at the start) instead of plain assert, which is deprecated. Note also that the counter will keep the value, so when you run this a second time in the same session the results will be different. To reset the counter you can use a separate initialization predicate, for example:
init_and_get_permutations(L1,L2,Skip) :-
retractall(iteration_nr(_)),
asserta(iteration_nr(0)),
get_permutations(L1,L2,Skip).
Further note: the use of assert and retract is not really considered 'clean' Prolog programming, because it is procedural and changes the knowledge base. However, for some applications it can be useful.
Hi I am creating a predicate list from, which if used gives you the numbers between a certain range. So say for instance
list_from(1,5,X).
would give you
X=[1,2,3,4,5].
However I got my predicate to work, but the list just keeps expanding, so it keeps increasing my one and I do not want it to. This is what is happening.
?- list_from(1,7,X).
X = [1, 2, 3, 4, 5, 6, 7] ;
X = [1, 2, 3, 4, 5, 6, 7, 8] ;
X = [1, 2, 3, 4, 5, 6, 7, 8, 9] ;
X = [1, 2, 3, 4, 5, 6, 7, 8, 9|...] ;
X = [1, 2, 3, 4, 5, 6, 7, 8, 9|...]
How do I get this to stop?
Here is my code
list_from(M,N,[]):- M > N.
list_from(M,N,[M|T]):- Mplusone is M + 1, list_from(Mplusone,N,T).
if I remove Mplusone and just M instead I get an error "Out of global stack"
Your two clauses are not mutually exclusive. You have a "guard" in the first clause saying that M > N, but you don't have the opposite condition, M =< N, in the second clause. If you trace the execution you should get an idea of what happens with your current definition.
You might also try to look at the definition of numlist/3 in SWI-Prolog's library(lists). It takes a different approach: first, make sure that the arguments make sense; then, under the condition that the initial Low is indeed lower than High (and both are integers), generate a list.
Semicolon means that you want Prolog to show you more options (that you are not satisfied with the answer). A full stop '.' will stop Prolog from providing you with alternatives.
You could also invoke list_from/3 using once/1. (Credit to #mat)
Given a Pseq similar to the following:
Pseq([1, 2, 3, 4, 5, 6, 7, 8], inf)
How would I randomise the values slightly each time? That is, not just randomly alter the 8 values once at initialisation time, but have a random offset added each time a value is sent to the stream?
Here's a neat way:
(Pseq([1, 2, 3, 4, 5, 6, 7, 8], inf) + Pgauss(0, 0.1))
First you need to know that Pgauss is just a pattern that generates gaussian random numbers. You can use any other kind of pattern such as Pwhite.
Then you need to know the really pleasant bit: performing basic math operations on Patterns (as above) composes the patterns (by wrapping them in Pbinop).