Is there an equivalent function for tuples in Matlab as there is for Mathematica?
See the first example:
http://reference.wolfram.com/language/ref/Tuples.html
I just mean the outputs and not necessarily the braces.
Thank you.
As I stated in comments, you only need to adapt this answer. You can do it as follows:
function y = tuples(x, n)
y = cell(1,n);
[y{end:-1:1}] = ndgrid(x);
y = cat(n+1, y{:});
y = reshape(y, [], n);
This gives a matrix where each row is a tuple. For example:
>> tuples([1 2 5], 2)
ans =
1 1
1 2
1 5
2 1
2 2
2 5
5 1
5 2
5 5
Related
I have a trouble find a matlab function/code to do following task
I have a vector C = [1 1 2 2 2 3 3 4]
I need resulting vector Y = [1 2 1 2 3 1 2 1]
You could create a function like the following:
C = [1 1 2 2 2 3 3 4]
Y = zeros(1,length(C))
helper = zeros(1,max(C)) % stores the count for each value
for i=1:length(C)
helper(C(i)) = helper(C(i))+1; %increases the count for the value in C(i)
Y(i) = helper(C(i));
end
Hope that helps
Try this out, if you want it in a one-liner, this will work...
Y = sum(cumsum(meshgrid(C)==meshgrid(C)',2).*(meshgrid(C)==meshgrid(C)').*eye(length(A)),1);
Not the prettiest, but it will work (you can always split it up to make it clearer)
just lets make it simple, assume that I have a 10x3 matrix in matlab. The numbers in the first two columns in each row represent the x and y (position) and the number in 3rd columns show the corresponding value. For instance, [1 4 12] shows that the value of function in x=1 and y=4 is equal to 12. I also have same x, and y in different rows, and I want to average the values with same x,y. and replace all of them with averaged one.
For example :
A = [1 4 12
1 4 14
1 4 10
1 5 5
1 5 7];
I want to have
B = [1 4 12
1 5 6]
I really appreciate your help
Thanks
Ali
Like this?
A = [1 4 12;1 4 14;1 4 10; 1 5 5;1 5 7];
[x,y] = consolidator(A(:,1:2),A(:,3),#mean);
B = [x,y]
B =
1 4 12
1 5 6
Consolidator is on the File Exchange.
Using built-in functions:
sparsemean = accumarray(A(:,1:2), A(:,3).', [], #mean, 0, true);
[i,j,v] = find(sparsemean);
B = [i.' j.' v.'];
A = [1 4 12;1 4 14;1 4 10; 1 5 5;1 5 7]; %your example data
B = unique(A(:, 1:2), 'rows'); %find the unique xy pairs
C = nan(length(B), 1);
% calculate means
for ii = 1:length(B)
C(ii) = mean(A(A(:, 1) == B(ii, 1) & A(:, 2) == B(ii, 2), 3));
end
C =
12
6
The step inside the for loop uses logical indexing to find the mean of rows that match the current xy pair in the loop.
Use unique to get the unique rows and use the returned indexing array to find the ones that should be averaged and ask accumarray to do the averaging part:
[C,~,J]=unique(A(:,1:2), 'rows');
B=[C, accumarray(J,A(:,3),[],#mean)];
For your example
>> [C,~,J]=unique(A(:,1:2), 'rows')
C =
1 4
1 5
J =
1
1
1
2
2
C contains the unique rows and J shows which rows in the original matrix correspond to the rows in C then
>> accumarray(J,A(:,3),[],#mean)
ans =
12
6
returns the desired averages and
>> B=[C, accumarray(J,A(:,3),[],#mean)]
B =
1 4 12
1 5 6
is the answer.
What is a Matlab-efficient way (no loop) to do the following operation: transform an input vector input into an output vector output such as output(i) is the number of integers in input that are less or equal than input(i).
For example:
input = [5 3 3 2 4 4 4]
would give:
output = [7 3 3 1 6 6 6]
First of all, don't use input for a variable name, it's a reserved keyword. I'll use X here instead.
An alternative way to obtain your desired result would be:
[U, V] = meshgrid(1:numel(X), 1:numel(X));
Y = sum(X(U) >= X(V))
and here's a one-liner:
Y = sum(bsxfun(#ge, X, X'))
EDIT:
If X has multiple rows and you want to apply this operation on each row, this is a little bit trickier. Here's what you can do:
[U, V] = meshgrid(1:numel(X), 1:size(X, 2));
V = V + size(X, 2) * idivide(U - 1, size(X, 2));
Xt = X';
Y = reshape(sum(Xt(U) >= Xt(V))', size(Xt))'
Example:
X =
5 3 3 2 4 4 4
3 9 7 7 1 2 2
Y =
7 3 3 1 6 6 6
4 7 6 6 1 3 3
I have found a possible answer:
output = arrayfun(#(x) sum(x>=input),input)
but it doesn't take advantage of vectorization.
I have 2 vectors (n and t) eg:
n t
1 5
5 3
5 2
2 6
2 9
Once I sample from vector n through randsample(n,1), I want to sample from the vector t but only from the values corresponding to that same one in vector n.
eg. If I drew a value of 2 from n, I then want to draw the value 6 or 9 from t. But how do I tell matlab to do that?
You could potentially do this:
out = t(n == randsample(n, 1))
This will create a filter based on whether n = its own random sample, ie if
randsample(n, 1) = 2
(n == randsample(n, 1)) = [0
0
0
1
1]
and applying this to t ie:
t(n == randsample(n, 1)) = [6
9]
which are the two corresponding values to 2 in n, but in t.
Hope this helps.
PS if you need just one value from t then you can randsample the output that this function gives you.
Simple one-liner, assuming you have them stored in a Nx2 matrix
nt = [
1 5;
5 3;
5 2;
2 6;
2 9];
meaning:
n = nt(:,1);
t = nt(:,2);
you can sample nSamples with replacement by randmonly indexing the matrix row-wise, i.e.:
nSamples = 5;
keepSamples = nt(randi(length(nt),nSamples,1),:);
I have 2 columns of x y data in data.txt like this:
0 0
1 1
2 4
3 9
4 16
5 25
Now I want to define a function f(x) where x is the first column and f(x) is the second column, and then be able to print values of this function like so:
f(2)
Which should give me 4.
How do I achieve this?
Assuming that you want some return value for numbers between the ones you have as reference, you can use linear interpolation:
function y= linearLut(x)
xl = [0 1 2 3 4 5];
yl = [0 1 4 9 16 25];
y = interp1(xl,yl,x);
end
A more generic version of the function might be:
function y= linearLut(xl,yl,x)
y = interp1(xl,yl,x);
end
And then you can create specific instances by using anonymous functions:
f = #(x)(linearLut([0 1 2 3 4],[0 1 4 9 16],x));
f(4);
You can import the file using textread(), then use find in order to select the right row.
Out of my head and untested:
function y = findinfile(x)
m = textread(data.txt)
ind = find(m(:,1)==x)
y = m(ind,2)
end
If you only need to find the correct value in the array (without interpolation) you can use:
function out=ff(b)
a = [0 1 2 3 4 5 ; 3 4 5 6 7 8]';
[c,d]=find(a(:,1)==b);
out = a(c,2);