I am reading some MATLAB code to hopefully improve my knowledge. I do not understand the use of NaN below in the 3rd line.
As I understand it ones is a N-by-N matrix of ones so why would you want to multiple them by NaN? I also do not understand the line where ret_usdvec is used again: ret_usdvec(sline(1,1):sline(1,2), :)... = tdata.
int_cos = length(usedolchk);
int_obs = length(pricedatew);
ret_usdvec = num2cell(NaN * ones(int_cos * int_obs, 4));
sline = ones(1, 2);
int_count_max = 400000;
int_count = 0;
for t = 1:int_obs
if (int_count == 0)
QES_DB = SEdatabase(data_base, '', '');
end
sql_statement = ['select idchk, co_name, pdatew, ret from D_RAWRETS'];
cursor = exec(QES_DB, sql_statement);
cursor = fetch(cursor);
tdata = cursor.data;
sline(1, 2) = sline(1, 1) + length(tdata(:, 1)) - 1;
ret_usdvec(sline(1, 1):sline(1, 2), :)...
= tdata;
sline(1, 1) = sline(1, 2) + 1;
int_count = int_count + length(tdata(:, 1));
if (int_count >= int_count_max) || t == int_obs
close(QES_DB);clear QES_DB
int_count = 0;
end
end
It looks to me like they are just allocating the space for the data with NaN values, and then filling in the data with the true values within the loop. That way, if there is any missing data, it will have the value NaN.
Related
I have two Xval(Predicted values) and Sv(validation test) matrices, one with the classifier output data and the other with the validation data for the same samples. Each column represents the predicted value, eg [0 0 1 0 0 0 0 0 0 0] represents digit 3 (1 in the digit that is). I would like to know if it is possible to calculate the confusion matrix in a vectorized way or with a built in function, the sizes of both matrices are 12000x10. The code who generates both matrices are this
load data;
load test;
[N, m] = size(X);
X = [ones(N, 1) X];
[Nt, mt] = size(Xt);
Xt = [ones(Nt, 1) Xt];
new_order = randperm(N);
X = X(new_order,: );
S = S(new_order,: );
part = 0.8;
Xtr = X(1: (part * N),: );
Xv = X((part * N + 1): N,: );
Str = S(1: (part * N),: );
Sv = S((part * N + 1): N,: );
v_c = [];
v_tx_acerto = [];
tx_acerto_max = 0;
c = 250;
w = (X'*X+c*eye(m+1))\X' * S;
Xval = Xv*w;
for i=1:12000
aux = Xval(i,:);
aux(aux == max(aux)) = 1;
aux(aux<1) = 0;
Xval(i,:) = aux;
end
There are build-in functions confusionmat or plotconfusion. But if you want to have full control, you can just write a simple function yourself, e.g:
function [CMat_rel,CMat_abs] = ConfusionMatrix(Cprd,Cact)
Cprd_uq = unique(Cprd);
Cact_uq = unique(Cact);
NumPrd = length(Cprd_uq);
NumAct = length(Cact_uq);
% assert(NumPrd == NumAct)
% allocate memory
CMat_abs = NaN(NumPrd,NumAct);
CMat_rel = NaN(NumPrd,NumAct);
for j = 1:NumAct
lgAct = Cact == Cact_uq(j);
SumAct = sum(lgAct);
for i = 1:NumAct
lgPrd = Cprd == Cact_uq(i);
Num = sum( lgPrd(lgAct) == true );
CMat_abs(i,j) = Num;
CMat_rel(i,j) = Num/SumAct;
end
end
end
I'm trying to find all possible combinations of a set but the order of the elements are also important for my problem.
For example for the set set={A, B, C}, the possible subsets are subsets={A},{B},{C},{A,B},{A,C},{B,A},{B,C},{C,A},{C,B},{A,B,C},{A,C,B},{B,A,C},{B,C,A},{C,A,B},{C,B,A}.
Are there any Matlab function to find that?
Thanks in advance.
I couldn't bear to see all those for loops in Tommaso's answer, so here's one with no loops:
a = {'A' 'B' 'C'};
% Build an array of binary vectors which we will use to select subsets of
% the array to be permuted
nGroups = 2^numel(a) - 1;
selector = dec2bin(1:nGroups) == '1'; % hack to convert numbers to binary vectors
selectVectors = arrayfun(#(x) selector(x,:), 1:size(selector, 1), 'UniformOutput', false);
% Get the permutations of each subset of the array
permsCell = cellfun(#(s) perms(a(s)), selectVectors, 'UniformOutput', false);
% Rearrange the permutations into a one-dimensional cell array with one
% permutation in each element
rowsAsCells = #(ca) arrayfun(#(x) ca(x,:), 1:size(ca,1), 'UniformOutput', false);
permsAsRows = cellfun(rowsAsCells, permsCell, 'UniformOutput', false);
result = cat(2, permsAsRows{:});
This returns a cell array with one permutation in each element, like Tommaso's second solution.
Whether this version is preferable is a matter of taste ;-)
a = {'A' 'B' 'C'};
a_len = numel(a);
res_len = 0;
for i = 1:a_len
res_len = res_len + (factorial(a_len) / factorial(a_len - i));
end
res = cell(res_len,a_len);
res_off = 1;
for i = 1:a_len
bin = nchoosek(a,i);
for j = 1:size(bin,1)
bin_j = bin(j,:);
per = perms(bin_j);
per_hei = size(per,1);
res_ran = res_off + per_hei - 1;
res(res_off:res_ran,:) = [per repmat({''},size(per,1),a_len - i)];
res_off = res_off + per_hei;
end
end
Alternatively, if you don't want results organized into equally sized columns, but rather inserted into a single vector with variable length:
a = {'A' 'B' 'C'};
a_len = numel(a);
res_len = 0;
for i = 1:a_len
res_len = res_len + (factorial(a_len) / factorial(a_len - i));
end
res = cell(res_len,1);
res_off = 1;
for i = 1:numel(a)
bin = nchoosek(a,i);
for j = 1:size(bin,1)
bin_j = bin(j,:);
per = perms(bin_j);
for y = 1:size(per,1)
res{res_off,1} = {per{y,:}};
res_off = res_off + 1;
end
end
end
I estimated a depth map using machine learning and i want to evaluate my results (using matlab). Depth map and depth true are images with 8 bits (normalized to [0 1] before evaluation). I used relative,rmse and log 10 error to do the step of evaluation.
function result = evaluate(estimated,depthTrue,number)
if(number == 1)
result = relative(estimated,depthTrue);
end
if (number == 2)
result = log10error(estimated,depthTrue);
end
if(number ==3)
result = rmse(estimated,depthTrue);
end
end
function result = relative(estimated,depthTrue)
result = mean(mean(abs(estimated - depthTrue)./depthTrue));
end
function result = log10error(estimated,depthTrue)
result = mean(mean(abs(log10(estimated) - log10(depthTrue))));
end
function result = rmse(estimated,depthTrue)
result = sqrt(mean(mean(abs(estimated - depthTrue).^2)));
end
When i try an evaluation with image i got infinity value (only log10error and relative). After search, i found that depthTrue and estimated can have 0 values.
log10(0)
ans =
-Inf
5/0
ans =
Inf
So, what should i do ?
I can think of several approaches to overcome this, depends on what best suits your needs. you can ignore the inf's or just replace them with other values. for example:
depthTrue = rand(4);
estimated = rand(4);
estimated(1,1) = 0;
% 1) ignore infs
absdiff = abs(log10(estimated(:)) - log10(depthTrue(:)));
result1 = mean( absdiff(~isinf(absdiff)) )
% 2) subtitute infs
veryHighNumber = 1e5;
absdiff(isinf(absdiff)) = veryHighNumber;
result2 = mean( absdiff )
% 3) subtitute zeros
verySmallNumber = 1e-5;
depthTrue(depthTrue == 0) = verySmallNumber;
estimated(estimated == 0) = verySmallNumber;
absdiff = abs(log10(estimated(:)) - log10(depthTrue(:)));
result3 = mean( absdiff )
I would like to divide an image into 8 by 6 blocks and then from each block would like to get the average of red, green and blue values then store the average values from each block into an array. Say that if I have image divided into 4 blocks the result array would be:
A = [average_red, average_green, average_blue,average_red, ...
average_green, average_blue,average_red, average_green, ...
average_blue,average_red, average_green, average_blue,...
average_red, average_green, average_blue,]
The loop I have created looks very complicated, takes a long time to run and I'm not even sure if it's working properly or not as I have no clue how to check. Is there any simpler way to implement this.
Here is the loop:
[rows, columns, ~] = size(img);
[rows, columns, ~] = size(img);
rBlock = 6;
cBlock = 8;
NumberOfBlocks = rBlock * cBlock;
bRow = ceil(rows/rBlock);
bCol = ceil(columns/cBlock);
row = bRow;
col = bCol;
r = zeros(row*col,1);
g = zeros(row*col,1);
b = zeros(row*col,1);
n = 1;
cl = 1;
rw = 1;
for x = 1:NumberOfBlocks
for i = cl : col
for j = rw : row
% some code
end
end
%some code
if i == columns && j ~= rows
cl = 1;
rw = j - (bRow -1);
col = (col - col) + bCol;
row = row + bRaw;
elseif a == columns && c == rows
display('done');
else
cl = i + 1;
rw = j - (bRow -1);
col = col + col;
row = row + row;
end
end
Because there are only 48 block, you may use simple for loop iterating blocks. (I think it's going to be fast enough).
Here is my code:
%Build test image
img = double(imresize(imread('peppers.png'), [200, 300]));
[rows, columns, ~] = size(img);
rBlock = 6;
cBlock = 8;
NumberOfBlocks = rBlock * cBlock;
bRow = ceil(rows/rBlock);
bCol = ceil(columns/cBlock);
idx = 1;
A = zeros(1, rBlock*cBlock*3);
for y = 0:rBlock-1
for x = 0:cBlock-1
%Block (y,x) boundaries: (x0,y0) to (x1,y1)
x0 = x*bCol+1;
y0 = y*bRow+1;
x1 = min(x0+bCol-1, columns); %Limit x1 to columns
y1 = min(y0+bRow-1, rows); %Limit y1 to rows
redMean = mean2(img(y0:y1, x0:x1, 1)); %Mean of red pixel in block (y,x)
greenMean = mean2(img(y0:y1, x0:x1, 2)); %Mean of green pixel in block (y,x)
blueMean = mean2(img(y0:y1, x0:x1, 3)); %Mean of blue pixel in block (y,x)
%Fill 3 elements of array A.
A(idx) = redMean;
A(idx+1) = greenMean;
A(idx+2) = blueMean;
%Advance index by 3.
idx = idx + 3;
end
end
I'm trying to implement this paper 'Salient Object detection by composition' here is the link: http://research.microsoft.com/en-us/people/yichenw/iccv11_salientobjectdetection.pdf
I have implemented the algorithm but it takes a long time to execute and display the output. I'm using 4 for loops in the code(Using for loops is the only way I could think of to implement this algorithm.) I have searched online for MATLAB code, but couldn't find anything. So can anyone please suggest any faster way to implement the algorithm. Also in the paper they(the authors) say that they have implemented the code using MATLAB and it runs quickly. So there definitely is a way to write the code more efficiently.
I appreciate any hint or code to execute this algorithm efficiently.
clc
clear all
close all
%%instructions to run segment.cpp
%to run this code
%we need an output image
%segment sigma K min input output
%sigma: used for gaussian smoothing of the image
%K: scale of observation; larger K means larger components in segmentation
%min: minimum component size enforced by post processing
%%
%calculating composition cost for each segment
I_org = imread('segment\1.ppm');
I = imread('segment\output1.ppm');
[rows,cols,dims] = size(I);
pixels = zeros(rows*cols,dims);
red_channel = I(:,:,1);
green_channel = I(:,:,2);
blue_channel = I(:,:,3);
[unique_pixels,count_pixels] = countPixels(I);
no_segments = size(count_pixels,1);
area_segments = count_pixels ./ (rows * cols);
appearance_distance = zeros(no_segments,no_segments);
spatial_distance = zeros(no_segments,no_segments);
thresh = multithresh(I_org,11);
thresh_values = [0 thresh];
for i = 1:no_segments
leave_pixel = unique_pixels(i,:);
mask_image = ((I(:,:,1) == leave_pixel(1)) & (I(:,:,2) == leave_pixel(2)) & (I(:,:,3) == leave_pixel(3)));
I_i(:,:,1) = I_org(:,:,1) .* uint8((mask_image));
I_i(:,:,2) = I_org(:,:,2) .* uint8((mask_image));
I_i(:,:,3) = I_org(:,:,3) .* uint8((mask_image));
LAB_trans = makecform('srgb2lab');
I_i_LAB = applycform(I_i,LAB_trans);
L_i_LAB = imhist(I_i_LAB(:,:,1));
A_i_LAB = imhist(I_i_LAB(:,:,2));
B_i_LAB = imhist(I_i_LAB(:,:,3));
for j = i:no_segments
leave_pixel = unique_pixels(j,:);
mask_image = ((I(:,:,1) == leave_pixel(1)) & (I(:,:,2) == leave_pixel(2)) & (I(:,:,3) == leave_pixel(3)));
I_j(:,:,1) = I_org(:,:,1) .* uint8((mask_image));
I_j(:,:,2) = I_org(:,:,2) .* uint8((mask_image));
I_j(:,:,3) = I_org(:,:,3) .* uint8((mask_image));
I_j_LAB = applycform(I_j,LAB_trans);
L_j_LAB = imhist(I_j_LAB(:,:,1));
A_j_LAB = imhist(I_j_LAB(:,:,2));
B_j_LAB = imhist(I_j_LAB(:,:,3));
appearance_distance(i,j) = sum(min(L_i_LAB,L_j_LAB) + min(A_i_LAB,A_j_LAB) + min(B_i_LAB,B_j_LAB));
spatial_distance(i,j) = ModHausdorffDist(I_i,I_j) / max(rows,cols);
end
end
spatial_distance = spatial_distance ./ max(max(spatial_distance));
max_apperance_distance = max(max(appearance_distance));
composition_cost = ((1 - spatial_distance) .* appearance_distance) + (spatial_distance * max_apperance_distance);
%%
%input parameters for computation
window_size = 9; %rows and colums are considered to be same
window = ones(window_size);
additional_elements = (window_size - 1)/2;
I_temp(:,:,1) = [zeros(additional_elements,cols);I(:,:,1);zeros(additional_elements,cols)];
I_new(:,:,1) = [zeros(rows + (window_size - 1),additional_elements) I_temp(:,:,1) zeros(rows + (window_size - 1),additional_elements)];
I_temp(:,:,2) = [zeros(additional_elements,cols);I(:,:,2);zeros(additional_elements,cols)];
I_new(:,:,2) = [zeros(rows + (window_size - 1),additional_elements) I_temp(:,:,2) zeros(rows + (window_size - 1),additional_elements)];
I_temp(:,:,3) = [zeros(additional_elements,cols);I(:,:,3);zeros(additional_elements,cols)];
I_new(:,:,3) = [zeros(rows + (window_size - 1),additional_elements) I_temp(:,:,3) zeros(rows + (window_size - 1),additional_elements)];
cost = zeros(rows,cols);
for i = additional_elements + 1:rows
for j = additional_elements+1:cols
I_windowed(:,:,1) = I_new(i-additional_elements:i+additional_elements,i-additional_elements:i+additional_elements,1);
I_windowed(:,:,2) = I_new(i-additional_elements:i+additional_elements,i-additional_elements:i+additional_elements,2);
I_windowed(:,:,3) = I_new(i-additional_elements:i+additional_elements,i-additional_elements:i+additional_elements,3);
[unique_pixels_w,count_pixels_w] = countPixels(I_windowed);
unique_pixels_w = setdiff(unique_pixels_w,[0 0 0],'rows');
inside_segment = setdiff(unique_pixels,unique_pixels_w);
outside_segments = setdiff(unique_pixels,inside_segment);
area_segment = count_pixels_w;
for k = 1:size(inside_pixels,1)
current_segment = inside_segment(k,:);
cost_curr_seg = sort(composition_cost(ismember(unique_pixels,current_segment,'rows'),:));
for l = 1:size(cost_curr_seg,2)
if(ismember(unique_pixels(l,:),outside_segments,'rows') && count_pixels(l) > 0)
composed_area = min(area_segment(k),count_pixels(l));
cost(i,j) = cost(i,j) + cost_curr_seg(l) * composed_area;
area_segment(k) = area_segment(k) - composed_area;
count_pixels(l) = count_pixels(l) - composed_area;
if area_segment(k) == 0
break
end
end
end
if area(k) > 0
cost(i,j) = cost(i,j) + max_apperance_distance * area_segment(k);
end
end
end
end
cost = cost / window_size;
The code for the countPixels function:
function [unique_rows,counts] = countPixels(I)
[rows,cols,dims] = size(I);
pixels_I = zeros(rows*cols,dims);
count = 1;
for i = 1:rows
for j = 1:cols
pixels_I(count,:) = reshape(I(i,j,:),[1,3]);
count = count + 1;
end
end
[unique_rows,~,ind] = unique(pixels_I,'rows');
counts = histc(ind,unique(ind));
end