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.