Matlab vector to its binary representation - matlab

I have a vector like A: 1 3 7 8
I would like to construct a binary vecor such as B (1 2 3 4 5 6 7 8)
(1 0 1 0 0 0 1 1)

You can use just indexing:
B = zeros(1, max(A));
B(A) = 1;
Or use sparse:
B = full(sparse(1, A, 1));
These approaches don't require arithmetical operations, and thus may be faster than previous answers.

How about:
binA = sum( de2bi(2.^(A-1)) , 1 )
binA =
1 0 1 0 0 0 1 1

You can first convert the vector to an integer (base 10),
d = sum(A(:).*(10.^[numel(A)-1: -1: 0])(:))
then convert d to binary using
b = de2bi(d)
You can then extract as many bits as you want from b

Related

Create matrix with N-4 rows and N-2 columns

Would you give me any comments on this question? I need to create a matrix in Matlab, following the description below:
for a given N and three values a, b and c. I want to create a (N-4)x(N-2) matrix, e.g. for N=8
a b c 0 0 0
0 a b c 0 0
0 0 a b c 0
0 0 0 a b c
Thanks a Lot
What you are trying to create is a toeplitz matrix. One you know the name, it's simple.
%construct the first row
row=zeros(N-2,1);
row(1:3)=[a,b,c];
%construct the first column
col=zeros(N-4,1);
col(1)=a;
%call the function
toeplitz(col,row)
Result with a=4;b=2;c=3;N=8;
ans =
4 2 3 0 0 0
0 4 2 3 0 0
0 0 4 2 3 0
0 0 0 4 2 3
You could solve using the identity matrix function eye() and some matrix concatenation:
N = 8;
a = 1;
b = 2;
c = 3;
a_I = [zeros(N-4, 0), a*eye(N-4), zeros(N-4, 2)];
b_I = [zeros(N-4, 1), b*eye(N-4), zeros(N-4, 1)];
c_I = [zeros(N-4, 2), c*eye(N-4), zeros(N-4, 0)];
X = a_I + b_I + c_I
Which produces the output
X =
1 2 3 0 0 0
0 1 2 3 0 0
0 0 1 2 3 0
0 0 0 1 2 3
You can also make it slightly more general and let the scalars a, b and c be contained in a vector:
N = 8;
v = [1 2 3];
X = zeros(N-4, N-2);
for ii = 1:length(v)
X = X + [zeros(N-4, ii-1), v(ii)*eye(N-4), zeros(N-4, length(v)-ii)];
end
Which produces the same output.
try this fully vectorized function:
function b=bandmat(a, N, M)
% license: CC-BY
% example: bandmat([1,2,3],4,6)
b=a(:).';
b(M+1)=0;
b=repmat(b,1,N);
b=reshape(b(1:end-N),M,N).';

More efficient way of symmetrizing a square matrix in MATLAB?

