MATLAB Error: "Vectors must be the same length" - matlab

I'm getting an error that says "Vectors must be the same length" but I'm not sure why. I'm basically trying to graph a piecewise function with respect to time. I was running into some other issues with the "piecewise" operator earlier, so I decided to use an if statement instead.
figure(1);
t = linspace(0, 30, 200);
v_wind1 = linspace(0, 20, 100);
v_wind2 = linspace(20, 0, 100);
if (0 <= t < 15)
v_wind = v_wind1;
elseif (15 <= t <30)
v_wind = v_wind2;
end
plot(t, v_wind);

Just concatenate v_wind1 and v_wind2.
figure(1);
t = linspace(0, 30, 200);
v_wind1 = linspace(0, 20, 100);
v_wind2 = linspace(20, 0, 100);
v_wind = [v_wind1 v_wind2];
plot(t, v_wind);
This should do the trick!? You want that result, don't you?

Simply use: indexing
t = linspace(0, 30, 200);
v_wind1 = linspace(0, 20, 200);
v_wind2 = linspace(20, 0, 200);
v_wind = zeros(size(t)) ;
idx = t >= 0 & t<15 ;
v_wind(idx) = v_wind1(idx) ;
idx = t >=15 & t < 30 ;
v_wind(idx) = v_wind2(idx) ;
plot(t,v_wind)

Related

Problem with normalizing a function with likelihood

