MATLAB stores 00 and 01 as 0 and 1 respectively. How can I make MATLAB store 00 as 00 and 01 as 01 instead of 0 and 1 only...here is my code.. I am talking about the statements with <-- only..In fact I want to input the result as initial population(chromosome) to a genetic algorithm.
function [x]=abc()
r=randi([0 3],1,20);
for i=1:20
if r(i)==0
x(i)=00; %// <--
elseif r(i)==1
x(i)=01; %// <--
elseif r(i)==2
x(i)=10;
elseif r(i)==3
ex(i)=11;
end
end
end
It looks like you want to store the binary representation of your numbers, so you can use the function dec2bin
and the best thing, you don't even need a loop ;)
r=randi([0 3],1,20);
x = dec2bin(r,2) ;
>> x
x =
10
00
11
11
10
11
10
01
...
Related
I have a cell array of size 5x5 as below
B= 00 10 11 10 11
01 01 01 01 11
10 00 01 00 01
10 10 01 01 11
10 10 10 00 10
And two column vectors
S1= 21
23
28
25
43
S2= 96
85
78
65
76
I want to create a new cell array of the same size as B say 5x5 such that it satisfies the following condition
Final={S1 if B{i}=11
S1 if B{i}=10
S2 if B{i}=01
S2 if B{i}=00
So the resulting output would be something like this
Z = s2 s1 s1 s1 s1
s2 s2 s2 s2 s1
s1 s2 s2 s2 s2
s1 s1 s2 s2 s1
s1 s1 s1 s2 s1
ie Z= 96 21 21 21 21
85 85 85 85 23
28 78 78 78 78
25 25 65 65 25
43 43 43 76 43
I tried using the if condition but i get error saying
'Error: The expression to the left of the equals sign is not a valid target for an assignment.'
for i=1:1:128
for j=1:1:16
if fs{i,j}=00
Z{i,j}=S1{i,j}
elseif fs{i,j}= 01
Z{i,j}=S2{i,j}
elseif fs{i,j}= 10
Z{i,j}=S1{i,j}
elseif fs{i,j}= 11
Z{i,j}=S2{i,j}
end
end
I think I'm making a mistake in the if statement as well as the expressions I'm using. Where am i going wrong? Please help thanks in advance.
Use == for comparison and = for assignment. So if fs{i,j}==00, etc.
Edit: Matlab is really designed for highly vectorized operations. Nested loops are slow compared to native functions, and typically can be replaced with vectorized versions. Is there any particular reason why you are using cell arrays instead of matrices, especially when you only have numeric data?
If B, S1, and S2 were matrices your code could be written in one highly efficient line that will run much much faster:
Z = bsxfun(#times, S1, B == 11 | B == 10) + bsxfun(#times, S2, B == 01 | B == 0)
Since B is a cell array you will want to convert it to a matrix using cell2mat unless you'd like to use cellfun.
Instead, you can just call B_mat = cell2mat(B), followed by (B_mat>=10).*repmat(S1,1,5) + (B_mat<10).*repmat(S2,1,5).
It's possible that your cell array actually contains binary values, possibly represented as strings, in which case the conditions used above would need to be changed. Then using cellfun may be necessary.
I have been working on viterbi decoder in matlab2009 on simple 1/2 rate convolutional encoder.
Here is my code
trel = poly2trellis(3,[7 5]);
msg = [ 0 1 0 1 1 1 0 0 1 0 1 0 0 0 1 ];
code = convenc(msg,trel);
% Traceback Length
tblen = 5;
ucode = real(awgn(1-2*code,tblen,'measured'));
dcd = vitdec(ucode,trel,tblen,'cont','unquant');
According to this input code
i am getting the code = 00 11 10 00 01 10 01 11 11 10 00 10 11 00 11
which is correct
but talking about the dcd which is output after viterbi decoder is coming incorrect
i.e 000000101110010. which is far different from my msg input.
guide me where i am going incorrect
The decoded output depends on the type of opmode Input you selected.
In case of cont, there is a delay in the output equal to tblen number of symbols whereas there are 'term' and trunc modes as well.
You can compare the initial msg(1,end-tblen) symbols with dcd(1,tblen+1:end). They are same!
You may check vitdec at Matlab help.
I have been breaking my head about trying to optimise a matlab script that needs to process quite long arrays.
Basically, there are 2 arrays: AbsoluteTimeTag and Channel.
AbsoluteTimeTag will hold int values signifying time that are recorded using a 16 bit counter. Since the counter is limited to 2^16 values it will often roll over during the course of the measurement. Channel registers this and when it does, bitand(Channel,2048) will evaluate true.
How these arrays are generated is out of my control and the overflow markers occur "in sync" with the data coming in.
It is now easy to reconstruct the absolute time by doing:
AbsoluteTimeTag(i) = NoOfOverflows * 65536 + TimeTag(i);
In a loop:
for i=1:NumberOfRecords
%Running through all records, if we meet anything other than an
%overflow record, we van just calculate its absolute time based on
%current overflow count and its timetag.
AbsoluteTimeTag(i) = NoOfOverflows * 65536 + TimeTag(i);
% We are running through all records so if we encounter an overflow
% (signified by bitand(..., 2048), we add 1 to the overflow count.
if bitand(Channel(i),2048)
NoOfOverflows = NoOfOverflows + 1;
end;
end;
I have been really breaking my head on how to potentially vectorise this (since Matlab is pretty bad at loops). So far however, I do not see the light for some reason.
Problem is that the number of overflows up to a certain record index along AbsoluteTimeTag can change as you walk the vector from start to end.
I do not know how I could express "count all occurrences of overflow up to this point" in a vectored operation.
Can somebody comment on whether or not this might be feasible at all?
EDIT
Example data would look like this:
TimeTag (each element is an event for which time is counted un a 2^3 register for simplicity):
[ 01 03 04 07 xx 02 03 04 05 xx 01 03 04 07 xx ... ]
overflow:
[ 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 ... ]
Which would need to yield
[ 01 03 04 07 xx 10 11 12 13 xx 17 19 20 23 xx ... ]
The reason xx is there is because originally, all records, both the events and the overflows are in one large uint32 array where each record holds different types of info on the different bits. The xx locations can undergo any operation but they are further meaningless when considering the TimeTag records. I have a logical array keeping track of what locations hold actual meaningful data.
"count all occurrences of ... to this point" in a vectored operation would be best expressed as cumsum.
Assuming NoOfOverflows is initialized as zero before the start of the loop and AbsoluteTimeTag, Timetag have NumberOfRecords as their number of elements , see if this works for you -
%// Get the overflow for all Channel entries in one go
bitand_all = bitand(Channel,2048)~=0;
%// AbsoluteTimeTag appears to be a cumsum of overflows plus Timetag
AbsoluteTimeTag = [0 ; cumsum(bitand_all(1:end-1).*65536)]+ TimeTag;
%// Get the count of overflows as NoOfOverflows
NoOfOverflows = sum(bitand_all);
I have a matrix like:
A=
10 31 32 22
32 35 52 77
68 42 84 32
I need a function like mode but with range, for example mymode(A,10) that return 30, find most frequent number in range 0-10, 10-20, 20-30, .... and return most number in range.
You can use histc to bin your data into the ranges of your desire and then find the bin with the most members using max on the output of histc
ranges = 0:10:50; % your desired ranges
[n, bins] = histc(A(:), ranges); % bin the data
[v,i] = max(n); % find the bin with most occurrences
[ranges(i) ranges(i+1)] % edges of the most frequent bin
For your specific example this returns
ans =
30 40
which matches with your required output, as the most values in A lay between 30 and 40.
[M,F] = mode( A((A>=2) & (A<=5)) ) %//only interested in range 2 to 5
...where M will give you the mode and F will give you frequency of occurence
> A = [10 31 32 22; 32 35 52 77; 68 42 84 32]
A =
10 31 32 22
32 35 52 77
68 42 84 32
> min = 10
min = 10
> max = 40
max = 40
> mode(A(A >= min & A <= max))
ans = 32
>
I guess by the number of different answers that we may be missing your goal. Here is my interpretation.
If you want to have many ranges and you want to output most frequent number for every range, create a cell containing all desired ranges (they could overlap) and use cellfun to run mode() for every range. You can also create a cell with desired ranges using arrayfun in a similar manner:
A = [10 31 32 22; 32 35 52 77; 68 42 84 32];
% create ranges
range_step = 10;
range_start=[0:range_step:40];
range=arrayfun(#(r)([r r+range_step]), range_start, 'UniformOutput', false)
% analyze ranges
o = cellfun(#(r)(mode(A(A>=r(1) & A<=r(2)))), range, 'UniformOutput', false)
o =
[10] [10] [22] [32] [42]
Quick MATLAB question.
What would be the best/most efficient way to select a certain number of elements, 'n' in windows of 'm'. In other words, I want to select the first 50 elements of a sequence, then elements 10-60, then elements 20-70 ect.
Right now, my sequence is in vector format(but this can easily be changed).
EDIT:
The sequences that I am dealing with are too long to be stored in my RAM. I need to be able to create the windows, and then call upon the window that I want to analyze/preform another command on.
Do you have enough RAM to store a 50-by-nWindow array in memory? In that case, you can generate your windows in one go, and then apply your processing on each column
%# idxMatrix has 1:50 in first col, 11:60 in second col etc
idxMatrix = bsxfun(#plus,(1:50)',0:10:length(yourVector)-50); %'#
%# reshapedData is a 50-by-numberOfWindows array
reshapedData = yourVector(idxMatrix);
%# now you can do processing on each column, e.g.
maximumOfEachWindow = max(reshapedData,[],1);
To complement Kerrek's answer: if you want to do it in a loop, you can use something like
n = 50
m = 10;
for i=1:m:length(v)
w = v(i:i+n);
% Do something with w
end
There's a slight issue with the description of your problem. You say that you want "to select the first 50 elements of a sequence, then elements 10-60..."; however, this would translate to selecting elements:
1-50
10-60
20-70
etc.
That first sequence should be 0-10 to fit the pattern which of course in MATLAB would not make sense since arrays use one-indexing. To address this, the algorithm below uses a variable called startIndex to indicate which element to start the sequence sampling from.
You could accomplish this in a vectorized way by constructing an index array. Create a vector consisting of the starting indices of each sequence. For reuse sake, I put the length of the sequence, the step size between sequence starts, and the start of the last sequence as variables. In the example you describe, the length of the sequence should be 50, the step size should be 10 and the start of the last sequence depends on the size of the input data and your needs.
>> startIndex = 10;
>> sequenceSize = 5;
>> finalSequenceStart = 20;
Create some sample data:
>> sampleData = randi(100, 1, 28)
sampleData =
Columns 1 through 18
8 53 10 82 82 73 15 66 52 98 65 81 46 44 83 9 14 18
Columns 19 through 28
40 84 81 7 40 53 42 66 63 30
Create a vector of the start indices of the sequences:
>> sequenceStart = startIndex:sequenceSize:finalSequenceStart
sequenceStart =
10 15 20
Create an array of indices to index into the data array:
>> index = cumsum(ones(sequenceSize, length(sequenceStart)))
index =
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
>> index = index + repmat(sequenceStart, sequenceSize, 1) - 1
index =
10 15 20
11 16 21
12 17 22
13 18 23
14 19 24
Finally, use this index array to reference the data array:
>> sampleData(index)
ans =
98 83 84
65 9 81
81 14 7
46 18 40
44 40 53
Use (start : step : end) indexing: v(1:1:50), v(10:1:60), etc. If the step is 1, you can omit it: v(1:50).
Consider the following vectorized code:
x = 1:100; %# an example sequence of numbers
nwind = 50; %# window size
noverlap = 40; %# number of overlapping elements
nx = length(x); %# length of sequence
ncol = fix((nx-noverlap)/(nwind-noverlap)); %# number of sliding windows
colindex = 1 + (0:(ncol-1))*(nwind-noverlap); %# starting index of each
%# indices to put sequence into columns with the proper offset
idx = bsxfun(#plus, (1:nwind)', colindex)-1; %'
%# apply the indices on the sequence
slidingWindows = x(idx)
The result (truncated for brevity):
slidingWindows =
1 11 21 31 41 51
2 12 22 32 42 52
3 13 23 33 43 53
...
48 58 68 78 88 98
49 59 69 79 89 99
50 60 70 80 90 100
In fact, the code was adapted from the now deprecated SPECGRAM function from the Signal Processing Toolbox (just do edit specgram.m to see the code).
I omitted parts that zero-pad the sequence in case the sliding windows do not evenly divide the entire sequence (for example x=1:105), but you can easily add them again if you need that functionality...