Question on the array generating sequence in Raku - sequence

I've come across this code at rosettacode
my #pascal = [1], { [0, |$_ Z+ |$_, 0] } ... Inf;
.say for #pascal[^4];
# ==>
# [1]
# [1 1]
# [1 2 1]
# [1 3 3 1]
Inside the explicit generator block, I know how the individual operators like the list flattening | and the zip operator Z+ work but I have difficulty comprehending how they cooperate to generate the next array. Can somebody explain in detail how it works? Thank you.
Note: The code is slightly rearranged for brevity, i.e. it's superficially different than the one in Rosetta.

So let's take a look at what's going on.
First up the Sequence generator ... this takes a list of starting values, a code block itself and and end point.
It uses the starting values to generate each next item in the list so lets start with #pascal[0] that's simple enough : [1]
For #pascal[1] we call the code block with our value in #pascal[0] like so :
sub ( $array ) {
[0, |$array Z+ |$array, 0]
}
You'll note I've made it into a sub, this is just so I can explain things easier. In the anonymous code block $_ is the incoming data and I've called it $array. So what code to we run when $array == [1]?
[0, |[1] Z+ |[1], 0] => [1,1]
So here's a question what happens if we don't use the | ?
[0, [1] Z+ [1], 0] => [1,1]
It's the same! So whys it there? Well what happens if we set $array == [3]?
[0, [3] Z+ [3], 0] => [1,1]
Weird? No, because the Z+ transforms like this :
[0, [3] Z+ [3], 0] => [0 + [3], [3] + 0] => [1,1]
Z makes a new list by zipping the elements with the given operator + between them. + is doing a numerical computation and the Numerical representation of an Array is the number of elements in it, in this case 1 both times.
And this is where the | slip operator comes in, it slips the array it's given open merging into the list context it's in. So lets go back to #pascal[1]
[0, |[1] Z+ |[1], 0] => [0, 1 Z+ 1, 0] => [0 + 1, 1 + 0] => [1,1]
Ok.. So #pascal[2] is calling the same block but now passing in [1,1]
[0, |[1, 1] Z+ |[1, 1], 0] => [0, 1, 1 Z+ 1, 1, 0] => [0 + 1, 1 + 1, 1 + 0] => [1,2,1]
And so on into Infinity!
I hope that's helped to explain what's going on?

This is a somewhat interesting application of the sequence operator, in so far as the values that it produces each time are arrays. So:
[1] is the first array produced at the start of the sequence
The block indicates how to produce the next array in the sequence. It takes one argument, which is the previous sequence value
The Inf will never be matched, so the sequence will go on forever
A simpler example may be helpful: the sequence [1], [1,1], [1,1,1], .... That is, we want to produce an array that is the previous item in the sequence with an extra 1 at the end. We could do this:
my #ones = [1], { [|$_, 1] } ... Inf;
.say for #ones[^4];
Producing:
[1]
[1 1]
[1 1 1]
[1 1 1 1]
The first time the block is called, it gets [1] in $_. We slip that with |, thus producing an array [1, 1]. That is passed to the block the second time, and so forth.
So, breaking down [0, |$_ Z+ |$_, 0]. The outer square brackets are an array composer. The rest can be read as 0, |$_ zipped with |$_, 0, using the + operator to zip the things.
The first call to be block will pass [1], thus we will be zipping 0, 1 and 1, 0. Zipping with an operator applies it pairwise, meaning it will calculate 0 + 1, 1 + 0. The overall result is the array [1,1].
The second call to the block gets that [1,1]. It forms the lists 0, 1, 1 and 1, 1, 0, and then the zip operator forms the pairwise addition again, which is 0 + 1, 1 + 1, 1 + 0. The overall result is the array [1,2,1].
Effectively, then, the result grows an element each time, resulting from the pairwise addition of the previous result padded with a zero at either end.

Related

is there a version of tf.unique that behaves like the bash uniq?

I would like for non-consecutive identical elements in a tensor to be assigned distinct idx (i.e., second output of tf.unique). Is there a way to accomplish that? Thanks.
OK my brain is less foggy today than usual, and here is a quick solution:
x = [1, 1, 2, 2, 3, 2, 1]
def bash_unique_with_counts(vector):
segment_starts = tf.concat(
[[1], tf.to_int32(tf.not_equal(vector[:-1], vector[1:]))], axis=0)
new_vector = tf.cumsum(segment_starts, exclusive=False)
return tf.unique_with_counts(new_vector)
y, idx, count = bash_unique_with_counts(x)
print(tf.Session().run(count))
[2 2 1 1 1]

