Is there a way to generate sequence of number with a given step, similar to R's seq(from, to, step) function?
e.g.
> seq(1,20,2)
[1] 1 3 5 7 9 11 13 15 17 19
user2393012's answer is close, but not exactly what question was looking for. The below works well -
q)seq:{x+z*til ceiling(1+y-x)%z}
q)seq[1;20;2]
1 3 5 7 9 11 13 15 17 19
An alternative (but not better than the simpler arithmetic solutions)
q){-1_(y>=)(z+)\x}[1;20;2]
1 3 5 7 9 11 13 15 17 19
Simply use arithmetic :-)
q){[step;start;length] start+step*til length}[2;0;10]
0 2 4 6 8 10 12 14 16 18
q){[step;start;length] start+step*til length}[3;0;10]
0 3 6 9 12 15 18 21 24 27
Another option (slight variation of terrylynch solution):
q) {(z+)\[floor(y-x)%z;x]} [1;20;2]
1 3 5 7 9 11 13 15 17 19
Related
given list of lists, how to merge them into a single list taking up to k items at a time from each of the lists until all items are merged?
for example, the following input and output is expected:
q)alternate[1] ("abc";"de";"fghi")
"adfbegchi"
for k~1 items at a time, the solution is:
q)mesh:{raze[y]rank x} / https://code.kx.com/phrases/sort/#mesh
q)alternate:{mesh[raze where each 1&{0|x-1}\[count each x];x]}
q)alternate ("abc";"de";"fghi")
"adfbegchi"
the above works because:
q)mesh[0 1 2 0 1 2 0 2 2;] ("abc";"de";"fghi")
"adfbegchi"
How to elegantly generalize alternate for any k<=max count each x ? python solution is here
the below should achieve this
q)f:{raze[y]iasc raze(x-1)|til'[count'[y]]};
q)f[1;("abc";"de";"fghi")]
"adfbegchi"
q)f[2;("abc";"de";"fghi")]
"abdefgchi"
Not sure if this is any faster or cleaner but a different approach:
q)alt:{(raze/)value each(s;::;)each til max count each s:x cut'y};
q)alt[1;("abc";"de";"fghi")]
"adfbegchi"
q)alt[2;("abc";"de";"fghi")]
"abdefgchi"
q)alt[2;(1 2 3 4;5 6 7;8 9 10 11;12 13 14 15)]
1 2 5 6 8 9 12 13 3 4 7 10 11 14 15
q)alt[3;(1 2 3 4;5 6 7;8 9 10 11;12 13 14 15)]
1 2 3 5 6 7 8 9 10 12 13 14 4 11 15
I was hoping to use case but unfortunately case doesn't like lists of different count (that aren't atomic values)
not sure if this is the fastest solution, substituting x for the hardcoded 1 in the alternate function above, and thus making it dyadic:
q)alternate:{mesh[raze where each x&{0|y-x}[x]\[count each y];y]}
q)alternate[2] ("abc";"de";"fghi")
"abdefgchi"
q)alternate[2] (1 2 3 4;5 6 7;8 9 10 11;12 13 14 15)
1 2 5 6 8 9 12 13 3 4 7 10 11 14 15
q)alternate[3] (1 2 3 4;5 6 7;8 9 10 11;12 13 14 15)
1 2 3 5 6 7 8 9 10 12 13 14 4 11 15
edit:
naïve benchmark comparison with #terrylynch 's alt and #Matthew Madill's f :
q)\t:10000 f[2] ("abc";"de";"fghi")
49
q)\t:10000 alternate[2] ("abc";"de";"fghi")
56
q)\t:10000 alt[2] ("abc";"de";"fghi")
87
q)\t:10000 f[3] (1 2 3 4;5 6 7;8 9 10 11;12 13 14 15)
55
q)\t:10000 alternate[3] (1 2 3 4;5 6 7;8 9 10 11;12 13 14 15)
61
q)\t:10000 alt[3] (1 2 3 4;5 6 7;8 9 10 11;12 13 14 15)
103
I would like to explore a better way to apply binary function which iterate via each element of the two argument. Let make the question simpler by using below function as an example:
func:{x+y}
a:til 10
q)a
0 1 2 3 4 5 6 7 8 9
b:a
q)b:a
q)b
0 1 2 3 4 5 6 7 8 9
What I what to get is the cross production such that each element of the argument will cross each other and apply the function. My expected result is
0 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 10 2 3 4 5 6 7 8 9 10 11 3 4 5 6 7 8 9 10 11 12 4 5 6 7 8 9 10 11 12 13 5 6 7 8 9 10 11 12 13 14 6 7 8 9 10 11 12 13 14 15 7 8 9 10 11 12 13 14 15 16 8 9 10 11 12 13 14 15 16 17 9 10 11 12 13 14 15 16 17 18
My current solution is crossing the the list of argument first:
(func/) each (a cross b)
I wonder is there a better way to doing that? simply using func'[a;b] will just get a pairwise result which not what I want.
The following should be what you are looking for:
a +/:\: b
The same can apply for other defined functions too, for example:
a {x mod y}/:\: b
You do not need cross for this just each-right or each-left. Because '+' is a vector function you can just iterate over one list and use other list as full vector.
q) a+/:b
Is there a MATLAB function to generate this matrix?:
[1 2 3 4 5 6 7 ... n;
2 3 4 5 6 7 8 ... n+1;
3 4 5 6 7 8 9 ... n+2;
...;
n n+1 n+2 ... 2*n-1];
Is there a name for it?
Thanks.
Yes indeed there's a name for that matrix. It's known as the Hankel matrix.
Use the hankel function in MATLAB:
out = hankel(1:n,n:2*n-1);
Example with n=10:
out =
1 2 3 4 5 6 7 8 9 10
2 3 4 5 6 7 8 9 10 11
3 4 5 6 7 8 9 10 11 12
4 5 6 7 8 9 10 11 12 13
5 6 7 8 9 10 11 12 13 14
6 7 8 9 10 11 12 13 14 15
7 8 9 10 11 12 13 14 15 16
8 9 10 11 12 13 14 15 16 17
9 10 11 12 13 14 15 16 17 18
10 11 12 13 14 15 16 17 18 19
Alternatively, you may be inclined to want a bsxfun based approach. That is certainly possible:
out = bsxfun(#plus, (1:n), (0:n-1).');
The reason why I wanted to show you this approach is because in your answer, you used repmat to generate the two matrices to add together to create the right result. You can replace the two repmat calls with bsxfun as it does the replication under the hood.
The above solution is for older MATLAB versions that did not have implicit broadcasting. For recent versions of MATLAB, you can simply do the above by:
out = (1:n) + (0:n-1).';
My standard approach is
repmat(1:n,n,1)+repmat((1:n)',1,n)-1
I need a function that splits a vector in smaller frames with an overlap, like buffer, but instead of column-wise, it should be done row-wise.
This is how buffer works:
x = 1:20
x = buffer(x, 10, 5);
x = 0 1 6 11
0 2 7 12
0 3 8 13
0 4 9 14
0 5 10 15
1 6 11 16
2 7 12 17
3 8 13 18
4 9 14 19
5 10 15 20
What I want would be this though:
x = 0 0 1 2
1 2 3 4
3 4 5 6
5 6 7 8
7 8 9 10
9 10 11 12
11 12 13 14
13 14 15 16
15 16 17 18
17 18 19 20
Is there any function or way to achieve that? Maybe combination of buffer + some rearranging?
First figure out the answer in columns, then transpose the resulting matrix:
buffer(x, 4, 2).'
This question already has an answer here:
Extract rows from matrix and make a new matrix in MATLAB
(1 answer)
Closed 10 years ago.
I have a 6639x5 matrix in Matlab and I would like to select certain specific rows in a particular order( say 1st,11th,21st,31st rows... and subsequent additions of 10 until end) to form a new matrix.Any ideas?
Thank you,
Oti.
subset = a(1:10:end, :);
Selects every 10th row until the end, and all columns.
Example:
>> a = magic(5)
a =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
>> a(1:2:end, :)
ans =
17 24 1 8 15
4 6 13 20 22
11 18 25 2 9