Error in for loop in matlab - matlab

I have an error in the following forloop. I know because the end value of the first for is going to be changed and it is not acceptable for Matlab to change in inside iteration. But would you have any idea how to overcome to it? By the way I used while, but does not help me at all. Data are as follow:
D = [
2.39484592826072e-05 286
4.94140791861196e-05 161
5.07906972800045e-05 163
0.000103133134300751 141
0.000142755898501384 136
0.000143741615840070 152
0.000188072960663613 177
0.000203545320971960 1
0.000269110781516704 296
0.000333161025069404 293
0.000351184122591795 167
0.000393661764751196 299
0.000469154814856272 173
0.000516662289403544 181
0.000537612407901054 156
0.000698464342131732 246
0.000848447859349023 66
0.000875283151707512 75
0.00102377583629824 68
0.00110034589129900 277
0.00110693756077989 129
0.00120680501123819 87
0.00151080017572355 78
0.00159156469379168 248
0.00190852817897233 270
0.00192106167039306 133
0.00224677708557380 258
0.00246430115488258 264
0.00288772180685041 255
0.00299392149856582 81
0.00315341807121748 242
0.00327625233716732 27
0.00362308575885149 124
0.00434568780796603 220
0.00443389247698617 239
0.00470947127244510 60
0.00474015278667278 23
0.00481651908877289 230
0.00487750364266560 53
0.00510342992049100 56
0.00513758569662983 228
0.00515453564704144 121
0.00515656244518627 232
0.00526922882200147 8
0.00547349131456174 50
0.00553337871530176 117
0.00569159206242299 18
0.00620144292620718 13
0.00630382865700000 119
0.00755647842280271 92
0.00983041839684126 40
0.00997057619578698 98
0.0102611966834032 44
0.0103337998140422 100
0.0105132461082006 37
0.0106952804631761 109
0.0107424055503829 208
0.0109630950142485 111
0.0115094667290339 105
0.0119529682389369 107];
ymin= D(:,1);
mean_value = 0.00773867192661190;
criteria = min(ymin);
kk = 1;
diff = 60;
and here is the code that I would have an error for the changing size_D which is expected.
while criteria < mean_value
if isempty(B)
ind_crt = find(min(ymin));
B(kk,:) = D(ind_crt,:);
D(ind_crt,:) = [];
kk = kk + 1;
end
criteria = min(min(D));
size_D = size(D,1);
for ii=1:size_D
if D(ii,1) == criteria
size_B = size(B,1);
for jj = 1:size_B
if abs(D(ii,2) - B(jj,2)) > diff
B(kk,:) = D(ii,:);
D(ii,:)= [];
kk = kk + 1;
end
size_D = size_D -1;
criteria = min(min(D))
end
end
end
end
Update:
Here is the error:
Attempted to access D(59,1); index out of bounds because
size(D)=[58,2].
Error in local_minima (line 50)
if D(ii,1) == criteria

Replace your for loop by a while loop, so that the code in the loop is run only if the condition ii<=size_D is verified:
ii=0;
while ii<=size_D
ii=ii+1;
%loop code
instead of the
for ii=1:size_D
%loop code

Related

How to perform reduced row echelon form on a non-square GF matrix (GF(2^8)) in matlab

%GF(2^8)
m=8
mat1 = gf([160 28 233 185 176],8);
result1 = gf([160 28 233 185 176],8)/gf([160],8)
% 1 77 174 32 220
[R,jb] = rref([1 77 174 32 220;189 244 80 245 190])
I use the result from result1 as 1st row and progressively add the next row vector [189 244 80 245 190]
% reduced row echelon
mat2 = [1 77 174 32 220;189 244 80 245 190]
a = gf([1 77 174 32 220;189 244 80 245 190],8);
r2 = a(2,:); r1 = gf(189,8) * a(1,:);
subt = r2 -r1; a(2,:)= subt./gf(122,8);
a(1,:) = a(1,:)- (gf(77,8) *a(2,:));
disp(a)
mat3 = [[1 0 101 105 110]; [0 1 163 128 97]; [157 233 247 64 118]];
m3 = gf(mat3,8);
m3(3,:)= m3(3,:) - (gf(157,8) * m3(1,:))
m3(3,:)= m3(3,:) - (gf(233,8) * m3(2,:))
m3(3,:)= m3(3,:)./ gf(29,8) .
rref works without GF(2^8). But I am unable to perform the reduction using GF(2^8) . Can someone help me to find a solution and how to proceed?
I will be using the result from the above and append another row-vector to the it. Is there any function we can solve it, instead of going step-by-step

