How can I slice a shaped array in Perl 6? - multidimensional-array

I can make a shaped (fixed-size) array:
my #array[3;3] = (
< 1 2 3 >,
< 4 5 6 >,
< 7 8 9 >
);
say #array; # [[1 2 3] [4 5 6] [7 8 9]]
say #array[1;1]; # 5
How can I slice this to get any particular column or diagonal that I want (rows are easy)?
How do I turn a list of the indices in each dimension into the right thing to put in the square braces?
And, surely there's some fancy syntax that would keep me from doing something complicated:
my #diagonal = gather {
my #ends = #array.shape.map: { (0 ..^ $^a).List };
for [Z] #ends {
take #array[ $_ ] # how do I make that $_[0];$_[1];...
};
}

How can I slice this to get any particular column or diagonal that I want?
As far as I know, you can't currently use slice syntax with shaped arrays (notwithstanding your "(rows are easy)" comment which confuses me per my comment on your post).
The obvious solution is to drop the shape and use slice syntax:
my #array = ( < 1 2 3 >, < 4 5 6 >, < 7 8 9 > );
say #array[1]; # 4 5 6 (second row)
say #array[1;*]; # same
say #array[*;1]; # 2 5 8 (second column)
If you wanted to retain the bounds-checking safety of using a shaped array (and/or the C array compatibility of a shaped native array if I'm right that's a thing) then you'd presumably have to keep two copies of the array around, using one to retain the desired aspect of shaped arrays, the other to slice.
How do I turn a list of the indices in each dimension into the right thing to put in the square braces?
Each dimensional slice before the final leaf one must be separated from the next by a ;.
I'm not yet clear on whether that's because the ; is a statement separator (within the subscript) or a list-of-list indicator, nor how to programmatically turn a list of indices into that form. (Investigation continues.)
And, surely there's some fancy syntax that would keep me from doing something complicated [for a diagonal slice]:
say #array[*;{$++}]; # 1 5 9 (diagonal)
The first ; separated field in the [...] array subscript corresponds to the first dimension in the array, i.e. the rows in the array.
Specifying * means you want to include all rows rather than specify the specific row(s).
The last field corresponds to the leaves of the subscript, the actual elements to be accessed.
I first tried just $++ rather than {$++} but that gave me column zero for all elements presumably because the language/roast and/or Rakudo only evaluates a scalar index value once per call of the [...] subscript operator.
Then I reasoned that if an index is Callable it'll be called and it might be called once per row. And that worked.
I think that corresponds to this code in Rakudo.
At first glance this appears to mean you can't use a Callable to calculate a leaf slice and I note that the roast'd slicing for "calculated indices" doesn't include use of a Callable. Perhaps I'm just not looking at it right.

You probably have seen that that returns a not yet implemented error (which was inserted to solve this bug;
Partially dimensioned views of shaped arrays not yet implemented. Sorry.
In this case, it might be better to just unshape the array and use a more traditional approach:
use v6;
my #array = (
< 1 2 3 >,
< 4 5 6 >,
< 7 8 9 >
);
my #diagonal = gather {
my #ends = ((0,0),(1,1),(2,2));
for #ends -> #indices {
take #array[ #indices[0] ][#indices[1]];
};
}
say #diagonal;
By looking at the synopsis on the subject, I would say that approach is not really specified. So when all is said and done, you will probably have to use either EVAL or macros (when they are eventually implemented, of course... )

Related

Julia: Turn Vector into multiple m x n matrices without a loop

