Bicubic interpolation beyond grid values in Matlab - matlab

Is it possible to achieve bi-cubic interpolation beyond grid values?
For example:
L = [5,10,20,25,40];
W= 1:3;
S= [50 99 787
779 795 850
803 779 388
886 753 486
849 780 598];
size1 = griddata(W,L,S,2,40,'cubic')
sizeBeyond = griddata(W,L,S,2,41,'cubic')
sizeV4 = griddata(W,L,S,2,41,'v4')
returns:
size1 = 780
sizeBeyond = NaN
sizeV4 = 721.57

What I was suggesting is, you can input the values which are extrapolated. Check the below code. But note that, as suggested by flawr, the extrapolation behave really bad.
l = [5,10,20,25,40];
w = 1:3;
li = [l 41] ;
S = [50 99 787
779 795 850
803 779 388
886 753 486
849 780 598];
[W,L] = meshgrid(w,l) ;
[Wi,Li] = meshgrid(w,li) ;
Si = interp2(W,L,S,Wi,Li,'spline') ;
size1 = griddata(W,L,S,2,40,'cubic')
sizeBeyond = griddata(Wi,Li,Si,2,41,'cubic')
sizeV4 = griddata(W,L,S,2,41,'v4')
Note: Don't use inbuilt commands like length,size etc as variables in the code, even for demonstration, it is trouble some.
Though, this is not answer, I have to post it here as for discussion.

Related

How can I plot heatmap of Wi-Fi signal strength in a 2-D surface?

I've my dataset as follows (for instance):
strength = [-90 -90 -90 -90 -40 -20 -22.4 -45 -35 -41 -44 -55 -40 -75 -26]
X = [10 550 550 10 50 234 393 129 237 328 448 225 344 457 477]
Y = [10 10 410 410 293 210 202 132 130 142 141 272 268 274 200]
Here, strength is the received signal strength in dBm, X and Y are 2-D coordinates. I want to plot the heatmap of the signal strength at all the coordinate points.
My situation is similar to this question. However, I want to plot the received signal strength and in Matlab, as shown in the attached figure (because of picture quality). A solution in Matlab is found here, however, the code given in the link does not work. The Command Window of Matlab displays HeatMap object with 0 rows and 0 columns. The available code in Matlab is as follows:
strength = [-90 -90 -90 -90 -40 -20 -22.4 -45 -35 -41 -44 -55 -40 -75 -26]';
X = [10 550 550 10 50 234 393 129 237 328 448 225 344 457 477]';
Y = [10 10 410 410 293 210 202 132 130 142 141 272 268 274 200]';
strengthPercent = 2*(strength+100)/100;
picture = imread('https://www.mathworks.com/help/examples/thingspeak/win64/CreateHeatmapOverlayImageTSExample_02.png');
[height,width,depth] = size(picture);
OverlayImage=[];
F = scatteredInterpolant(Y, X, strengthPercent,'linear');
for i = 1:height-1
for j = 1:width-1
OverlayImage(i,j) = F(i,j);
end
end
alpha = (~isnan(OverlayImage))*0.6;
imshow(picture);
hold on
OverlayImage = imshow( OverlayImage );
caxis auto
colormap( OverlayImage.Parent, jet );
colorbar( OverlayImage.Parent );
set( OverlayImage, 'AlphaData', alpha );
Any suggestions, please!
Thank you.
You can use scatteredInterpolant as in the code you showed, just pair it with surf
F = scatteredInterpolant(X(:), Y(:), strength(:));
[XD, Yd] = meshgrid( 0:10:410, 0:10:550 );
Zd = F( XD, Yd );
surf( XD, Yd, Zd, 'EdgeColor', 'interp' );
view([0,90]); % view 3D plot from above
You can change the colormap to customise the appearance.
colormap( 'hot' );
colorbar();
You should be able to reduce the FaceAlpha of the surface to lay it over an image.

Kalman Filter implementation for one dimensional vector

I am having an hard time figuring out something really stupid I think.
I want to refresh my kalman filter knowledge but I am not able to make it work.
In a simple case with
real states x:
x = [ 1000 750 563 422 316 237 178 133 100 75]';
and observations
z_array = [ 1056 943 469 235 433 230 116 136 -75 267]';
I get something really nice (estimated stands for FILTERED):
When instead I use another signal, more complex. I don't know why but it doesn't work (estimated stands for FILTERED).
The problem, I am quite sure is in how I choose the a and r in my code for the second case. But how can I change them?
Here is the short code I have written in MATLAB and I am getting lost (I am really ashamed because I should know how to do this!!).
close all
z_array = noisyMeas.signals.values;
x = meas.signals.values;
a = 0.75;
r= 200;
p=1;
% x = [ 1000 750 563 422 316 237 178 133 100 75]';
% z_array = [ 1056 943 469 235 433 230 116 136 -75 267]';
xhat_array = zeros(length(z_array),1);
xhat = z_array(1);
xhat_array(1) = xhat;
% Core of the Kalman Filter
for k=2:length(x)
z = z_array(k);
% Predict
xhat = a * xhat;
p = a * p * a;
% Update
g = p / (p + r);
xhat = xhat + g * (z - xhat);
p = (1 - g) * p;
xhat_array(k) = xhat;
end
% plotting
figure
hold on
plot(xhat_array,'r')
plot(x,'b');
plot(z_array,'g')
grid on
legend('estimated','notNoisy','Noisy')
Thanks in advance for your help.

