Best-Worst Method(BWM) in Matlab - linprog - matlab

I need a guidance on a problem with linprog. I have an optimization problem that weights and the minimum value of the objective function are needed, but I can't allocate the parameters properly. The form of problem and subjects are like this. The picture of the problem is attached.
Any help regarding understanding the problem and getting a solution would be much appreciated. The picture below contains the formula for the problem.
IMAGE
P.S.: The object here is to code BWM(Best Worst Method) By Dr. Jafar Rezaei in matlab.
Ws and Ksi are the optimal weights and objective function we want to obtain and As are the vector that its values are present.

Here is the code in matlab.
clc;clear;close all;
delete Data.mat
DATA = xlsread("Data.xlsx");
NumOfExperts = size(DATA , 1) / 2;
NumOfCriteria = size(DATA , 2);
BestData = DATA( 1:NumOfExperts , : );
WorstData = DATA( NumOfExperts + 1: end , :);
WorstData = WorstData';
ConsistencyIndex = [0 , .44 , 1 , 1.63 , 2.3 ,3 , 3.73 , 4.47 , 5.23];
DATA = struct;
for i = 1:NumOfExperts
IndexOfBest = find(BestData(i , :) == 0);
IndexOfWorst = find(WorstData(: , i) == 0);
BestData(i , IndexOfBest) = 1;
WorstData(IndexOfWorst , i) = 1;
DATA(i).Best = BestData(i , :);
DATA(i).Worst = WorstData(: , i);
DATA(i).BestIndex = IndexOfBest;
DATA(i).WorstIndex = IndexOfWorst;
end
clear BestData .. WorstData .. IndexOfBest .. IndexOfWorst;
MeanWeight = zeros(1 , NumOfCriteria);
for i = 1:NumOfExperts
Data = DATA(i);
save Data
EqualCoefftMat = ones(1 , NumOfCriteria);
InitialPoints = rand(1 , NumOfCriteria);
LowerBound = zeros(1 , NumOfCriteria);
UpperBound = ones(1 , NumOfCriteria);
options = optimoptions(#fmincon , 'Algorithm' , 'interior-point' , 'MaxFunctionEvaluations' , 50000 , 'MaxIterations' , 5000 );
[DATA(i).Weights , DATA(i).Ksi] = fmincon(#Epsilon , InitialPoints , [] , [] , EqualCoefftMat , 1 , LowerBound , UpperBound , [], options);
DATA(i).ConsistencyRatio = DATA(i).Ksi/ConsistencyIndex(max(max(DATA(i).Best) , max(DATA(i).Worst)));
MeanWeight = MeanWeight + DATA(i).Weights;
end
MeanWeight = MeanWeight/NumOfExperts;
bar(MeanWeight);
xlabel('Criterias');
ylabel('Weights');
title(['Mean Of Weights is: ', num2str(mean(MeanWeight))]);
[Result.Weights , Result.IndexOfWeight] = sort(MeanWeight , 'descend');
function Out = Epsilon(x)
load Data
for i = 1:NumOfCriteria
f(i) = abs(x(Data.BestIndex)/x(i) - Data.Best(i));
g(i) = abs(x(i)/x(Data.WorstIndex) - Data.Worst(i));
end
Out = (sum(f) + sum(g) - g(Data.BestIndex))*2/NumOfCriteria;
end

Related

Why MATLAB keeps getting error 'Unrecognized Variable' when i pass a matrix of numbers?

My code is :
function qam = qmodulation(t, Fc, symbol)
modcombs = [
1 1;
1 3;
3 1;
3 3;
-1 1;
-1 3;
-3 1;
-3 3;
-1 -1;
-1 -3;
-3 -1;
-3 -3;
1 -1;
1 -3;
3 -1;
3 -3;
];
for j = 1:16
if(symbol == (j-1))
i = modcombs(j,1);
q = modcombs(j,2);
end
end
qam = cos(2*pi*Fc*t).*i - sin(2*pi*Fc*t).*q ;
end
I have one more function called "symbol( t , tinc , csn , bits )":
function sym = symbol(t, tinc, csn, bits)
qamx = 16;
digitcount = log(qamx)/log(2);
compfact = 1/tinc;
tsyc = 20000/digitcount;
sampleperiod = csn/tsyc;
bitindex = digitcount*fix( (t*compfact) / sampleperiod ) + 1 ;
temp = 0;
for k = 0 : 1 : ( digitcount - 1 )
temp = temp + bits(bitindex) * 2.^(digitcount-1-k);
bitindex = bitindex + 1;
end
sym = temp;
end
This is main script:
tmin = 0;
tinc = 0.0000001;
tmax = 3.9999999;
csn = (tmax - tmin + tinc) / tinc;
bits = round(0.75*rand(1,20000));
t = tmin : tinc : tmax;
Fc = 50000;
y = qmodulation( t, Fc, symbol(t, tinc, csn, bits) );
%y = awgn(x,35,'measured');
plot(t,y)
I want to modulate the qmodulation function with symbol function. But when i pass the symbol function into qmodulation, MATLAB doesn't seems to get the symbol function and can't enter the if block in the qmodulation function. Thus, i and q are not defined. So the command window shows an error "Unrecognized Variable 'i'".
When I pass a single value as symbol parameter, qmodulation function works fine and MATLAB can plot it.
All the parameters are defined in the main function. tmin, tinc, tmax also predefined.
t = tmin : tinc : tmax;
qmodulation( t , Fc , 15 ) ---> Works fine
qmodulation( t , Fc , symbol( t , tinc , csn , bits ) ) ---> Doesn't work, Unrecognized Error
qmodulation ( t , Fc , symbol( 0.080 , tinc , csn , bits ) ) ---> Works fine too
What could possible cause that? Why MATLAB doesn't seem to get a matrix of data while it's okey with a single value?
The Error is :
>> main
Unrecognized function or variable 'i'.
Error in qmodulation (line 34)
qam = cos(2*pi*Fc*t).*i - sin(2*pi*Fc*t).*q ;
Error in main (line 12)
y = qmodulation( t, Fc, symbol(t, tinc, csn, bits) );

Detect faces, crop, and save them in different file

I have image data (for 40 people) and I am trying to detect face in each image, crop it and save it in another file. I am using MATLAB for this but it doesn't work.
ERROR : Unable to open file "C:\Users\mstfy\Desktop\Matlab\alex\newdata\cropped\" for writing. You might not have write permission.
I think there is something wrong in my for loop.
location = 'C:\Users\mstfy\Desktop\Matlab\alex\newdata\*.jpg';
croppedimg = 'C:\Users\mstfy\Desktop\Matlab\alex\newdata\cropped\';
imds = imageDatastore ( 'C:\Users\mstfy\Desktop\Matlab\alex\newdata' , ...
'IncludeSubfolders' , true, ...
'LabelSource' , 'foldernames' );
idx = randperm (numel (imds.Files), 16);
j = 1;
figure
for t = 1: 16
img = readimage (imds, idx (t));
FaceDetect = vision.CascadeObjectDetector;
FaceDetect.MergeThreshold = 7;
BB = step (FaceDetect, img);
for i = 1: size (BB, 1)
rectangle ( 'Position' , BB (i, :), 'LineWidth' , 3, 'LineStyle' , '-' , 'EdgeColor' , 'r' );
end
for i = 1: size (BB, 1)
J = imcrop (img, BB (i, :));
figure (3);
subplot (6, 6, i);
imshow (J);
j = j + 1;
imwrite (J,croppedimg,'jpg' )
end
end

How to split a cell 1x1 in Matlab?

Let's say I have a 1x1 cell with this value : 'atcatcaaca' .
My goal is :
Add 1 to 5 'a' beside any 'a'.
Add 1 to 10 'c' beside any 'c'.
Add a random number of 'g' beside any 'g'.
Add a random number of 't' beside any 't'.
For example i have 'atcatcaaca'.My goal is to make it like:'aaaattttcccaattttccaaaaaaaaaacccccccccaa'
My thought is to take the value cell and split it somehow in a matrix:
a | t | a | t | c |a |a | c | a.
Is it possible?And if it is ,how?
The code is :
filename = fullfile(matlabroot,'virus_nucleotitde2.dat');
Z = readtable(filename);
S = table2cell(Z);
num_rows = size (Z,1);
num_cols = size (Z,2);
for i=1:1:num_rows
for j=1:1:num_cols
B = S(i,j);
a=0;
c=0;
g=0;
t=0;
B{1} = num2cell(B{1});
n = randi(6); % Random number between 1 and 6
B{1} = strrep(B{1} , 'a' , repmat('a' , 1, n));
n = randi(11); % Random number between 1 and 11
B{1} = strrep(B{1} , 'c' , repmat('c' , 1, n));
n = randi(11);
B{1} = strrep(B{1} , 'g' , repmat('g' , 1, n));
n = randi(11);
B{1} = strrep(B{1} , 't' , repmat('t' , 1, n));
end
end
Inside the cell, there is a char that you can access with curly brackets:
S = {'ataggatag'};
B = S{1};
disp(B)
Then, strrep is your friend:
n = randi(6); % Random number between 1 and 6
B = strrep(B , 'a' , repmat('a' , 1, n));
n = randi(11); % Random number between 1 and 11
B = strrep(B , 'c' , repmat('c' , 1, n));
n = randi(11);
B = strrep(B , 'g' , repmat('g' , 1, n));
n = randi(11);
B = strrep(B , 't' , repmat('t' , 1, n));
Then put it back into the cell
S{1} = B;
disp(S)
Note that I used 6 as maximum number of 'a's because strrep is going to replace the original a, not adding letters beside it as you asked.
EDIT:
Following OP's edit, here is your solution:
S = {'ataggatag'};
num_rows = size (S,1);
num_cols = size (S,2);
for i=1:1:num_rows
for j=1:1:num_cols
n = randi(6); % Random number between 1 and 6
S{i,j} = strrep(S{i,j} , 'a' , repmat('a' , 1, n));
n = randi(11); % Random number between 1 and 11
S{i,j} = strrep(S{i,j} , 'c' , repmat('c' , 1, n));
n = randi(11);
S{i,j} = strrep(S{i,j} , 'g' , repmat('g' , 1, n));
n = randi(11);
S{i,j} = strrep(S{i,j} , 't' , repmat('t' , 1, n));
end
end
disp(S)
It's already so.. 'a string' is an array of chars, so in order to convert them to a cell array you need to use the usual num2cell function:
>> name_in_1x1_cell_array{1} = 'ataggatag'
name_in_1x1_cell_array =
'ataggatag'
>> name_in_1x1_cell_array{1} = num2cell(name_in_1x1_cell_array{1})
name_in_1x1_cell_array =
{1x9 cell}
You can also access to characters directly, for example you can cycle every character of a string and display it:
name = 'some name';
for i = 1 : length(name)
disp(name(i));
end
Based on your description, not the code:
With the function strrep this is straightforward, as it operates on cell arrays as well:
cell_string = {'atcatcaaca'};
% add a's
cell_string = strrep(cell_string, 'a', repmat('a',1,5));
% add c's
cell_string = strrep(cell_string, 'c', repmat('c',1,10));
% add t's
cell_string = strrep(cell_string, 't', repmat('t',1,randi(10)));
The function repmat is used to duplicate characters.

Weird phenomenon when converting RGB to HSV manually in Matlab

I have written a small Matlab funcion which takes an image in RGB and converts it to HSV according to the conversion formulas found here.
The problem is that when I apply this to a color spectrum there is a cut in the spectrum and some values are wrong, see images (to make the comparison easier I have used the internal hsv2rgb() function to convert back to RGB. This does not happen with Matlabs own function rgb2hsv() but I can not find what I have done wrong.
This is my function
function [ I_HSV ] = RGB2HSV( I_RGB )
%UNTITLED3 Summary of this function goes here
% Detailed explanation goes here
[MAX, ind] = max(I_RGB,[],3);
if max(max(MAX)) > 1
I_r = I_RGB(:,:,1)/255;
I_g = I_RGB(:,:,2)/255;
I_b = I_RGB(:,:,3)/255;
MAX = max(cat(3,I_r, I_g, I_b),[],3);
else
I_r = I_RGB(:,:,1);
I_g = I_RGB(:,:,2);
I_b = I_RGB(:,:,3);
end
MIN = min(cat(3,I_r, I_g, I_b),[],3);
d = MAX - MIN;
I_V = MAX;
I_S = (MAX - MIN) ./ MAX;
I_H = zeros(size(I_V));
a = 1/6*mod(((I_g - I_b) ./ d),1);
b = 1/6*(I_b - I_r) ./ d + 1/3;
c = 1/6*(I_r - I_g) ./ d + 2/3;
H = cat(3, a, b, c);
for m=1:size(H,1);
for n=1:size(H,2);
if d(m,n) == 0
I_H(m,n) = 0;
else
I_H(m,n) = H(m,n,ind(m,n));
end
end
end
I_HSV = cat(3,I_H,I_S,I_V);
end
Original spectrum
Converted spectrum
The error was in my simplification of the calculations of a, b, and c. Changing it to the following solved the problem.
function [ I_HSV ] = RGB2HSV( I_RGB )
%UNTITLED3 Summary of this function goes here
% Detailed explanation goes here
[MAX, ind] = max(I_RGB,[],3);
if max(max(MAX)) > 1
I_r = I_RGB(:,:,1)/255;
I_g = I_RGB(:,:,2)/255;
I_b = I_RGB(:,:,3)/255;
MAX = max(cat(3,I_r, I_g, I_b),[],3);
else
I_r = I_RGB(:,:,1);
I_g = I_RGB(:,:,2);
I_b = I_RGB(:,:,3);
end
MIN = min(cat(3,I_r, I_g, I_b),[],3);
D = MAX - MIN;
I_V = MAX;
I_S = D ./ MAX;
I_H = zeros(size(I_V));
a = 1/6*mod(((I_g - I_b) ./ D),6);
b = 1/6*((I_b - I_r) ./ D + 2);
c = 1/6*((I_r - I_g) ./ D + 4);
H = cat(3, a, b, c);
for m=1:size(H,1);
for n=1:size(H,2);
if D(m,n) == 0
I_H(m,n) = 0;
else
I_H(m,n) = H(m,n,ind(m,n));
end
if MAX(m,n) == 0
S(m,n) = 0;
end
end
end
I_HSV = cat(3,I_H,I_S,I_V);
end

Bifurcation and ending in an edge image

I'm trying to find Ending and Bifurcation points of a binary edge image produced from an ear image.
I'm writing the code based on the algorithm defined in [this paper] (http://elcvia.cvc.uab.es/article/view/108). I've implemented the part that introduced the formula to find endings and bifurcation. However, I don't get the correct result for different pictures, It's like this formula can't find some of the bifurcations and endings.
this is my code :
stats = regionprops(BW4 , 'PixelList');
[numofcomp,x] = size(stats);
BEcell = cell(numofcomp,2);
Ne = zeros(numofcomp,1);
Nb = zeros(numofcomp,1);
for i=1:1:numofcomp
contour = stats(i).PixelList;
S = size(contour);
b=0;
ee=0;
for j=1:1:S(1)
J = contour(j,1);
I = contour(j,2);
g1 = BW4(I,J+1) - 1;
g2 = BW4(I-1,J+1) - 1;
g3 = BW4(I-1,J) - 1;
g4 = BW4(I-1,J-1) - 1;
g5 = BW4(I,J-1) - 1;
g6 = BW4(I+1,J-1) - 1;
g7 = BW4(I+1,J) - 1;
g8 = BW4(I+1,J+1) - 1;
G1=g1*g2*g3;
G3=g3*g4*g5;
G5=g5*g6*g7;
G7=g7*g8*g1;
Nc = (g1 -G1) + (g3 -G3) + (g5 -G5) + (g7 -G7 );
if Nc < -2
b=b+1;
BEcell{i , 1}(j,1) = I;
BEcell{i , 1}(j,2) = J;
end
if Nc == -1
ee=ee+1;
BEcell{i , 2}(j,1) = I;
BEcell{i , 2}(j,2) = J;
end
end
Nb(i,1)=b;
Ne(i,1)=ee;
end
I don't know what it's wrong with it ? Have you ever seen this formula before?
also, I'm not sure about g9 there is no g9 in the matrix which is numbered by paper
EDIT
I used bwmorph :
Bifurcation = bwmorph(BW4 , 'branchpoints' ,Inf );
B=0;
for i = 1:1:Size(1)
for j = 1:1:Size(2)
if( Bifurcation(i,j)) %
B = B+1;
end
end
end
%----------------------------- Find End Points ----------------------------
Endpoint = bwmorph(can , 'endpoints' ,Inf );
E=0;
for i = 1:1:Size(1)
for j = 1:1:Size(2)
if( Endpoint(i,j))
E = E+1;
end
end
end