Let's say I have a vector V, and I want to either turn this vector into multiple m x n matrices, or get multiple m x n matrices from this Vector V.
For the most basic example: Turn V = collect(1:75) into 3 5x5 matrices.
As far as I am aware this can be done by first using reshape reshape(V, 5, :) and then looping through it. Is there a better way in Julia without using a loop?
If possible, a solution that can easily change between row-major and column-major results is preferrable.
TL:DR
m, n, n_matrices = 4, 2, 5
V = collect(1:m*n*n_matrices)
V = reshape(V, m, n, :)
V = permutedims(V, [2,1,3])
display(V)
From my limited knowledge about Julia:
When doing V = collect(1:m*n), you initialize a contiguous array in memory. From V you wish to create a container of m by n matrices. You can achieve this by doing reshape(V, m, n, :), then you can access the first matrix with V[:,:,1]. The "container" in this case is just another array (thus you have a three dimensional array), which in this case we interpret as "an array of matrices" (but you could also interpret it as a box). You can then transpose every matrix in your array by swapping the first two dimensions like this: permutedims(V, [2,1,3]).
How this works
From what I understand; n-dimensional arrays in Julia are contiguous arrays in memory when you don't do any "skipping" (e.g. V[1:2:end]). For example the 2 x 4 matrix A:
1 3 5 7
2 4 6 8
is in memory just 1 2 3 4 5 6 7 8. You simply interpret the data in a specific way, where the first two numbers makes up the first column, then the second two numbers makes the next column so on so forth. The reshape function simply specifies how you want to interpret the data in memory. So if we did reshape(A, 4, 2) we basically interpret the numbers in memory as "the first four values makes the first column, the second four values makes the second column", and we would get:
1 5
2 6
3 7
4 8
We are basically doing the same thing here, but with an extra dimension.
From my observations it also seems to be that permutedims in this case reallocates memory. Also, feel free to correct me if I am wrong.
Old answer:
I don't know much about Julia, but in Python using NumPy I would have done something like this:
reshape(V, :, m, n)
EDIT: As #BatWannaBe states, the result is technically one array (but three dimensional). You can always interpret a three dimensional array as a container of 2D arrays, which from my understanding is what you ask for.

Generate Unique Combinations of Integers

I am looking for help with pseudo code (unless you are a user of Game Maker 8.0 by Mark Overmars and know the GML equivalent of what I need) for how to generate a list / array of unique combinations of a set of X number of integers which size is variable. It can be 1-5 or 1-1000.
For example:
IntegerList{1,2,3,4}
1,2
1,3
1,4
2,3
2,4
3,4
I feel like the math behind this is simple I just cant seem to wrap my head around it after checking multiple sources on how to do it in languages such as C++ and Java. Thanks everyone.
As there are not many details in the question, I assume:
Your input is a natural number n and the resulting array contains all natural numbers from 1 to n.
The expected output given by the combinations above, resembles a symmetric relation, i. e. in your case [1, 2] is considered the same as [2, 1].
Combinations [x, x] are excluded.
There are only combinations with 2 elements.
There is no List<> datatype or dynamic array, so the array length has to be known before creating the array.
The number of elements in your result is therefore the binomial coefficient m = n over 2 = n! / (2! * (n - 2)!) (which is 4! / (2! * (4 - 2)!) = 24 / 4 = 6 in your example) with ! being the factorial.
First, initializing the array with the first n natural numbers should be quite easy using the array element index. However, the index is a property of the array elements, so you don't need to initialize them in the first place.
You need 2 nested loops processing the array. The outer loop ranges i from 1 to n - 1, the inner loop ranges j from 2 to n. If your indexes start from 0 instead of 1, you have to take this into consideration for the loop limits. Now, you only need to fill your target array with the combinations [i, j]. To find the correct index in your target array, you should use a third counter variable, initialized with the first index and incremented at the end of the inner loop.
I agree, the math behind is not that hard and I think this explanation should suffice to develop the corresponding code yourself.

The number of occurences of elements in a vector [JULIA]