Utilizing Redis for setting and retrieving bits

Main idea is to store random bits to redis and retrieve and drop them when required.
Pseudocode which sets the boolean value to the next position of the bitcollection. This way I should have a growing collection of bits.
Setter:
boolean = rand(1/0)
SETBIT bitcollection boolean (BITCOUNT bitcollection + 1)
Getter:
GETBIT bitcollection 0
Questions:
How can I drop the retrieved bit from position 0?
Is it possible to retrieve more than just the first bit like (0..n)?
Ruby code for better understanding what I try to achieve.
bitcollection = [0, 1, 0, 1, 0]
# set
bitcollection.push 1 #=> [0, 1, 0, 1, 0, 1]
# get
bitcollection.shift(1) #=> 0
puts bitcollection #=> [1, 0, 1, 0, 1]

How do I get a tensor representing the "on" positions in the original tensor?

I have a Tensorflow label that may be exemplified by any of the following: [1, 2], [3], []. The first has two classes, the second has one class, and the third has none. I'd like to then turn that these another tensor that looks like the following:
[1, 2] --> [0, 1, 1, 0].
[3] --> [0, 0, 0, 1].
[] --> [0].
The number of classes is defined beforehand (here it's 3). In some sense, this is the inverse of this question - Tensorflow Extract Indices Not Equal to Zero.
The following works:
sparse_categories = tf.convert_to_tensor([[1 if k == i else 0 for k in range(num_categories+1)] for i in range(num_categories+1)])
values = tf.cond(tf.size(values) > 0, lambda: values, lambda: [0])
values = tf.reduce_sum(tf.gather(sparse_categories, values))

What is the difference between a[:,:-1] and a[:,-1]?

How to understand the difference between a[:,:-1] and a[:,-1]?
a = np.array([[1,2],[3,4],[5,6]])
b = a[:,:-1]
print b
The output for this is:
[[1]
[3]
[5]]
And for the following code-
b = a[:,-1]
print b
The output is:
[2 4 6]
Let's create another numpy array for understanding.
my_array = np.array([[1,2,3],[4,5,6],[7,8,9]])
This array contains three different arrays. That is, my_array is an array of arrays.
type(my_array) and type(my_array[0]) will both return numpy.ndarray
When you execute my_array[:,-1], this means goto every element in my_array and print the last item in that element. The : before , means all and -1 means the last element.
So the output of my_array[:,-1] will be
array([3, 6, 9])
meaning- The last element of each array inside my_array.
Now, when you execute my_array[:,:-1], the output is:
array([[1, 2],
[4, 5],
[7, 8]])
Meaning- print all the items in all arrays of my_array except the last item.
Here : means goto all elements and :-1 means exclude the last item.

Delete rows from a ndarray in python

I have a 2D - array A, which contains the x and y coordinates of points
array([[ 0, 0],
[ 0, 0],
[ 0, 0],
[ 3, 4],
[ 4, 1],
[ 5, 10],
[ 9, 7]])
as you can see the point ( 0 , 0 ) appears more often.
I want to delete this point so that the array looks like this:
array([[ 3, 4],
[ 4, 1],
[ 5, 10],
[ 9, 7]])
Since the array in real is very huge, it is very important to do this without for loops, otherwise it takes very long.
I'm new to python but i'm used to matlab, where I can solve it very easily with:
A (A(:,1) == 0 & A(:,2) == 0, :) = []
I thought it is almost the same or very similar in python, but I can't figure it out - am totally stuck. Errors like "use a.any()/all()" or "ufunc "bitwise_and" not supported for the input types" appear and I don't know what I should change.
Technically what you are doing in MATLAB is not deleting elements from A. What you are actually doing is creating a new array that lacks the elements of A. It is equivalent to:
>> A = A (A(:,1) ~= 0 | A(:,2) ~= 0, :);
You can do exactly the same thing in numpy:
>>> a = a[(a[:,0] != 0) | (a[:,1] != 0), :]
However, thanks to numpy's automatic broadcasting, you can make this simpler:
>>> a = a[(a != [0, 0]).any(1)]
This will work for any target array so long as it has the same number of columns as a.