Output in Vector form - matlab

I am getting output of reshape function as follow
s1 =
11
00
10
11
01
11
10
10
10
10
10
10
10
01
10
01
How to convert s1 as
[1 1 0 0 1 0 1 1 0 1 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 1 1 0 0 1]
so i can pick up bit values
s1(1) will be 1
s1(3) will be 0
s1(5) will be 1
I have tried it with reshape and transpose but not picking up correct bit values. Appreciate any help..
I am doing following operation with below code
converting cipher text to bytes, then I am calculating index variable (called as p) & formula is MOD(No of Bytes,3).. I have ciphertext length as 5 bytes so Index Variable (p) is 2.. I will always have index varaible values as 0 or 1 or 2 which will be based on no. of Bytes
Say ciphertext is 11001011 01111010 10101010 10011001 01010101
This data is five bytes there for inde variable is 2
11001011 01111010 10101010 10011001 01010101
Now
for first two bits (11) , index variable to be assigned as 2
for next two bits (00), index variable to be assigned as 0
for next two bits (10), index variable to be assigned as 1
for next two bits (11), index variable to be assigned as 2..so on till end of my bits.
Other Example
Ciphertet with Three Bytes 11001011 01111010 10101010
Index Variable (p) will be 0
for first two bits (11) , index variable to be assigned as 0
for next two bits (00), index variable to be assigned as 1
for next two bits (10), index variable to be assigned as 2
for next two bits (11), index variable to be assigned as 0..
so on till end of my bits..
s = '11001011 01111010 10101010 10011001 01010101'
p = rem(numel(regexp(s,' [01]'))+1,3)
k = (0:2)'
s1 = reshape(regexprep(s,' ',''),2,[])'
n = size(s1,1)
N = k(:,ones(fix((n+1)/3)+1,1))
P = N(find(N(:,1) == p)+(0:n-1))'

Well s1' will give you
[11 00 10 11 ...]
but if you show us the input to your function I might be able to give you the answer you really want.