I have a problem with the following code. In the evidence part, the value is very small so, in the end, the probabilities are not calculated. I need to normalize it, but in which part should it be?
The code in MATLAB is:
clear all; close all; clc;
randn('seed', 1234);
resistivities = [50 200 2000 1500];
thicknesses = [500 100 200];
Par_real = [resistivities, thicknesses];
dataFreq = logspace(log10(0.001), log10(1000), 100);
[Ydata, phase] = modelMT2(Par_real, dataFreq);
sigma = 0.1;
Yexp = Ydata + sigma*randn(size(Ydata));
plot(dataFreq, Yexp, '.'); hold on; plot(dataFreq, Ydata, '-')
nsamples = 20000;
R1 = 5;
R2 = 2050;
P1 = 25;
P2 = 500;
Resis = R1 + (R2-R1)*rand(nsamples, 7);
Profs = P1 + (P2-P1)*rand(nsamples, 6);
for ii=1:nsamples
par3C = [Resis(ii, 1:3), Profs(ii, 1:2)];
par4C = [Resis(ii, 1:4), Profs(ii, 1:3)];
par5C = [Resis(ii, 1:5), Profs(ii, 1:4)];
par7C = [Resis(ii, 1:7), Profs(ii, 1:6)];
Like_M3C(ii) = log_likelihood(#modelMT2, dataFreq, Yexp, sigma, par3C);
Like_M4C(ii) = log_likelihood(#modelMT2, dataFreq, Yexp, sigma, par4C);
Like_M5C(ii) = log_likelihood(#modelMT2, dataFreq, Yexp, sigma, par5C);
Like_M7C(ii) = log_likelihood(#modelMT2, dataFreq, Yexp, sigma, par7C);
end
figure()
subplot(1, 2, 1)
plot(exp(Like_M5C))
subplot(1, 2, 2)
hist(exp(Like_M5C))
Evidencia(1) = mean(exp(Like_M3C));
Evidencia(2) = mean(exp(Like_M4C));
Evidencia(3) = mean(exp(Like_M5C));
Evidencia(4) = mean(exp(Like_M7C));
Denominador = sum(Evidencia);
PPMM = Evidencia/Denominador;
fprintf('La probabilidad de los modelos : \n');
fprintf('--------------------------------\n');
fprintf('Modelo M3C: %.4f \n', PPMM(1));
fprintf('Modelo M4C: %.4f \n', PPMM(2));
fprintf('Modelo M5C: %.4f \n', PPMM(3));
fprintf('Modelo M7C: %.4f \n', PPMM(4));
figure()
model = [1, 2, 3, 4];
bar(model, PPMM), grid on
ylim([0, 1])
xlabel('Modelo')
ylabel('Probabilidad del modelo')
function [LogPDF_post] = log_likelihood(Mod, xx, data, sigma, oldpar)
erro = (Mod(oldpar, xx) - data)';
LogPDF_post = -0.5 * erro' * 1/sigma^2 * erro;
end
I have tried to normalize the likelihood as follows, but it doesn't work. It gives equal probability in all cases.
function [LogPDF_norma] = log_likelihood(Mod, xx, data, sigma, oldpar)
erro = (Mod(oldpar, xx) - data)';
LogPDF_post = -0.5 * erro' * 1/sigma^2 * erro;
LogPDF_norma = (1/max(LogPDF_post))*LogPDF_post;
end

Making colorbar tick labels a string above and below bar, remove ticks - Matlab

I am trying to reproduce the colorbar below for my chart. Specifically it is the string colorbar axis title (above and below the colorbar) that I am struggling with, the rest seems fine.
Below is my current code:
time_begin = [1981, 1, 1, 0,0,0];
time_end = [2010,12,31,23,0,0];
years = (time_begin(1):time_end(1))';
nyears = length(years);
TXx1 = randi(100, 288, 192, 30);
lat = rand(192, 1);
lon = rand(288, 1);
time = rand(30,1);
M = numel(lon);
N = numel(lat);
slope1 = zeros(M, N);
intercept1 = zeros(M, N);
T = numel(time);
x = ([ones(T, 1) years]);
for i = 1 : M
for j = 1 : N
y1 = squeeze(TXx1(i, j, :));
c = regress(y1, x);
intercept1(i, j) = c(1);
slope1(i, j) = c(2);
end
end
TXx2 = randi(100, 288, 192, 30);
slope2 = zeros(M, N);
intercept2 = zeros(M, N);
T = numel(time);
x = ([ones(T, 1) years]);
for i = 1 : M
for j = 1 : N
y2 = squeeze(TXx2(i, j, :));
c = regress(y2, x);
intercept2(i, j) = c(1);
slope2(i, j) = c(2);
end
end
figure()
set(gcf, 'color', 'w');
temp = [slope1(:) slope2(:)];
temp(temp == 0) = NaN;
[Q,Qc] = hist3(temp,'Nbins',[100 100],'CDataMode','auto');
Qx = cell2mat(Qc(1));
Qy = cell2mat(Qc(2));
Q = Q';
Q = Q./trapz(Qy,trapz(Qx,Q,2));
surf(Qx,Qy,Q,'FaceColor','interp','EdgeColor','none')
grid off
set(gca, 'Fontsize', 12, 'Fontweight', 'Bold'); %added
cmap = jet(500);
cmap(1,:) = [1,1,1];
colormap(cmap);
h=colorbar;
set(h,'position',[.91 .34 .031 .475]) %[xposition yposition width height].
set(get(h,'ylabel'),'string','Point density');
set(h,'XTickLabel',{'Low',' ',' ',' ',' ','High',});
view(0,90)
Here is my current colourbar:
Replace this line:
set(h,'XTickLabel',{'Low',' ',' ',' ',' ','High',});
with:
h.YTick = h.Limits;
h.YTickLabel = {'Low', 'High'};
This makes two tick-lines and two tick labels. By setting YTicks of the colorbar to its limits, the tick-lines get overlapped by colorbar boundary. So these get hidden and now there is no need to remove them.
However there is this TickLength property which can be used otherwise i.e.
h.TickLength = 0;
Result:

Occasionally, figure size is not set properly in Matlab

I tried to set same figure size for several images using for loop in matlab and save in png
But some (usually one) of them has different size.
In below code, I tried to save image in (48,64).
Why some figure sizes are not set properly as I commanded?
nMarker = 5;
mark = ['o', 's', 'd', '^', 'p'];
nSize = 3;
mSize = [9, 18, 27];
nRow = 48;
nCol = 64;
BG = zeros(nRow, nCol);
idxStage = 2;
numAction = 1;
numPositionX = 4;
numPositionY = 4;
xtrain = [1,2,3,4];
ytrain = [1,2,3,4];
xpos = [20, 30, 40, 50];
ypos = [8, 18, 28, 38];
nStepS = 10;
nStepB = 10;
nStep = nStepS + nStepB;
for a = 1
for x = 1:numPositionX
for y = 1:numPositionY
for obj = 1:nMarker
for s = 1:nSize
obj_command = x*1000 + y*100 + obj*10 + s;
fig1 = figure(1);
imagesc(BG)
hold on
scatter(xpos(x), ypos(y), mSize(s), mark(obj), 'k', 'filled')
axis off
set(fig1, 'Position', [500, 500, 64, 48]);
set(gca,'position',[0 0 1 1],'units','normalized')
F = getframe(gcf);
pause(0.05)
[X, Map] = frame2im(F);%
tmp_frame = rgb2gray(X);
tmp_im_fn = sprintf('tmp/image_seq%04d.png',obj_command);
imwrite(tmp_frame, tmp_im_fn)
clf
end
end
end
end
end
I found some trick to solve the problem for now.
I put,
fig1 = figure(1);
drawnow
in front of the for loop and it seems all sizes are equal now.
But still waiting for better solution...

matlab - unfixed dimension matrix, set value to multiple fields of struct at once, avoid loop

I have 2 (not very small) 3-dimension structs with matrices as fields:
sz1 = 200;
sz2 = 9;
sz3 = [20, 40, 80, 160, 320, 640, 1280, 2560, 5120]
% actually the structs have 12 fields, each has size 200x9x5120
mat.p1(sz1, sz2, sz3(sz2)) = uint8(0);
mat.p2(sz1, sz2, sz3(sz2)) = uint8(0);
mat.p3(sz1, sz2, sz3(sz2)) = 0;
mat.p4(sz1, sz2, sz3(sz2)) = 0;
old_mat.p1(sz1, sz2, sz3(sz2)) = uint8(0);
old_mat.p2(sz1, sz2, sz3(sz2)) = uint8(0);
old_mat.p3(sz1, sz2, sz3(sz2)) = 0;
old_mat.p4(sz1, sz2, sz3(sz2)) = 0;
And i need to write a reset function, where i will re-assign the values to 3 of 4 (actually 10 of 12) fields in both matrices as follows:
for i = 1:sz1
for j = 1:sz2
for k = 1:sz3(j)
mat.p1(i,j,k) = uint8(255);
mat.p3(i,j,k) = -1;
mat.p4(i,j,k) = 0.01;
old_mat.p1(i,j,k) = uint8(255);
old_mat.p3(i,j,k) = -1;
old_mat.p4(i,j,k) = 0.01;
end
end
end
Note that actually what i need in the matrices is the same as the reset function, means i only need the 5120th index of the 3rd-dimension when 2nd-dimension is 9, if 2nd-dimension = 4, i only need up to 160 indices at 3rd-dimension etc.
The questions are:
Is there anyway to assign values to the fields at the same time (not 1 line 1 field) since i actually have to do with 10 fields?
Is there anyway to avoid the for-loops? I tried like this:
mat.p1(:) = uint8(255);
mat.p3(:) = -1;
mat.p4(:) = 0.01;
old_mat.p1(:) = uint8(255);
old_mat.p3(:) = -1;
old_mat.p4(:) = 0.01;
but here all the matrices are filled with max 3rd-dimension = 5120 so i expect someone can show me how to use the vectorizing function like arrayfun, bsxfun, cellfun etc., which can apply for just the "half-cubic" like the for-loops above.
UPDATE:
Thanks horchler for the video, it seems the problem with big size (in bytes) of the matrices is solved when i change the matrix of struct to a struct with matrices as fields. This also clears the timing problem even with nested for-loops. So i updated the questions and the input as well, please see above.
Yes, I think that using a structure of arrays will work better for you here. You should be able to allocate using zeros just as if mat.p1, mat.p2, etc. were regular arrays. I'd do something like this (note that you didn't indicate any values for mat.p2) using a single for loop:
sz1 = 200;
sz2 = 9;
sz3 = [20, 40, 80, 160, 320, 640, 1280, 2560, 5120];
% Be careful with this form of pre-allocation if your sz arrays change
% Clear your struct or make sure to use the code in a function
mat.p1(sz1,sz2,sz3(sz2)) = uint8(0);
mat.p3(sz1,sz2,sz3(sz2)) = 0;
mat.p4(sz1,sz2,sz3(sz2)) = 0;
for i = 1:sz2
mat.p1(:,i,1:sz3(i)) = uint8(255);
mat.p3(:,i,1:sz3(i)) = -1;
mat.p4(:,i,1:sz3(i)) = 0.01;
end
old_mat.p1 = mat.p1;
old_mat.p3 = mat.p3;
old_mat.p4 = mat.p4;
Alternatively, you could do something like this:
sz1 = 200;
sz2 = 9;
sz3 = [20, 40, 80, 160, 320, 640, 1280, 2560, 5120];
mat = struct('p1',zeros(sz1,sz2,sz3(sz2),'uint8'),...
'p3',zeros(sz1,sz2,sz3(sz2)),...
'p4',zeros(sz1,sz2,sz3(sz2)));
for i = 1:sz2
mat.p1(:,i,1:sz3(i)) = uint8(255);
mat.p3(:,i,1:sz3(i)) = -1;
mat.p4(:,i,1:sz3(i)) = 0.01;
end
old_mat = struct('p1',mat.p1,'p3',mat.p3,'p4',mat.p4);

how can I fix this error code in cbir using wavelet transform and color histogram?

I have a project of CBIR using wavelet transform and color histogram. I perform re-experiment from Singha and Hemachandran research. I have tried to code it, but when image was added in database, it has been error. The error message states :
Error using database/fastinsert (line 222)
Cell array or struct should not contain vectors
Error in koneksidbEkstraksi (line 11)
fastinsert(conn, 'ekstraksifitur', colciri, rowciri);
Error in metode_ekstraksi (line 157)
koneksidbEkstraksi(A, H, V);
Error in tambah>btn_tmbhcitra_Callback (line 361)
metode_ekstraksi(input);
Error in gui_mainfcn (line 96)
feval(varargin{:});
Error in tambah (line 42)
gui_mainfcn(gui_State, varargin{:});
Error in
#(hObject,eventdata)tambah('btn_tmbhcitra_Callback',hObject,eventdata,guidata(hObject))
Error while evaluating uicontrol Callback
I think it was caused by algorithm of extraction code. Here is the code.
function metode_ekstraksi(citra)
%extract component of RGB
r = citra(:,:,1);
g = citra(:,:,2);
b = citra(:,:,3);
%decompose each Red, Green, Blue component
[R,SR] = wavedec2(r,1,'db2');
LL1R = appcoef2(R,SR,1,'db2');
[HL1R,LH1R,HH1R] = detcoef2('all',R,SR,1);
[G,SG] = wavedec2(g,1,'db2');
LL1G = appcoef2(G,SG,1,'db2');
[HL1G,LH1G,HH1G] = detcoef2('all',G,SG,1);
[B,SB] = wavedec2(b,1,'db2');
LL1B = appcoef2(B,SB,1,'db2');
[HL1B,LH1B,HH1B] = detcoef2('all',B,SB,1);
%combine approximate, horizontal, vertical coefficient of RGB component
A1(:,:,1) = LL1R;
A1(:,:,2) = LL1G;
A1(:,:,3) = LL1B;
H1(:,:,1) = HL1R;
H1(:,:,2) = HL1G;
H1(:,:,3) = HL1B;
V1(:,:,1) = LH1R;
V1(:,:,2) = LH1G;
V1(:,:,3) = LH1B;
%assign the weights
BA = 0.003*A1;
BH = 0.001*H1;
BV = 0.001*V1;
[rowsA, colsA, numOfBands] = size(BA);
[rowsH, colsH, numOfBands] = size(BH);
[rowsV, colsV, numOfBands] = size(BV);
%convert coefficient into hsv plane
hsvA = rgb2hsv(BA);
ha = hsvA(:, :, 1);
sa = hsvA(:, :, 2);
va = hsvA(:, :, 3);
hsvH = rgb2hsv(BH);
hh = hsvH(:, :, 1);
sh = hsvH(:, :, 2);
vh = hsvH(:, :, 3);
hsvV = rgb2hsv(BV);
hv = hsvV(:, :, 1);
sv = hsvV(:, :, 2);
vv = hsvV(:, :, 3);
% Specify the number of quantization levels.
numberOfLevelsForH = 8;
numberOfLevelsForS = 8;
numberOfLevelsForV = 8;
% Find the max.
maxValueForHa = max(ha(:));
maxValueForSa = max(sa(:));
maxValueForVa = max(va(:));
maxValueForHh = max(hh(:));
maxValueForSh = max(sh(:));
maxValueForVh = max(vh(:));
maxValueForHv = max(hv(:));
maxValueForSv = max(sv(:));
maxValueForVv = max(vv(:));
% create final histogram matrix of size 8x2x2
A = zeros(8, 8, 8);
H = zeros(8, 8, 8);
V = zeros(8, 8, 8);
% create col vector of indexes for later reference
indexA = zeros(rowsA*colsA, 3);
indexH = zeros(rowsH*colsH, 3);
indexV = zeros(rowsV*colsV, 3);
% Put all pixels into one of the "numberOfLevels" levels.
count = 1;
for rowA = 1:size(ha, 1)
for colA = 1 : size(ha, 2)
quantizedValueForHa(rowA, colA) = ceil(numberOfLevelsForH * ha(rowA, colA)/maxValueForHa);
quantizedValueForSa(rowA, colA) = ceil(numberOfLevelsForS * sa(rowA, colA)/maxValueForSa);
quantizedValueForVa(rowA, colA) = ceil(numberOfLevelsForV * va(rowA, colA)/maxValueForVa);
% keep indexes where 1 should be put in matrix hsvHist
indexA(count, 1) = quantizedValueForHa(rowA, colA);
indexA(count, 2) = quantizedValueForSa(rowA, colA);
indexA(count, 3) = quantizedValueForVa(rowA, colA);
countA = count+1;
end
end
for rowH = 1:size(hh, 1)
for colH = 1 : size(hh, 2)
quantizedValueForHh(rowH, colH) = ceil(numberOfLevelsForH * hh(rowH, colH)/maxValueForHh);
quantizedValueForSh(rowH, colH) = ceil(numberOfLevelsForS * sh(rowH, colH)/maxValueForSh);
quantizedValueForVh(rowH, colH) = ceil(numberOfLevelsForV * vh(rowH, colH)/maxValueForVh);
% keep indexes where 1 should be put in matrix hsvHist
indexH(count, 1) = quantizedValueForHh(rowH, colH);
indexH(count, 2) = quantizedValueForSh(rowH, colH);
indexH(count, 3) = quantizedValueForVh(rowH, colH);
countH = count+1;
end
end
for rowV = 1:size(hv, 1)
for colV = 1 : size(hv, 2)
quantizedValueForHv(rowV, colV) = ceil(numberOfLevelsForH * hv(rowV, colV)/maxValueForHv);
quantizedValueForSv(rowV, colV) = ceil(numberOfLevelsForS * sv(rowV, colV)/maxValueForSv);
quantizedValueForVv(rowV, colV) = ceil(numberOfLevelsForV * vv(rowV, colV)/maxValueForVv);
% keep indexes where 1 should be put in matrix hsvHist
indexV(count, 1) = quantizedValueForHv(rowV, colV);
indexV(count, 2) = quantizedValueForSv(rowV, colV);
indexV(count, 3) = quantizedValueForVv(rowV, colV);
countV = count+1;
end
end
% put each value of h,s,v to matrix 8x2x2
% (e.g. if h=7,s=2,v=1 then put 1 to matrix 8x2x2 in position 7,2,1)
for rowA = 1:size(indexA, 1)
if (indexA(rowA, 1) == 0 || indexA(rowA, 2) == 0 || indexA(rowA, 3) == 0)
continue;
end
A(indexA(rowA, 1), indexA(rowA, 2), indexA(rowA, 3)) = ...
A(indexA(rowA, 1), indexA(rowA, 2), indexA(rowA, 3)) + 1;
end
for rowH = 1:size(indexH, 1)
if (indexH(rowH, 1) == 0 || indexH(rowH, 2) == 0 || indexH(rowH, 3) == 0)
continue;
end
H(indexH(rowH, 1), indexH(rowH, 2), indexH(rowH, 3)) = ...
H(indexH(rowH, 1), indexH(rowH, 2), indexH(rowH, 3)) + 1;
end
for rowV = 1:size(indexV, 1)
if (indexV(rowV, 1) == 0 || indexV(rowV, 2) == 0 || indexV(rowV, 3) == 0)
continue;
end
V(indexV(rowV, 1), indexV(rowV, 2), indexV(rowV, 3)) = ...
V(indexV(rowV, 1), indexV(rowV, 2), indexV(rowV, 3)) + 1;
end
% normalize hsvHist to unit sum
A = A(:)';
A = A/sum(A);
H = H(:)';
H = H/sum(H);
V = V(:)';
V = V/sum(V);
koneksidbEkstraksi(A, H, V);
Before that, I also show code of database connection for result of extraction. Here is the code.
function koneksidbEkstraksi(App, Hor, Ver)
conn=database('cbir018','root','');
Cciri = exec(conn, 'select max(kd_ekstraksi)+1 from ekstraksifitur');
Cciri = fetch(Cciri);
%Cciri.Data
kd=Cciri.Data{1,1};
colciri = {'kd_ekstraksi' 'koe_app' 'koe_hor' 'koe_ver'};
rowciri = {kd, App, Hor, Ver};
fastinsert(conn, 'ekstraksifitur', colciri, rowciri);
close(conn);
I hope anyone can help me to solve this problem. Thank you.