Suppose we have matrix A like this:
10 5 8 6 2
A= 9 3 5 4 1
12 5 7 2 6
How can I choose a subset of A where there is no third column(for example)??
like this:
10 5 6 2
B = 9 3 4 1
12 5 2 6
I know I can say:
B = A(:,[1 2 4 5]);
but I need a better way
You can use
B = A(:,1:size(A,2)~=n);
with n as selected column (see answer of #freude).
His solution also works fine in any case, but locial indexing (as here) should be faster than his approach.
If we assume that the column to remove is n, it reads:
B = A(:,[1:n-1 n+1:end]);
An alternative, though not a single line, is to copy over and then remove the bit you don't want by setting it to empty:
B = A;
B(:,n) = [];
I mention this because in the case that you don't need B as a new matrix but just want to take one column out of A, this is the simplest/easiest to read way of doing it.
Related
I am trying to reverse the elements of the matrix such that for given matrix order of the elements get reversed.
my code is as shown for the 3x3 matrix is working.
X = [ 1 2 3 ; 4 5 6 ; 7 8 9 ];
B = [fliplr(X(3,:));fliplr(X(2,:));fliplr(X(1,:))];
input X =
1 2 3
4 5 6
7 8 9
output:
B =
9 8 7
6 5 4
3 2 1
the above code I am trying to generalize for any matrix with the following code
[a,b]=size(X);
for i=0:a-1
A = [fliplr(X(a-i,:))];
end
but get only last row as output.
output A =
3 2 1
please help me to concatenate all the rows of the matrix one above to each other after it got reversed.
rot90 is the function made for this purpose.
B = rot90(A,2);
Your code doesn't work because you overwrite A in every loop iteration. Instead, you should index into A to save each of your rows.
However, fliplr can flip a whole matrix. You want to flip left/right and up/down:
B = flipud(fliplr(X));
This is the same as rotating the matrix (as Sardar posted while I was writing this):
B = rot90(X,2);
A totally different approach would work for arrays of any dimensionality:
X(:) = flipud(X(:));
I am trying to compare two vectors of different size. For instance when I run the code below:
A = [1 4 3 7 9];
B = [1 2 3 4 5 6 7 8 9];
myPadded = [A zeros(1,4)];
C = ismember(myPadded,B)
I get the following output:
C = 1 1 1 1 1 0 0 0 0
However, I want an output that will reflect the positions of the compared values, hence, I would like an output that is displayed as follows:
C = 1 0 1 1 0 0 1 0 1
Please, I need some help :)
There are 2 points. First, you are writing the inputs of ismember in the wrong order. Additionally, you do not need to grow your matrix. Simply try ismember(B, A) and you will get what you expect.
The function ismember(myPadded, B) returns a vector the same size of myPadded, indicating if the i-th element of myPadded is present in B.
To get what you want, just invert parameter order: ismember(B, myPadded).
A quick way of doing this is to use logical indexing. This will only work if the last digit of B is included in A.
A = [1 4 3 7 9];
c(A) = 1; % or true.
An assumption here is that you want to subindex a vector 1:N, so that B always is B = 1:N. In case the last digit is not one this is easy to fix. Just remember to return all to its previous state after you are done. It will be 2 rows extra though.
This solution is meant as a special case working on a very common problem.
From the integers 1,...,N I would like to take k random distinct combinations without repetition of size p. For example, if N=10, k=4 and p=3, a possible outcome would be:
1 4 9
9 4 2
3 5 2
1 8 4
But not:
1 4 9
9 4 2
3 5 3
1 9 4
For two reasons:
[1 4 9] and [1 9 4] are the same combination.
[3 5 3] is not without repetition.
Note that getting all possible combinations and the (randomly) picking k of them easily runs into memory problems.
Okay, I have found a solution that works for me. My main concerns were:
I want the k combinations to be random.
processing time.
The below function samples a single random combination of size p, (namely row = randperm(N,p)) each iteration and adds that combination if it isn't already present.
Of the three parameters, mainly k influences the processing time. For not too large k, this codes runs in matters of seconds. The most extreme case I myself will encounter is N = 10^6, k = 2000, p = 10 and it still runs in 1 second.
I hope this also helps other people, as I've come across this question on multiple sites, without a satisfactory answer.
function C = kcombsn(N,k,p)
C = randperm(N,p);
Csort = sort(C,2);
while size(C,1) < k
row = randperm(N,p);
row_sort = sort(row);
if isempty(intersect(row_sort,Csort,'rows'))
C = [C; row];
Csort = [Csort; row_sort];
end
end
end
Edit:
I also posted the code on the MATLAB File Exchange.
I've two matrix a and b and I'd like to combine the rows in a way that in the first row I got no duplicate value and in the second value, columns in a and b which have the same row value get the maximum value in new matrix. i.e.
a = 1 2 3
8 2 5
b = 1 2 5 7
2 4 6 1
Desired output
c = 1 2 3 5 7
8 4 5 6 1
Any help is welcomed,please.( the case for accumulation is asked here)
Accumarray accepts functions both anonymous as well as built-in functions. It uses sum function as default. But you could change this to any in-built or anonymous functions like this:
In this case you could use max function.
in = horzcat(a,b).';
[uVal,~,idx] = unique(in(:,1));
out = [uVal,accumarray(idx,in(:,2),[],#max)].'
Based upon your previous question and looking at the help file for accumarray, which has this exact example.
[ii, ~, kk] = unique([a(1,:) b(1,:)]);
result = [ ii; accumarray(kk(:), [a(2,:) b(2,:)], [], #max).'];
The only difference is the anonymous function.
I am new to matlab and just wondering if you guys can help me out with this problem.
For instance, I have two matrices:
A = [X1 X2 X3 X4]
B = [Y1; Y2; Y3]
now what I really want to achieve is to multiply these two matrices in this way:
[X1Y1 X2Y1 X3Y1 X4Y1;
X1Y2 X2Y2 X3Y2 X4Y2;
X1Y3 X2Y3 X3Y3 X4Y3;
.... and so on]
I tried using A(1,:).*B(:,1) but matlab is saying that matrix dimensions must agree.
I just don't know how to manipulate this on matlab but in excel is possible.
This is a simple outer product. kron is not needed (although it will work.) bsxfun is wild overkill, although will yield what you have asked for. repmat is inappropriate, because while it will help you do what you wish, it replicates the arrays in memory, using more resources than are needed. (Avoid using inefficient programming styles when there are good ones immediately at your disposal.)
All you need use is the simple * operator.
A is a row vector. B a column vector.
C = B*A
will yield the result C(i,j)=B(i)*A(j), which is exactly what you are looking for. Note that this works because B is 3x1 and A is 1x4, so the "inner" dimensions of B and A do conform.
In MATLAB, IF you are unsure if something works, TRY IT!
A = [1 2 3 4];
B = [1;2;3];
C = B*A
ans =
1 2 3 4
2 4 6 8
3 6 9 12
See that kron did indeed work, although I'd bet that use of kron here is probably less efficient than is the simple outer product multiply.
C = kron(B,A)
C =
1 2 3 4
2 4 6 8
3 6 9 12
As well, bsxfun will work here too, although since we are using a general tool to do something that a basic operator will do, I'd bet it is slightly less efficient.
C = bsxfun(#times,B,A)
C =
1 2 3 4
2 4 6 8
3 6 9 12
The WORST choice is repmat. Again, since it artificially replicates the vectors in memory FIRST, it must go out and grab big chunks of memory in the case of large vectors.
C = repmat(B,1,4).*repmat(A,3,1)
C =
1 2 3 4
2 4 6 8
3 6 9 12
I suppose for completeness, you could also have used meshgrid or ndgrid. See that it is doing exactly what repmat did, but here it explicitly creates new matrices. Again, this is a poor programming style when there are good tools to do exactly what you wish.
[BB,AA] = ndgrid(B,A)
BB =
1 1 1 1
2 2 2 2
3 3 3 3
AA =
1 2 3 4
1 2 3 4
1 2 3 4
C = BB.*AA
C =
1 2 3 4
2 4 6 8
3 6 9 12
What you need to understand is exactly why each of these tools COULD have been used for the job, and why they are different.
In Matlab there is * and .* and they are very different.
* is normal matrix multiplication which is what you want i.e. B*A, note the B must come first as the inner dimension must match. You can multiply a column by a row but not a row by a column (unless they have the same number of elements).
.* is element by element multiplication in which case the matrices must be exactly the same size and shape so for example [1 2 3].*[4 5 6] = [1*4 2*5 3*6] = [4 10 18]
Do not do a ".*". You should rather do a "*".
The ".*" is for index by index multiplication and should have given you [X1Y1 X2Y2 X3Y3] were they vectors have been equal in size.
If you do the regular multiplication "*", this is actually matrix multiplication.
I think you just need to transpose one of the vectors. You are multiplying a column vector (A(1,:)) with a row vector (B(:,1)). This should work:
C = A(1,:).*B(:,1)';