function returning vector in matlab

I have a function returning a vector in MatLab, the problem is that function should return a unsigned integer value, I've debugged my code and I realize that the variable galois_value turns into a vector when I do a bitand and a bitxor operation. I've tried to do a typecast to turn the vector into a unsigned value but doesn't works. I've tried to force a cast, but doesn't works too. Below the function:
function galois_value = galois_mul2( value )
hex = uint8(hex2dec('1B'));
temp = typecast(value, 'int8');
temp = bitshift(temp,-7);
temp = bitand(typecast(temp,'uint8'),hex);
galois_value = bitxor(bitshift(value,1),uint16(temp));
end
The correct output of this function should be (this output comes from a C code that is working) :
96
210
97
224
119
194
192
156
196
195
102
10
10
117
235
213
49
57
235
79
172
5
23
62
111
188
223
128
113
133
128
102
30
238
226
31
The output I get with the MatLab function:
96 96
210 210
353 378
224 224
375 364
194 194
192 192
156 156
196 196
451 472
102 102
10 10
10 10
373 366
491 496
469 462
305 298
313 290
491 496
335 340
172 172
261 286
279 268
62 62
367 372
188 188
479 452
128 128
369 362
389 414
128 128
102 102
30 30
238 238
226 226
287 260
The code to display and debug the function:
%Key
key = {'00','01','02','03','04','05','06','07','08','09','0a','0b','0c','0d','0e','0f'};
for n = 1 : 16
keyU(n)=uint16(hex2dec(key(n)));
end
%State
state = {'00','11','22','33','44','55','66','77','88','99','aa','bb','cc','dd','ee','ff'};
for n = 1 : 16
stateU(n)=uint16(hex2dec(state(n)));
end
%Sbox
sbox = {'63','7c','77','7b','f2','6b','6f','c5','30','01','67','2b','fe','d7','ab','76','ca','82','c9','7d','fa','59','47','f0','ad','d4','a2','af','9c','a4','72','c0','b7','fd','93','26','36','3f','f7','cc','34','a5','e5','f1','71','d8','31','15','04','c7','23','c3','18','96','05','9a','07','12','80','e2','eb','27','b2','75','09','83','2c','1a','1b','6e','5a','a0','52','3b','d6','b3','29','e3','2f','84','53','d1','00','ed','20','fc','b1','5b','6a','cb','be','39','4a','4c','58','cf','d0','ef','aa','fb','43','4d','33','85','45','f9','02','7f','50','3c','9f','a8','51','a3','40','8f','92','9d','38','f5','bc','b6','da','21','10','ff','f3','d2','cd','0c','13','ec','5f','97','44','17','c4','a7','7e','3d','64','5d','19','73','60','81','4f','dc','22','2a','90','88','46','ee','b8','14','de','5e','0b','db','e0','32','3a','0a','49','06','24','5c','c2','d3','ac','62','91','95','e4','79','e7','c8','37','6d','8d','d5','4e','a9','6c','56','f4','ea','65','7a','ae','08','ba','78','25','2e','1c','a6','b4','c6','e8','dd','74','1f','4b','bd','8b','8a','70','3e','b5','66','48','03','f6','0e','61','35','57','b9','86','c1','1d','9e','e1','f8','98','11','69','d9','8e','94','9b','1e','87','e9','ce','55','28','df','8c','a1','89','0d','bf','e6','42','68','41','99','2d','0f','b0','54','bb','16'};
for n = 1 : 256
sboxU(n)=uint16(hex2dec(sbox(n)));
end
%Rcon
rcon = {'01','02','04','08','10','20','40','80','1b','36'};
for n = 1 : 10
rconU(n)=uint16(hex2dec(rcon(n)));
end
%Main AES Data Loop
for round = 1 : 10
%Add key + sbox
for i = 1 : 16
stateU(i)= sboxU(bitxor(stateU(i),keyU(i))+1);
end
%Shift Rows
buf1 = stateU(2);
stateU(2) = stateU(6);
stateU(6) = stateU(10);
stateU(10) = stateU(14);
stateU(14) = buf1;
buf1 = stateU(3);
buf2 = stateU(7);
stateU(3) = stateU(11);
stateU(7) = stateU(15);
stateU(11) = buf1;
stateU(15) = buf2;
buf1 = stateU(16);
stateU(16) = stateU(12);
stateU(12) = stateU(8);
stateU(8) = stateU(4);
stateU(4) = buf1;
%Process mixcolumn for all rounds but the last one
if round < 10
for j = 0 : 3
%Compute the current index
buf4 = (bitshift(j,2));
%buf1
aux1 = bitxor(stateU(buf4+1),stateU(buf4+2));
aux2 = bitxor(stateU(buf4+3),stateU(buf4+4));
buf1 = bitxor(aux1,aux2);
%buf2
buf2 = stateU(buf4+1);
%buf3
buf3 = bitxor(stateU(buf4+1),stateU(buf4+2));
buf3 = galois_mul2(buf3);
disp(buf3);
end
end
end
The problem is in line 3 of galois_mul2 function
temp = typecast(value, 'int8');
since value has type uint16 output of typecast is two elements.
for e.g. output of typecast(uint16(5), 'int8') is 5 0
If you change all types in lines 3,8,13,18 of main and lines 3,6 of galois_mul2 function to uint8 the problem will be solved.