The key to this question is that the elements are of char type. Then you could use reshape like this:
reshape(s1.',1, [])
ans = 11001011...
This is a similar question.

Related

Counting islands in a matrix (preferably in IDL)

How can I count the number of values that are contiguous in an matrix? For example, if
A= [ 1 0 1 0 0 0 0 \
1 1 1 0 0 0 1\
1 1 0 1 1 1 1]
is a 7 by 3 matrix then the result should indicate that there are 12 contiguous values that are "1" (highlighted in bold), that there are 8 contiguous 0 values (highlighted in italics) and one lone 0 value. Code in IDL is preferred but MATLAB would also be helpful.
This is what you can do in MATLAB using the bwconncomp function. This is a function in the Image Processing Toolbox. I don't know a whole lot about IDL, it might have a similar function.
bwconncomp returns a struct with some information, one of the fields is PixelIdxList, which is a cell array with one element per connected component. Each of these elements is a vector with the indices to one of the array elements in the connected component. For the case of the 1 elements in your example, this cell array will have one vector with 12 values. For the case of the 0 elements, it will have two vectors, one with 1 value and one with 8:
>> A = [ 1 0 1 0 0 0 0 ; 1 1 1 0 0 0 1 ; 1 1 0 1 1 1 1 ];
>> CC = bwconncomp(A==1, 8);
>> cellfun(#numel, CC.PixelIdxList)
ans =
12
>> CC = bwconncomp(A==0, 8);
>> cellfun(#numel, CC.PixelIdxList)
ans =
1 8
The bwconncomp takes 4 or 8 as the second argument. This specifies what are considered connected elements (contiguous values, neighbors). 4 means only the 4 elements N,S,E,W are connected; 8 means also diagonal connections exist (8 neighbors).

How to rediagonalize the diagonal of a matrix in MATLAB?

I have a 5x5 matrix, V1, with values and a classification in both the first row and first column. If you wanted to, you could think of sectors in an economy that have a classification. The first two sectors have a 3-digit classification, the last two have a 4-digit classification.
V1 =
0 101 111 1234 1111
101 4 0 7 0
111 5 8 0 0
1234 6 0 6 2
1111 0 0 4 9
Now, I want to rediagonalize all columns that have a 4-digit code using MATLAB. That means in four-digit columns the values should be summed up over the whole column and shifted to the diagonal. In particular, the code should perform the following steps:
If the classification code has four digits AND the classification code is equal in both the first row AND the first column, then sum up the whole column (excl. the first value of the column, which is the classification code itself)
Elseif the classification code has three digits in the column, then leave the value as is
Else assign a zero.
The resulting matrix should look like this:
V1 =
0 101 111 1234 1111
101 4 0 0 0
111 5 8 0 0
1234 6 0 17 0
1111 0 0 0 11
I have tried the following code, but it didn't work:
[vrow vcol] = size(V1)
for c = 2:vcol;
for r = 2:vrow;
if all([ V1(1,c) == V1(r,1), numel(num2str(V1(1,c))) > 3, numel(num2str(V1(r,1))) > 3 ]) ;
V1(r,c) = sum(V1(2:end,c)) ;
elseif numel(num2str(V1(1,c))) == 3;
V1(r,c) = V1(r,c);
else
V1(r,c) = 0;
end
end
end
With the above code, I got the following result, which is sort of close to the desired result, only the column summations do not work yet:
V1 =
0 101 111 1234 1111
101 4 0 0 0
111 5 8 0 0
1234 6 0 10 0
1111 0 0 0 9
Thank you for any hints!
Since you're changing elements of V1 as the code executes, but also relying on values in V1 to get your answer (when you sum columns), you'll have errors if you set a value to 0 before it's needed in a sum. Below, I've fixed that issue by initializing a second matrix V2 as your output. I've also gone ahead and removed a few unneeded lines, as explained in the comments
[vrow vcol] = size(V1);
V2 = zeros(vrow, vcol);
for c = 2:vcol;
for r = 2:vrow;
if all([ V1(1,c) == V1(r,1), numel(num2str(V1(1,c))) > 3]) ; %Third statement was redundant
V2(r,c) = sum(V1(2:end,c)) ;
elseif numel(num2str(V1(1,c))) == 3;
V2(r,c) = V1(r,c);
end %We intialized whole thing to 0, so we don't need to set elements to 0
end
end

Inserting Ones at pseudo-fixed Intervals

I have the following row vector:
A = zeros(1,200);
I'd like to insert a '1' every 2-3 columns until I have exactly 80 ones in total that are approximately evenly spaced - as opposed to having fixed spacing - with the first 2 columns being zeros.
e.g.
0 0 1 0 1 0 0 1 0 0 1 0 1 ...
It would be nice if the combination could be permuted as well so that more than one row vector satisfies the criteria.
Thanks!
You could use repelem (run-length encoding) to do this. The way that repelem works is that we have two inputs: the values and the number of times each value is repeated.
For example
values = [0 1];
repeats = [1 2];
repelem(values, repeats)
% 0 1 1
We can also have duplicate values in the values array
values = [0 1 0 1];
repeats = [2 1 1 1];
repelem(values, repeats)
% 0 0 1 0 1
We can utilize this to solve your problem.
First we construct the values matrices to simply alternate between 0 and 1 meaning that we want the expanded matrix to contain some 0's followed by a 1, some 0's followed by a 1, etc.
values = ~mod(1:80, 2);
% 0 1 0 1 0 1 0 1 ....
In your case, the number of times each 0 is going to be repeated is going to be either 1 or 2. Each 1 however, is only going to be repeated once. To make this happen we use rand to pick randomly between 1 and 2 repeats. Then we assign all the repeats for 1 values to be a single repeat.
repeats = randi([1 2], size(values));
% Make sure that the 1's are always only repeated once
repeats(values) = 1;
We use 80 entries in the repeats and values arrays just to make sure that we end up with at least 80 values in the final (expanded) array.
Now apply the repelem and keep only the first 80 values
result = repelem(values, repeats);
result = result(1:80);
% 0 1 0 0 1 0 0 1 0 1 0 0 1
You can do this with a few standard functions and array indexing. Something like this ...
A = zeros(1,200);
ixs = round(cumsum(2 + rand(200,1)));
A(ixs(ixs<200))=1;
%Sample result here, first 20 entries: 0 0 1 0 1 0 0 1 0 0 1 0 1 0 0 1 0 1 0 1
What we're doing here is:
Setting up the A array (this is clear)
Defining an oversized array of index values to set to one (more on that below)
Then using that index to set values to one, trimming the oversize.
In terms of creating the index ixs, in innermost portion (2 + rand(200,1)) creates a 200x1 array of values between 2 and 3. Using cumsum generates the cumulative sum of this array, and then round rounds the values to an integer, which can be used for indexing. For example, the first 10 values is ixs look like this, for a particular run:
>> ixs(1:10)'
ans =
3 5 8 11 13 16 18 20 22 24
Since the number of 1 values will vary each time, I set this up to be oversized. That is, the last few values are [487 489 491 497 500], larger than the actual size required. This is why the values need to be trimmed with applying the index.
A = zeros(1,200);
idx = cumsum(1 + randi(2,80,1)); % This is the main trick
A(idx) = 1;
cumsum(1 + randi(2,80,1)) gets you the indexes for exactly 80 elements in A which need to be switched to 1 spaced by 2 or 3 (randomly)

how to group elements in matrix in matlab?

For eg. I have [1;1;0;0;1;0;0;0;1;1;1;0] this as column and I want output the group of four elements:
1100
1000
1110
How to do this? I tried it with accumarray() but it is not working.
Assuming your vector only contains the elements 0 and 1 and has n*4 elements:
bvec = [1;1;0;0;1;0;0;0;1;1;1;0];
bvec = char(reshape( bvec, 4, numel(bvec)/4 ) + '0').';
Let's break it down:
reshape( bvec, numel(bvec)/4, 4 );
breaks your column vector (could be row vector as well) into a matrix that has 4 rows (your 4 bit[?] groups), it is a 4*n matrix of type double,
+ '0' adds a numerical value of 48 to represent the ASCII character '0'; this translates all values of 0 to 48 (ASCII '0') and all values of 1 to 49 (ASCII '1')
char( ... ) converts your matrix to a character type matrix.
.' transposes the matrix in the very end to get a n*4 matrix.
Result:
bvec =
1100
1000
1110
how is this?
A = [1;1;0;0;1;0;0;0;1;1;1;0];
B = reshape(A,4,3)'; %//DONT FORGET THE `'` or your results would be wrong...
C = strcat(num2str(B)); %C is a char Array currently
C =
1 1 0 0
1 0 0 0
1 1 1 0
Remove the space:
you can do C(:,2:3) =[];C(:,3:4)=[];C(:,4:5)=[]; to create a 3 x 4 char Array:
C =
1100
1000
1110
but why would you right? So the better way is:
regexprep(cellstr(C),'[^\w'']',''); %//Now a cell Array. It is generally better practice to store strings as Cell Array instead of Char Array.
ans =
'1100'
'1000'
'1110'

How do I sum the max value of every row in a matrix?

A=[ 2 4 8 20 0 0;
1 3 6 18 22 0;
0 3 5 8 18 20]
and then from the above matrix, I want to account average of max value of every rows.
so I wish the result :
result=average(20+22+20)=20,67
thankf for your help.
[C,I] = max(...) finds the indices of the maximum values of A, and returns them in output vector I. If there are several identical maximum values, the index of the first one found is returned.
for your problem
maxValues= max(A,[],2)
result=Mean(maxValues)