I have an "almost symmetric" matrix, which I wish to symmetrize in MATLAB. For example, I wish to symmetrize
>> A = [0 0 1; 2 0 3; 0 3 0]
A =
0 0 1
2 0 3
0 3 0
into
>> B
B =
0 2 1
2 0 3
1 3 0
Safe assumptions are that diagonal entries of A are all zero and that "the bits to change" are always 0. E.g., I changed A(1, 2) and A(3, 1) in the above example, and original values at both locations were 0.
My best attempt based on #Photon's comment (Thanks Photon!) is
>> C = -0.5*(A.'.*A~=0)+1;
>> B = (A+A.').*C
B =
0 2 1
2 0 3
1 3 0
Is there a better (more efficient or faster) way of achieving this?
What about
B = max( A, A.' );
Assuming all entries of A are non-negative.

Replace specific matrix position with array value without using for loop in MATLAB

can I know how can I replace values in specific matrix position without using for loop in MATLAB? I initialize matrix a that I would like to replace its value on specified row and column for each no. This has to be done a few time within num for loop. The num for loop is important here because I would want the update the value in the original code.
The real code is more complicated, I am simplifying the code for this question.
I have the code as follow:
a = zeros(2,10,15);
for num = 1:10
b = [2 2 1 1 2 2 2 1 2 2 2 2 1 2 2];
c = [8.0268 5.5218 2.9893 5.7105 7.5969 7.5825 7.0740 4.6471 ...
6.3481 14.7424 13.5594 10.6562 7.3160 -4.4648 30.6280];
d = [1 1 1 2 1 1 1 1 1 1 3 1 6 1 1];
for no = 1:15
a(b(no),d(no),no) = c(1,no,:)
end
end
A sample output for, say no 13 is as follows:
a(:,:,13) =
Columns 1 through 8
0 0 0 0 0 7.3160 0 0
0 0 0 0 0 0 0 0
Columns 9 through 10
0 0
0 0
Thank you so much for any help I could get.
It can be done using sub2ind, which casts the subs to a linear index.
Following your vague variable names, it would look like this (omitting the useless loop over num):
a = zeros(2,10,15);
b = [2 2 1 1 2 2 2 1 2 2 2 2 1 2 2];
d = [1 1 1 2 1 1 1 1 1 1 3 1 6 1 1];
c = [8.0268 5.5218 2.9893 5.7105 7.5969 7.5825 7.0740 4.6471 ...
6.3481 14.7424 13.5594 10.6562 7.3160 -4.4648 30.6280];
% // we vectorize the loop over no:
no = 1:15;
a(sub2ind(size(a), b, d, no)) = c;
Apart from the sub2ind based approach as suggested in Nras's solution, you can use a "raw version" of sub2ind to reduce a function call if performance is very critical. The related benchmarks comparing sub2ind and it's raw version is listed in another solution. Here's the implementation to solve your case -
no = 1:15
a = zeros(2,10,15);
[m,n,r] = size(a)
a((no-1)*m*n + (d-1)*m + b) = c
Also for pre-allocation, you can use a much faster approach as listed in Undocumented MATLAB blog post on Preallocation performance with -
a(2,10,15) = 0;
The function sub2ind is your friend here:
a = zeros(2,10,15);
x = [2 2 1 1 2 2 2 1 2 2 2 2 1 2 2];
y = [1 1 1 2 1 1 1 1 1 1 3 1 6 1 1];
z = 1:15;
dat = [8.0268 5.5218 2.9893 5.7105 7.5969 7.5825 7.0740 4.6471 ...
6.3481 14.7424 13.5594 10.6562 7.3160 -4.4648 30.6280];
inds = sub2ind(size(a), x, y, z);
a(inds) = dat;
Matlab provides a function 'sub2ind' may do what you expected.
with variable as the same you posted:
idx = sub2ind(size(a),b,d,[1:15]); % return the index of row a column b and page [1:15]
a(idx) = c;

MATLAB - Add Value at the first column of a matrix

I want to add one value at the beginning of a matrix for example, my matrix is
0,0,0,0,0,0
0,1,1,1,0,0
1,0,0,1,0,0
1,1,1,0,0,0
then I want to add '1' or '0' at the first column therefore it will become like this
1,0,0,0,0,0,0
1,0,1,1,1,0,0
1,1,0,0,1,0,0
1,1,1,1,0,0,0
0,0,0,0,0,0,0
0,0,1,1,1,0,0
0,1,0,0,1,0,0
0,1,1,1,0,0,0
how can I do that in MATLAB?
You can concatenate matrices without creating another one from scratch like this:
% your matrix
A = [ 0,0,0,0,0,0;
0,1,1,1,0,0;
1,0,0,1,0,0;
1,1,1,0,0,0 ];
A_with_zeros = [zeros(size(A,1),1) A]
A_with_ones = [ones(size(A,1),1) A]
% Output:
% A_with_zeros = [ 0 0 0 0 0 0 0
% 0 0 1 1 1 0 0
% 0 1 0 0 1 0 0
% 0 1 1 1 0 0 0 ]
%
% A_with_ones = [ 1 0 0 0 0 0 0 0
% 1 0 0 1 1 1 0 0
% 1 0 1 0 0 1 0 0
% 1 0 1 1 1 0 0 0 ]
Documentation about concatenating matrices:
horzcat
vertcat
These two documentation pages describe in details the existing methods that let you concatenate arrays horizontally (what I did in the example above) and vertically (if you wanted to add lines to your matrix).
Use the array concatenation syntax - [a b] to glue matrices together horizontally, [a; b] to glue them together vertically.
Like so:
>> a = ones(3,1)
a =
1
1
1
>> b = magic(3)
b =
8 1 6
3 5 7
4 9 2
>> c = [a b]
c =
1 8 1 6
1 3 5 7
1 4 9 2
Vertically:
>> d = ones(1,3)
d =
1 1 1
>> e = [d; b]
e =
1 1 1
8 1 6
3 5 7
4 9 2
If you mismatch the dimensions, MATLAB will give you an error. Don't do this:
>> f = ones(1,10)
f =
1 1 1 1 1 1 1 1 1 1
>> g = magic(3)
g =
8 1 6
3 5 7
4 9 2
>> [f; g]
??? Error using ==> vertcat
CAT arguments dimensions are not consistent.
Create a new matrix with an extra column, copy the old matrix in, then put the data for the new column in at (:, 1).
output = zeros(size(input, 1), size(input, 2) + 1);
output(:, 2:end) = input;
output(:, 1) = new_column;
or if you mean that you want to get two matricies, one with a column of 1s and one with a column of 0s:
output0 = zeros(size(input, 1), size(input, 2) + 1);
output0(:, 2:end) = input;
output1 = ones(size(input, 1), size(input, 2) + 1);
output1(:, 2:end) = input;

Set column to 0 with probability p

I've got a matrix A with the dimensions m X n. For every column i (i > 0and i <= n) I want to flip a coin and fill the whole column with 0 values with probability p. How can this be accomplished in MATLAB?
Example:
A = [1 2 3 4; 5 6 7 8] and p = 0.5 could result in
A' = [1 0 3 0; 5 0 7 0]
You can use the function rand() to generate an array of uniformly distributed random numbers, and use logical indexing to select colums where that array is less than p:
A = [1 2 3 4; 5 6 7 8];
p = 0.5;
A(:, rand(size(A,2), 1)<p) = 0
A =
0 2 0 0
0 6 0 0
You can do something like bsxfun(#times, A, rand(1, size(A, 2)) > p). Alex's answer is admittedly better, though.