fitcdiscr function in MatLab

I'm attempting to use the fitcdiscr class to reproduce SAS results, but I'm evidently not using the function correctly. I've been through the MatLab documentation on the subject repeatedly, but can't seem to figure out what I'm specifying incorrectly. I'll first post the data, then the SAS code that is specifying the correct linear discriminant functions, then the MatLab code that I'm struggling with. Any help would be appreciated.
Data:
a 191 131 53
a 185 134 50
a 200 137 52
a 173 127 50
a 171 128 49
a 160 118 47
a 188 134 54
a 186 129 51
a 174 131 52
a 163 115 47
b 186 107 49
b 211 122 49
b 201 144 47
b 242 131 54
b 184 108 43
b 211 118 51
b 217 122 49
b 223 127 51
b 208 125 50
b 199 124 46
SAS:
options ls=78;
title "Discrimant Analysis - Insect Data";
data insect;
infile "C:\Users\Zach\Documents\Classes\Penn State\STAT 505\Data\insect.txt";
input species $ joint1 joint2 aedeagus;
run;
data test;
input joint1 joint2 aedeagus;
cards;
194 124 49
;
proc discrim data=insect pool=test crossvalidate testdata=test testout=a;
class species;
var joint1 joint2 aedeagus;
run;
proc print;
run;
MatLab:
path = 'C:\Users\Zach\Documents\Classes\Penn State\STAT 505\Data';
file = 'insect.txt';
fid = fopen(fullfile(path,file));
X = textscan(fid, '%s%f%f%f','Delimiter');
fclose(fid); clear fid
data = cell2mat(X(:,2:4));%data
grps = X{:,1};%group a or b
prednames = {'joint 1', 'joint 2', 'aedeagus'};
M = fitcdiscr(data,grps,'PredictorNames',prednames,...
'Prior','uniform','DiscrimType','linear');
The linear functions are specified using variants of
M.Coeffs(1,2).Linear and M.Coeffs(1,2).Const
The two functions I'm expecting are:
da = -247 -1.4x1 + 1.5x2 10.9x3
db = -193 - .74x1 + 1.1x2 + 8.3x3
Thanks for the help.
Edit:
Using "Applied Multivariate Statistical Analysis, 6th ed" by Johnson and Wichern, section 11.3, I've produced the following code that gives me the SAS results:
xbar = M.Mu;
S = M.Sigma;
Sinv = inv(S);
for ii = 1:2
d0(ii,:) = -1/2*xbar(ii,:)*Sinv*xbar(ii,:)';
d(ii,:) = xbar(ii,:)*Sinv;
end
I'm still left wondering just what fitcdiscr is doing.

Slow speed of UDP reception in Matlab