Import coordinates from file .txt with Matlab

I need to plot some trajectories with matlab, i have the coordinates of each points in a file .txt, i work with c++ i want to plot this trajectories with Matlab to make some comparisons, this is an example of the file who contains the coordinates :
515 // this is x
317 // this is y
0 // i dont want to import this variable
511 // this is x
328 // this is y
20 // i dont want to import this variable
508
353
40
511
... etc
there is a function in Matlab that can help me to import only x and y?
file :
172
489
54460
283
469
54480
388
428
54500
476
384
54520
555
350
54540
635
325
54560
700
286
54580
760
250
54600
811
222
54620
840
192
54640
856
171
54660
871
175
54680
890
181
54700
930
170
54720
979
168
54740
You can read in all values using textscan and simply ignore every third value in the output by using the * in the format specifier.
fid = fopen('filename.txt', 'r');
data = textscan(fid, '%d\n%d\n%*d\n');
[x,y] = data{:};
fclose(fid);
Another option is to read in all data, then reshape and grab the parts you care about.
fid = fopen('filename.txt', 'r');
data = textscan(fid, '%d');
data = reshape(data{1}, 3, []);
x = data(1,:);
y = data(2,:);
fclose(fid);

How to classify a matrix within a Matlab parfor loop?

I am looking to classify the values of a matrix. The following example works outside of a parfor loop, however it does not work when used within a parfor loop. What are my options to classify matrices, following the provided example, within a parfor loop?
% Sample data
Imag1 = [ 62 41 169 118 210;
133 158 96 149 110;
211 200 84 194 29;
209 16 15 146 28;
95 144 13 249 170];
% Perform the classification
Imag1(find(Imag1 <= 130)) = 4;
Imag1(find(Imag1 >= 150)) = 1;
Imag1(find(Imag1 > 140)) = 2;
Imag1(find(Imag1 > 130)) = 3;
Results in the following (outside parfor loop):
Imag1 =
62 41 169 118 210
133 158 96 149 110
211 200 84 194 29
209 16 15 146 28
95 144 13 249 170
Imag1 =
4 4 1 4 1
3 1 4 2 4
1 1 4 1 4
1 4 4 2 4
4 2 4 1 1
You can use another matrix to store the result.
Imag2 = zeros(size(Imag1));
% Perform the classification
Imag2(find(Imag1 <= 130)) = 4;
Imag2(find(Imag1 >= 150)) = 1;
Imag2(find(Imag1 > 140)) = 2;
Imag2(find(Imag1 > 130)) = 3;
so you can use a parfor loop somehow. Since parfor doesn't care about order of execution. Your code doesn't work in a parfor loop because right now you are modifying the values of Imag1, then comparing those values again, aka any loop iteration would be be dependent on the prior loop iterations
Here's another approach:
parfor c = 1:size(Imag1,2)
Imag2(:,c) = 4-min(ceil(max((Imag1(:,c) - 130),0)/10),3);
end
Now you can split it up however you like; by rows, by columns, by blocks, by alternate columns...
Edit:
Unfortunately this classifies a value of 150 as 2. So you probably shouldn't use this one.
Take 3
class = [150 141 131 0]; %// minimum values for class 1, 2, 3, 4
[m, n] = size(Imag1);
parfor c=1:n
for r=1:m
Imag3(r,c) = find(Imag1(r,c) >= class, 1);
end
end

Matlab : How I can creat a polynomial generator Reed Solomon for QR Code

I have to make a matlab program, which should create a QR Code.
My problem is the Reed Solomon error correction
The user enters the word he wants. [...] I got a string of numbers I should be gone in a polynomial generator (Reed Solomon) (I found some sites that do this very well: http://www.pclviewer.com/rs2/calculator.html)
I would like it to happen: for example I input: 32 91 11 120 209 114 220 77 67 64 236 17 236
[Reed Solomon generator polynomial]
and I want to find out: 168 72 22 82 217 54 156 0 46 15 180 122 16
I found the functions rsenc comm.rsencoder gf ... But it is impossible to understand the operation of these functions. Functions are detailed: http://www.mathworks.fr/fr/help/comm...n.html#fp12225
I tried a code of this type :
n = 255; k = 13; % Codeword length and message length
m = 8; % Number of bits in each symbol
msg = [32 91 11 120 209 114 220 77 67 64 236 17 236]; % Message is a Galois array.
obj = comm.RSEncoder(n, k);
c1 = step(obj, msg(1,:)');
c = [c1].';
He produced a string of 255 while I want 13 output.
Thank you for your help.
I think that you are committing a mistake.
'n' is the length of final message with parity code.
'k' is the lenght of message (number of symbols)
I guess that this will help you:
clc, clear all;
M = 16; % Modulation Order || same that Max value, at your case: 256! 2^m
hEnc = comm.RSEncoder;
hEnc.CodewordLength = M - 1; % Max = M-1, Min = 4, Must be greater than MessageLenght
hEnc.MessageLength = 13; % Experiment change up and down value (using odd number)
hEnc.BitInput = false;
hEnc
t = hEnc.CodewordLength - hEnc.MessageLength;
frame = 2*hEnc.MessageLength; % multiple of MensagemLength
fprintf('\tError Detection (in Symbols): %d\n',t);
fprintf('\tError Correction: %.2f\n',t/2);
data = randi([0 M-1], frame, 1); % Create a frame with symbols range (0 to M-1)
encodedData = step(hEnc, data); % encod the frame