Related
Basically I have a code where it produces a plot of all possible permutations between Cost and Reliability. There's a total of 864 data points split up between 8 rows. Five of the rows have 2 options and three of them 3 options.
Given here is a copy of my code. I'm trying to have the permutations of 'Other Cameras' and 'Depth & Structure Testing' have a different color with the other six possibilities. I tried using the 'gscatter' command but didn't have much luck with it.
I believe I need to have the scatter command in the if/else statements themselves, although I'm not too sure what to plot in the 'X' and 'Y' for the 'scatter' command. Currently my code is set up for plotting all the data in one color. I deleted my code with the 'gscatter' because I got many errors and when I tried to fix them the plot ultimately didn't work as planned.
% Pareto_Eval
baseline_cost = 45;
nrows = 8;
%Initialize Variables
for aa = 1:nrows
cost_delta(aa) = 0;
reliability(aa) = 1;
end
icount = 1;
%Propulsion
for row1 = 1:2
if row1 == 1
cost_delta(1)= -7;
reliability(1) = 0.995;
elseif row1==2
cost_delta(1)=0;
reliability(1)=.99;
end
%Entry Mode
for row2 = 1:2
if row2 == 1
cost_delta(2) = -3;
reliability(2) = .99;
else
cost_delta(2) = 0;
reliability(2) = .98;
end
%Landing Method
for row3 = 1:3
if row3 == 1 %if needs declaration
cost_delta(3)= 0;
reliability(3) = .99;
elseif row3 == 2 %elseif needs declaration
cost_delta(3) = 4;
reliability(3) = .995;
else %else does not need declaration
cost_delta(3) = -2;
reliability(3) = .95;
end
%Lander Type
for row4 = 1:3
if row4 == 1
cost_delta(4)= 10;
reliability(4) = .99;
elseif row4 == 2
cost_delta(4) = 0;
reliability(4) = .99;
else
cost_delta(4) = 15;
reliability(4) = .95;
end
%Rover Type
for row5 = 1:2
if row5 == 1
cost_delta(5)= -2;
reliability(5) = .98;
else
cost_delta(5) = 0;
reliability(5) = .975;
end
%Power Source
for row6 = 1:2
if row6 == 1
cost_delta(6) = -3;
reliability(6) = .95;
else
cost_delta(6) = 0;
reliability(6) = .995;
end
%Depth & Structure Testing
for row7 = 1:2
if row7 == 1
cost_delta(7) = 0;
reliability(7) = .99;
else
cost_delta(7) = 2;
reliability(7) = .85;
end
%Other Cameras
for row8 = 1:3
if row8 == 1
cost_delta(8)= -1;
reliability(8) = .99;
elseif row8 == 2
cost_delta(8) = -1;
reliability(8) = .99;
else
cost_delta(8) = 0;
reliability(8) = .9801;
end
cost_delta_total = 0;
reliability_product = 1;
for bb=1:nrows
cost_delta_total = cost_delta_total + cost_delta(bb);
reliability_product = reliability_product*reliability(bb);
end
total_cost(icount) = baseline_cost + cost_delta_total;
total_reliability(icount) = reliability_product;
icount = icount + 1;
end; end; end; %Rows 1,2,3
end; end; end; %Rows 4,5,6
end; end; %Rows 7,8
%Plot the Pareto Evaluation
fignum=1;
figure(fignum)
sz = 5;
scatter(total_reliability, total_cost, sz, 'blue')
xlabel('Reliability')
ylabel('Cost')
title('Pareto Plot')
Any help is appreciated. I don't have a lot of experience with Matlab and I've tried looking around for help but nothing really worked.
Here is a sample code to make questions easier I created:
% Pareto_Eval
baseline_cost = 55;
nrows = 3;
%Initialize Variables
for aa = 1:nrows
cost_delta(aa) = 0;
reliability(aa) = 1;
end
icount = 1;
%Group 1
for row1 = 1:2
if row1 == 1
cost_delta(1)= 5;
reliability(1) = 0.999;
elseif row1==2
cost_delta(1) = 0;
reliability(1) = .995;
end
%Group 2
for row2 = 1:2
if row2 == 1
cost_delta(2) = 0;
reliability(2) = .98;
else
cost_delta(2) = -2;
reliability(2) = .95;
end
%Group 3
for row3 = 1:2
if row3 == 1
cost_delta(3) = 3;
reliability(3) = .997;
else
cost_delta(3) = 0;
reliability(3) = .96;
end
%initializing each row
cost_delta_total = 0;
reliability_product = 1;
for bb = 1:nrows
cost_delta_total = cost_delta_total + cost_delta(bb);
reliability_product = reliability_product*reliability(bb);
end
total_cost(icount) = baseline_cost + cost_delta_total;
total_reliability(icount) = reliability_product;
icount = icount + 1;
end
end
end
fignum=1;
figure(fignum)
sz = 25;
scatter(total_reliability, total_cost, sz)
xlabel('Reliability')
ylabel('Cost')
title('Pareto Plot')
Basically I need to make a plot in each if-loop, but I'm not sure how to do it and have them all on the same plot
sounds like an interesting project! Not sure if I understood your intended plots correctly, but hopefully the code below gets you a bit closer to what you are looking for.
I've started off with a rather deep mess of nested for loops (as you did) but kept it more concise bybuilding a permutations matrix.
counter = 0;
for propulsion_options = 1:2
for entry_mode = 1:2
for landing_method = 1:3
for lander_type = 1:3
for rover_type = 1:2
for power_source = 1:2
for depth_testing = 1:2
for other_cameras = 1:3
counter = counter +1
permutations(counter,:) = [...
propulsion_options,...
entry_mode,...
landing_method,...
lander_type,...
rover_type,...
power_source,...
depth_testing,...
other_cameras];
end
end
end
end
end
end
end
end
This way I kept the actual scoring out of the loops, and perhaps easier to tweak the values. I initialised the cost and reliabiltiy arrays to be the same size as the permutations array:
cost_delta = zeros(size(permutations));
reliability = zeros(size(permutations));
Then for each metric, I searched the permutations array for all occurances of each possible value and assigned the appropriate score:
%propulsion
propertyNo = 1;
cost_delta(find(permutations(:,propertyNo)==1),propertyNo) = -7;
cost_delta(find(permutations(:,propertyNo)==2),propertyNo) = 0;
reliability(find(permutations(:,propertyNo)==1),propertyNo) = 0.995;
reliability(find(permutations(:,propertyNo)==2),propertyNo) = 0.99;
%entry_mode (2)
propertyNo = 2;
cost_delta(find(permutations(:,propertyNo)==1),propertyNo) = -3;
cost_delta(find(permutations(:,propertyNo)==2),propertyNo) = 0;
reliability(find(permutations(:,propertyNo)==1),propertyNo) = 0.99;
reliability(find(permutations(:,propertyNo)==2),propertyNo) = 0.98;
%landing_method (3)
propertyNo = 3;
cost_delta(find(permutations(:,propertyNo)==1),propertyNo) = 0;
cost_delta(find(permutations(:,propertyNo)==2),propertyNo) = 4;
cost_delta(find(permutations(:,propertyNo)==3),propertyNo) = -2;
reliability(find(permutations(:,propertyNo)==1),propertyNo) = 0.99;
reliability(find(permutations(:,propertyNo)==2),propertyNo) = 0.995;
reliability(find(permutations(:,propertyNo)==3),propertyNo) = 0.95;
%lander_type (3)
propertyNo = 4;
cost_delta(find(permutations(:,propertyNo)==1),propertyNo) = 10;
cost_delta(find(permutations(:,propertyNo)==2),propertyNo) = 0;
cost_delta(find(permutations(:,propertyNo)==3),propertyNo) = 15;
reliability(find(permutations(:,propertyNo)==1),propertyNo) = 0.99;
reliability(find(permutations(:,propertyNo)==2),propertyNo) = 0.99;
reliability(find(permutations(:,propertyNo)==3),propertyNo) = 0.95;
%rover_type (2)
propertyNo = 5;
cost_delta(find(permutations(:,propertyNo)==1),propertyNo) = -2;
cost_delta(find(permutations(:,propertyNo)==2),propertyNo) = 0;
reliability(find(permutations(:,propertyNo)==1),propertyNo) = 0.98;
reliability(find(permutations(:,propertyNo)==2),propertyNo) = 0.975;
%power_source (2)
propertyNo = 6;
cost_delta(find(permutations(:,propertyNo)==1),propertyNo) = -3;
cost_delta(find(permutations(:,propertyNo)==2),propertyNo) = 0;
reliability(find(permutations(:,propertyNo)==1),propertyNo) = 0.95;
reliability(find(permutations(:,propertyNo)==2),propertyNo) = 0.995;
%depth_testing (2)
propertyNo = 7;
cost_delta(find(permutations(:,propertyNo)==1),propertyNo) = 0;
cost_delta(find(permutations(:,propertyNo)==2),propertyNo) = 2;
reliability(find(permutations(:,propertyNo)==1),propertyNo) = 0.99;
reliability(find(permutations(:,propertyNo)==2),propertyNo) = 0.85;
%other_cameras (3)
propertyNo = 8;
cost_delta(find(permutations(:,propertyNo)==1),propertyNo) = -1;
cost_delta(find(permutations(:,propertyNo)==2),propertyNo) = -1;
cost_delta(find(permutations(:,propertyNo)==3),propertyNo) = 0;
reliability(find(permutations(:,propertyNo)==1),propertyNo) = 0.99;
reliability(find(permutations(:,propertyNo)==2),propertyNo) = 0.99;
reliability(find(permutations(:,propertyNo)==3),propertyNo) = 0.9801;
Then each permutation can have a total cost / reliabiltiy score by summing and takign the product along the second dimension:
cost_delta_total = sum(cost_delta,2);
reliability_product = prod(reliability,2);
Finally, you can plot all points (as per your original):
%Plot the Pareto Evaluation
fignum=1;
figure(fignum)
sz = 5;
scatter(reliability_product, cost_delta_total, sz, 'b')
xlabel('Reliability')
ylabel('Cost')
title('Pareto Plot')
or you can create an index into the permutations by searching for specific property values and plot these different colours (actually this bit answers your most specific question of how to plot two things on the same axes - you just need the hold on; command):
propertyNo = 7;
indexDepth1 = find(permutations(:,propertyNo)==1);
indexDepth2 = find(permutations(:,propertyNo)==2);
fignum=2;
figure(fignum)
sz = 5;
scatter(reliability_product(indexDepth1), cost_delta_total(indexDepth1), sz, 'k');
hold on;
scatter(reliability_product(indexDepth2), cost_delta_total(indexDepth2), sz, 'b');
xlabel('Reliability')
ylabel('Cost')
title('Pareto Plot')
legend('Depth & Structure Test 1','Depth & Structure Test 2')
propertyNo = 8;
indexCam1 = find(permutations(:,propertyNo)==1);
indexCam2 = find(permutations(:,propertyNo)==2);
indexCam3 = find(permutations(:,propertyNo)==3);
fignum=3;
figure(fignum)
sz = 5;
scatter(reliability_product(indexCam1), cost_delta_total(indexCam1), sz, 'k');
hold on;
scatter(reliability_product(indexCam2), cost_delta_total(indexCam2), sz, 'b');
scatter(reliability_product(indexCam3), cost_delta_total(indexCam3), sz, 'g');
xlabel('Reliability')
ylabel('Cost')
title('Pareto Plot')
legend('Other Camera 1','Other Camera 2','Other Camera 3')
Good luck with the mission! When is launch day?
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
Say I have Matrix A, defined in MATLAB as:
A = zeros(2,2,2,2,2);
A(1,1,1,1,1) = 1;
A(1,1,1,1,2) = 2;
A(1,1,1,2,1) = 3;
A(1,1,1,2,2) = 4;
A(1,1,2,1,1) = 5;
A(1,1,2,1,2) = 6;
A(1,1,2,2,1) = 7;
A(1,1,2,2,2) = 8;
A(1,2,1,1,1) = 9;
A(1,2,1,1,2) = 10;
A(1,2,1,2,1) = 11;
A(1,2,1,2,2) = 12;
A(1,2,2,1,1) = 13;
A(1,2,2,1,2) = 14;
A(1,2,2,2,1) = 15;
A(1,2,2,2,2) = 16;
A(2,1,1,1,1) = 17;
A(2,1,1,1,2) = 18;
A(2,1,1,2,1) = 19;
A(2,1,1,2,2) = 20;
A(2,1,2,1,1) = 21;
A(2,1,2,1,2) = 22;
A(2,1,2,2,1) = 23;
A(2,1,2,2,2) = 24;
A(2,2,1,1,1) = 25;
A(2,2,1,1,2) = 26;
A(2,2,1,2,1) = 27;
A(2,2,1,2,2) = 28;
A(2,2,2,1,1) = 29;
A(2,2,2,1,2) = 30;
A(2,2,2,2,1) = 31;
A(2,2,2,2,2) = 32;
How can I convert this Matrix into a new Matrix B, such that matrix B is a vector such that B = [1,2,3,4...32]?
The reshape function isn't working and I can't find anything online to help.
Thanks in advance!
You have the dimensions in the opposite order to achieve what you want. So: just permute the dimensions (with permute) and then linearize (with :):
B = permute(A, [5 4 3 2 1]);
B = B(:);
If you want it in one line, use reshape for the linearization:
B = reshape(permute(A, [5 4 3 2 1]), [],1);
If you defined (note the reversal of indices)
A(1,1,1,1,1) = 1;
A(2,1,1,1,1) = 2;
A(1,2,1,1,1) = 3;
A(2,2,1,1,1) = 4;
A(1,1,2,1,1) = 5;
A(2,1,2,1,1) = 6;
A(1,2,2,1,1) = 7;
A(2,2,2,1,1) = 8;
...
the dimensions would be in the "right" order, and then you wouldn't need permute:
B = A(:);
or
B = reshape(A, [],1);
Assuming types of all variables are struct and have same fields with concatenatable size (dimensions). For example:
a.x = 1; a.y = 2;
b.x = 10; b.y = 20;
With the ordinary concatenation:
c = [a; b];
returns
c(1).x = 1; c(1).y = 2;
c(2).x = 10; c(2).y = 20;
What I want is:
c.x(1) = 1; c.y(1) = 2;
c.x(2) = 10; c.y(2) = 20;
It can be done by:
c.x = [a.x; b.x];
c.y = [a.y; b.y;];
However, if the variables have lots of fields,
a.x1 = 1;
a.x2 = 2;
% Lots of fields here
a.x100 = 100;
It's a waste of time to write such a code. Is there any good way to do this?
This function does what you want, but has no error checking:
function C = cat_struct(A, B)
C = struct();
for f = fieldnames(A)'
C.(f{1}) = [A.(f{1}); B.(f{1})];
end
You would use it like this in your code above:
c = cat_struct(a, b);
If all contents are numbers, or row vectors of the same size, it can be done without loops:
f = fieldnames(a);
t = [f mat2cell(cell2mat([struct2cell(a) struct2cell(b)]), ones(1,numel(f)))].';
c = struct(t{:});
The idea here is to generate a cell array of strings (t) such that when expanded to a comma-separated list (t{:}) it will generate the input arguments to struct necessary to build c.
Example:
a.x = [1 1]; a.y = [2 2]; a.z = [3 3];
b.x = [10 100]; b.y = [20 200]; b.z = [30 300];
gives
c =
x: [1 1 10 100]
y: [2 2 20 200]
z: [3 3 30 300]
I am trying to write a function which performs Gaussian elimination with scaled row pivoting. I almost have it right, but my answer is not quite correct, so something must be wrong in my code. I have written:
function [B,h] = factorization(A)
n = length(A);
p = zeros(1,n);
s = zeros(1,n);
for i = 1:n
p(i) = i;
s(i) = max(abs(A(i,1:n)));
end
for k = 1:(n-1)
m = abs(A(k:n,k));
q = length(m);
v = zeros(1,q);
w = s(k:n);
for j = 1:q
v(j) = m(j)/(w(j));
end
[pivot,pivot] = max(abs(v(1:end)));
if pivot ~= 1
var = p(k);
p(k) = p(pivot);
p(pivot) = var;
end
for i = (k+1):n
z = A(p(i),k)/A(p(k),k);
A(p(i),k) = z;
for j = (k+1):n
A(p(i),j) = A(p(i),j) - z*A(p(k),j);
end
end
end
B = A;
h = p;
Say then that I use the matrix A = [2 3 -6; 1 -6 8; 3 -2 1] as input. My code gives me the output: B = [0.6667 -0.8125 -0.4375; 0.3333 -5.3333 7.6667; 3 -2 1], h = [3 2 1]. The correct answer, however, should be: B = [0.0007 4.3333 -6.6667; 0.3333 -1.2308 -0.5385; 3 -2 1], h = [3 1 2]
I can't see where in the code I'm doing wrong, so if anyone could help me out, I would be very grateful!