My FPGA is sending UDP packets on network using 100 mbps ethernet and a have written a MATLAB code to capture the data. The problem is i am getting very low speed in MATLAB around 50 kbps during reception. FPGA kit is connected to a gbps switch and then to PC. No internet cable in the switch.
I am pasting the matlab code below. If i try to increase the speed by increasing buffer size, the packets are dropped. current settings are through hit and trial on which i receive all data successfully. IS there any way to increase data reception speed in MATLAB?
Code:: (UDP from FPGA to Matlab)
clc
clear all
close all
u=udp('192.168.0.100','RemotePort',4660,'Localport',4661);
set(u,'DatagramTerminateMode','off');
set(u, 'InputBufferSize', 18);
set(u,'Timeout',0.1);
fopen(u);
x=tic;
for i =1:1000
a(:,i) = fread(u,18);
end
fclose(u);
delete(u);
t=toc(x);
bw = (1000*18*8)/t;
/////////////////////////////////////////////////////////
A MODIFIED VERSION OF THE ABOVE CODE (EASE OF UNDERSTANDING) + IMAGE Showing the PROBLEM
also: An image showing Data Variable with a buffer size of 20 Packets (18 bytes / Packet). Data must not be all zero as pointed in the image. It represents missed packets.
/////////////////////////////////////////////////////////
clc
clear all
close all
packet_size = 18; % Size of 1 Packet
buffer_size = 1*packet_size; % Buffer to store 1024 packets each of Packet_Size
buffer_read_count = 10; % How many times the buffer must be read
u=udp('192.168.0.100','RemotePort',4660,'Localport',4661);
set(u,'DatagramTerminateMode','off');
set(u, 'InputBufferSize', buffer_size);
set(u,'Timeout',0.5);
fopen(u);
x=tic;
for i =1:buffer_read_count
[a, count] = fread(u,buffer_size); % Read the complete buffer in one Fread()
if (count == buffer_size)
data(:, i) = a; %If Read_BYtes(Count) == BufferSize Store in Data
end
end
fclose(u);
delete(u);
t=toc(x);
bw = (buffer_read_count*buffer_size*8)/t; %Speed / BW of UDP Reception
I looked at your code and found some basic corrections, let me know if it speed up your code.
u=udp('192.168.0.100','RemotePort',4660,'Localport',4661);
set(u,'DatagramTerminateMode','off', ...
'InputBufferSize', 18, ...
'Timeout',0.1); % I think only one call of set is needed here
fopen(u);
x=tic;
% The variable a is not pre-allocated before the loop
a = zeros(YourNumberOfLine, 1000)
for ii =1:1000 % Always use ii and jj and not i and j
a(:,ii) = fread(u,18);
end
fclose(u);
delete(u);
t=toc(x);
bw = (1000*18*8)/t;
Let me summarize my comments.
Low code efficiency
As #m_power has pointed out, using i and j slows down your code by a bit. See this for more information. In Matlab, you should always use ii and jj instead.
You didn't initialize data. See how Mathworks explain this. If #1 "slows by a bit", #2 then slows a lot.
Since your code is slow, it's not guaranteed that each time FPGA sends a packet, your PC is able to find any available buffer to receive the packet.
Full buffer
if (count == buffer_size)
data(:, i) = a; %If Read_BYtes(Count) == BufferSize Store in Data
end
So if the packet is smaller than the buffer, data(:,i) = nothing? That is the most possible reason why you are getting zeros in column 3,4,and 5.
Empty buffer
Zeros in column 3, 4 and 5 may also originate from an empty buffer, if you have done the previous changes. The buffer is not guaranteed to carry something when Matlab reads it, so some for iterations may catch zero-length contents, data(:,ii) = 0.
Use a while loop to solve this issue. Only count for non-empty buffer readings.
ii = 0;
while (ii < buffer_read_count)
[a, count] = fread(u, buffer_size);
if count % non-empty reading
ii = ii+1;
data(1:count,ii) = a;
end
end
....incomplete packets?
You wait for a full buffer, because each time you want to read an entire packet? I suddenly realized it; how stupid I was!
But what you have done is keeping reading the buffer, and throwing away the data as long as it's shorter than the buffer length.
Instead, you'll need aggregate the data in each loop.
data = zeros(buffer_size, buffer_read_count);
total_size = buffer_read_count*buffer_size;
ptr = 1; % 1-D array index of data
while (ptr < total_size)
[a, count] = fread(u, buffer_size);
if count % non-empty reading
if ( (ptr+count) > total_size )
data(ptr:end) = a(1:(total_size-ptr+1));
ptr = total_size;
else
data( ptr:(ptr+count-1) ) = a;
ptr = ptr+count;
end
end
end
Test - I changed fread to a random integer generator with ii remembering how many times the buffer is read.
clear all;clc;
buffer_size = 18;
buffer_read_count = 10;
data = zeros(buffer_size, buffer_read_count);
total_size = buffer_read_count*buffer_size;
ptr = 1; % 1-D array index of data
ii = 1;
while (ptr < total_size)
count = randi(buffer_size);
a = randi(9, count, 1) + ii*10; % 10's show number of buffer readings
ii = ii+1;
% [a, count] = fread(u, buffer_size);
if count % non-empty reading
if ( (ptr+count) > total_size )
data(ptr:end) = a(1:(total_size-ptr+1));
ptr = total_size;
else
data( ptr:(ptr+count-1) ) = a;
ptr = ptr+count;
end
end
end
disp(data)
The result is
13 38 51 63 72 93 104 125 141 164
12 35 53 63 73 96 101 123 148 168
14 33 55 68 72 99 106 124 142 168
14 37 51 69 77 91 109 127 145 165
12 33 57 66 76 96 114 137 143 168
14 39 56 63 72 94 117 139 144 169
11 46 55 61 72 93 111 139 146 164
16 42 58 68 75 93 119 135 153 164
26 41 58 66 79 109 126 139 152 166
33 43 58 69 75 102 122 132 152 177
35 48 53 61 81 108 125 131 153 174
36 49 55 66 95 102 125 133 165 177
31 47 57 63 94 109 129 136 164 179
35 47 51 72 98 108 128 135 162 175
36 43 51 74 94 104 129 139 169 175
32 46 53 74 95 107 127 144 164 173
38 48 55 78 97 105 124 145 168 171
39 44 59 77 98 108 129 147 166 172
As you can see, each time the length of fread output is either equal to or less than the buffer size. But it only jumps to the next column when the current one has been completely received.