I have a vector of 2500 values composed of repeated values and NaN values. I want to remove all the NaN values and compute the number of occurrences of each other value.
y
2500-element Array{Int64,1}:
8
43
NaN
46
NaN
8
8
3
46
NaN
For example:
the number of occurences of 8 is 3
the number of occurences of 46 is 2
the number of occurences of 43 is 1.
To remove the NaN values you can use the filter function. From the Julia docs:
filter(function, collection)
Return a copy of collection, removing elements for which function is false.
x = filter(y->!isnan(y),y)
filter!(y->!isnan(y),y)
Thus, we create as our function the conditional !isnan(y) and use it to filter the array y (note, we could also have written filter(z->!isnan(z),y) using z or any other variable we chose, since the first argument of filter is just defining an inline function). Note, we can either then save this as a new object or use the modify in place version, signaled by the ! in order to simply modify the existing object y
Then, either before or after this, depending on whether we want to include the NaNs in our count, we can use the countmap() function from StatsBase. From the Julia docs:
countmap(x)
Return a dictionary mapping each unique value in x to its number of
occurrences.
using StatsBase
a = countmap(y)
you can then access specific elements of this dictionary, e.g. a[-1] will tell you how many occurrences there are of -1
Or, if you wanted to then convert that dictionary to an Array, you could use:
b = hcat([[key, val] for (key, val) in a]...)'
Note: Thanks to #JeffBezanon for comments on correct method for filtering NaN values.
y=rand(1:10,20)
u=unique(y)
d=Dict([(i,count(x->x==i,y)) for i in u])
println("count for 10 is $(d[10])")
countmap is the best solution I've seen so far, but here's a written out version, which is only slightly slower. It only passes over the array once, so if you have many unique values, it is very efficient:
function countmemb1(y)
d = Dict{Int, Int}()
for val in y
if isnan(val)
continue
end
if val in keys(d)
d[val] += 1
else
d[val] = 1
end
end
return d
end
The solution in the accepted answer can be a bit faster if there are a very small number of unique values, but otherwise scales poorly.
Edit: Because I just couldn't leave well enough alone, here's a version that is more generic and also faster (countmap doesn't accept strings, sets or tuples, for example):
function countmemb(itr)
d = Dict{eltype(itr), Int}()
for val in itr
if isa(val, Number) && isnan(val)
continue
end
d[val] = get(d, val, 0) + 1
end
return d
end

array index difference notation Python <-> R

what is the Python notation a[i-j] translated to R? As far as I understand it, it should be the array element at position i-j. But in R it seems to be the array until the ith element subtracted by the element at position j.
R and Python have somewhat similar indexing properties, with the main difference being that indexing in Python starts at 0 while in R it starts at 1. Beyond the index start, there is also the fact that Python supports negative indexing, while in R negative indexing means that you are removing the element at that exact index from your list. To be specific to your case, the indexing list[i-j] could be somewhat the same thing if i - j returns a positive integer. Otherwise, you are talking about two completely different things. The illustration below should be helpful to you:
Python:
#Create a list
lst = [1,3,5,6,7,7]
#index element at 4-2 (which is 2)
lst[4-2] # returns 5
#index element at 2-4 (which is -2) or lst[len(lst)-2]
lst[2-4] # returns 7
R:
lst <- c(1,3,5,6,7,7)
#indexing element at 4-2 (which is 2)
lst[4-2] # returns 3 (because R indexing starts at 1, not 0)
[1] 3
#BUT indexing element at 2-4 (which is -2) does not work,
#because it means that you are removing the element at index 2, i.e. 3
lst[2-4] #returns the original list without element at index 2
[1] 1 5 6 7 7
These are the main differences in indexing a list that I could offer to help with your question. The differences in indexing become more prominent as you tackle more complicated data structures in both languages.
I hope this is helpful.

Completing a list of possible binary sequences give a binary sequence with gaps

So, I am working on a program in Scilab which solves a binary puzzle. I have come across a problem however. Can anyone explain to me the logic behind solving a binary sequence with gaps (like [1 0 -1 0 -1 1 -1] where -1 means an empty cell. I want all possible solutions of a given sequence. So far I have:
function P = mogelijkeCombos(V)
for i=1:size(V,1)
if(V(i) == -1)
aantalleeg = aantalleeg +1
end
end
for i=1:2^aantalleeg
//creating combos here
end
endfunction
sorry that some words are in dutch
aantalleeg means amountempty by which I mean the amount of empty cells
I hope I gave you guys enough info. I don't need any code written, I'd just like ideas of how I can make every possible rendition as I am completely stuck atm.
BTW this is a school assignment, but the assignment is way bigger than this and it's just a tiny part I need some ideas on
ty in advance
Short answer
You could create the combos by extending your code and create all possible binary words of the length "amountempty" and replacing them bit-for-bit in the empty cells of V.
Step-by-step description
Find all the empty cell positions
Count the number of positions you've found (which equals the number of empty cells)
Create all possible binary numbers with the length of your count
For each binary number you generate, place the bits in the empty cells
print out / store the possible sequence with the filled in bits
Example
Find all the empty cell positions
You could for example check from left-to-right starting at 1 and if a cell is empty add the position to your position list.
V = [1 0 -1 0 -1 1 -1]
^ ^ ^
| | |
1 2 3 4 5 6 7
// result
positions = [3 5 7]
Count the number of positions you've found
//result
amountempty = 3;
Create all possible binary numbers with the length amountempty
You could create all possible numbers or words with the dec2bin function in SciLab. The number of possible words is easy to determine because you know how much separate values can be represented by a word of amountempty bits long.
// Create the binary word of amountEmpty bits long
binaryWord = dec2bin( i, amountEmpty );
The binaryWord generated will be a string, you will have to split it into separate bits and convert it to numbers.
For each binaryWord you generate
Now create a possible solution by starting with the original V and fill in every empty cell at the position from your position list with a bit from binaryWordPerBit
possibleSequence = V;
for j=1:amountEmpty
possibleSequence( positions(j) ) = binaryWordPerBit(j);
end
I wish you "veel succes met je opdracht"

Resources