Matlab getting point coordinates

How can I get the coordinates at a specific point?
I want to get the X coordinate of the points with Y = 18.1 ; Y = 33; Y = 70
Those points need to lie on the function that I plot.
Sample Code
t = [0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100 105 110 115 120 125 130 135 140 145 150 155 160 165 170 175 180];
y = [0 5 9 19 25 32 46 65 79 90 100 115 123 141 153 159 160 171 181 185 193 200 205 211 215 220 223 222 225 224 228 231 231 228 235 234 231];
plot(t,y) , grid on
Unfortunately, you are trying to find the values of t associated with a y, and your function is not monotonic so we need to actually code up a mock linear interpolation. Note, there may be a better way, but I do not know of it right now. Try the following code where yVals are the values you want an associated t for, and possArray will include all values of t that may satisfy those conditions.
clc; close all; clear all;
t = [0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100 105 110 115 120 125 130 135 140 145 150 155 160 165 170 175 180];
y = [0 5 9 19 25 32 46 65 79 90 100 115 123 141 153 159 160 171 181 185 193 200 205 211 215 220 223 222 225 224 228 231 231 228 235 234 231];
plot(t,y)
grid on
hold on
yVals = [18.1,33,70,222.5,230];
possArray = cell(1,numel(yVals));
iter = 1;
for val = yVals;
poss = [];
possNum = 1;
for i = 1:numel(y)-1
if y(i) <= val && y(i+1) >= val
minDiff = val-y(i);
yDiff = y(i+1)-y(i);
percAlong = minDiff/yDiff;
poss(possNum) = (t(i+1)-t(i))*percAlong+t(i);
possNum = possNum+1;
end
end
possArray{iter} = poss;
iter = iter + 1;
end
colors = hsv(numel(yVals));
legendCell = cell(numel(yVals)+1,1);
legendCell{1} = 'Original Line';
for i = 1:numel(yVals)
plot(possArray{i},yVals(i)*ones(size(possArray{i})),...
'x','MarkerSize',10,'LineWidth',2,'Color',colors(i,:))
legendCell{i+1} = ['Values for Y = ' ,num2str(yVals(i))];
end
legend(legendCell)
hold off
As stated previously, this is linear interpolation, so if you need it to be more complicated that is on you, the concept should however be similar
UPDATE
Updated code above to be a little more clean, and added a plot indicating that multiple possibilities may arise for a single value, and that the code will return all possibilities.