Indexing inside a nested loop in matlab - matlab

I would like to create a matrix to hold the result of functions in a nested loop as follow:
list = [0.01; 0.03; 0.1; 0.3; 1; 3; 10; 30];
res = zeros((size(list,1)),(size(list,1)));
for i = list
for j = list
res(i,j)=function(depending on i and j values from the list) goes
here); % This is the part where I need help
end
end
Because list contains real numbers the indexing res(i,j) doesn't work. Cn anyone give me an idea on how to proceed?
Thanks in advance.

All the suggested comments (working with indexes in a nested for) are valid for this answer, I will also recommend use something like this, the operation that you need is something simimlar to apply to a function to de cartesian product of the list so you can work as follow:
>> [X,Y] = meshgrid(list,list);
>> abs(X - Y)
ans =
0 0.0200 0.0900 0.2900 0.9900 2.9900 9.9900 29.9900
0.0200 0 0.0700 0.2700 0.9700 2.9700 9.9700 29.9700
0.0900 0.0700 0 0.2000 0.9000 2.9000 9.9000 29.9000
0.2900 0.2700 0.2000 0 0.7000 2.7000 9.7000 29.7000
0.9900 0.9700 0.9000 0.7000 0 2.0000 9.0000 29.0000
2.9900 2.9700 2.9000 2.7000 2.0000 0 7.0000 27.0000
9.9900 9.9700 9.9000 9.7000 9.0000 7.0000 0 20.0000
29.9900 29.9700 29.9000 29.7000 29.0000 27.0000 20.0000 0

Related

How to make a third matrix with exclusive values from two other matrices, with multiple columns?

I am trying to make a new matrix of n rows and 7 columns, but my code only outputs the first column.
%sample values
table_a = [161.0972 11.0000 14.0000 1.0000 0 0 0;
163.0401 9.0000 8.0000 3.0000 0 0 0;
163.0765 10.0000 12.0000 2.0000 0 0 0;
163.1129 11.0000 16.0000 1.0000 0 0 0;
165.0194 8.0000 6.0000 4.0000 0 0 0;
165.0558 9.0000 10.0000 3.0000 0 0 0;
165.0922 10.0000 14.0000 2.0000 0 0 0]
table_b = [163.0401 9.0000 8.0000 3.0000 0 0 0;
163.0765 10.0000 12.0000 2.0000 0 0 0;
165.0558 9.0000 10.0000 3.0000 0 0 0;
165.0922 10.0000 14.0000 2.0000 0 0 0;
167.0350 8.0000 8.0000 4.0000 0 0 0;
167.0714 9.0000 12.0000 3.0000 0 0 0;
169.0143 7.0000 6.0000 5.0000 0 0 0]
table_c = table_a(~ismember(table_a(:, 1:7), table_b(:, 1:7)));
This is what I yield:
table_c =
163.0401
163.0765
165.0922
This is what I expect to yield:
table_c =
163.0401 9.0000 8.0000 3.0000 0 0 0
163.0765 10.0000 12.0000 2.0000 0 0 0
165.0922 10.0000 14.0000 2.0000 0 0 0
Your code currently does this:
filter = ~ismember(table_a(:, 1:7), table_b(:, 1:7));
table_c = table_a(filter);
This selects all table_a(x) that have filter(x) = true.
You want to select the rows of table_a that fulfill the condition, but select all columns of those rows.
To do this, you have to tell Matlab to select those rows, and all columns of table_a
table_c = table_a(filter, :);
Or in one line,
table_c = table_a(~ismember(table_a(:, 1:7), table_b(:, 1:7)), :);
To clarify, Matlab stores its 2D arrays as column-major arrays. With a matrix
A = [0, 1, 2;
3, 4, 5;
6, 7, 8];
A(i) selects the ith element in the column-major-ordered array, so A(4) would give you 1. A(i, j) selects the ith row and jth column of the matrix.

Matrix being divided by a value unexpectedly

Just working on multiply 2 rows of a matrix and making the answer another row within the same matrix. However when putting the new row in the matrix all of the values are for some reason divided by 1.0e+03.
X = (M(1,1:5) .* M(2,1:5));
M(3,1:5) = X(1,1:5)
disp(X)
Actual Result
X =
1.0e+03 *
0.4000 0.5500 0.7000 0.5000 0.6000
0.0030 0.0005 0.0008 0.0015 0.0050
1.2000 0.2750 0.5250 0.7500 3.0000
Expected Result
400.0000 550.0000 700.0000 500.0000 600.0000
3.0000 0.5000 0.7500 1.5000 5.0000
1200 275 525 750 3000

Solve System of Linear Equations in MatLab with Matrix of Arbitrary Size for Finite Difference Calculation

I am trying to write a script in MatLab R2016a that can solve a system of linear equations that can have different sizes depending on the values of p and Q.
I have the following equations that I am trying to solve, where h=[-p:1:p]*dx. Obviously, there is some index m where h=0, but that shouldn't be a problem.
I'm trying to write a function where I can input p and Q and build the matrix and then just solve it to get the coefficients. Is there a way to build a matrix using the variables p, Q, and h instead of using different integer values for each individual case?
I would use bsxfun(in recent matlab versions this function may be implented to the interpreter, I don't know for sure):
p = 4;
Q = 8;
dx = 1;
h = -p:p*dx
Qvector = [Q,1:Q-1]'
Matrix = bsxfun(#(Qvector, h)h.^(Qvector)./factorial(Qvector), Qvector, h)
Output:
h =
-4 -3 -2 -1 0 1 2 3 4
Qvector =
8
1
2
3
4
5
6
7
Matrix =
1.6254 0.1627 0.0063 0.0000 0 0.0000 0.0063 0.1627 1.6254
-4.0000 -3.0000 -2.0000 -1.0000 0 1.0000 2.0000 3.0000 4.0000
8.0000 4.5000 2.0000 0.5000 0 0.5000 2.0000 4.5000 8.0000
-10.6667 -4.5000 -1.3333 -0.1667 0 0.1667 1.3333 4.5000 10.6667
10.6667 3.3750 0.6667 0.0417 0 0.0417 0.6667 3.3750 10.6667
-8.5333 -2.0250 -0.2667 -0.0083 0 0.0083 0.2667 2.0250 8.5333
5.6889 1.0125 0.0889 0.0014 0 0.0014 0.0889 1.0125 5.6889
-3.2508 -0.4339 -0.0254 -0.0002 0 0.0002 0.0254 0.4339 3.2508

Summing cumulative area under curves of overapping triangles

I have two matrices for several triangles:
x =
2.0000 5.0000 10.0000
8.0000 10.0000 12.0000
12.0000 24.0000 26.0000
22.0000 25.0000 28.0000
23.0000 26.0000 25.0000
23.5000 27.0000 27.5000
20.0000 23.0000 27.0000
21.0000 24.0000 27.0000
24.0000 25.0000 27.0000
24.0000 26.0000 27.0000
24.0000 28.0000 29.0000
19.0000 22.0000 25.0000
18.0000 21.0000 23.0000
y =
0 1.0000 0
0 0.8000 0
0 0.6000 0
0 0.8000 0
0 0.8000 0
0 0.8000 0
0 1.0000 0
0 1.0000 0
0 1.0000 0
0 1.0000 0
0 1.0000 0
0 1.0000 0
0 1.0000 0
one line is one triangle. Columns are x and y positions of each point of the triangles.
So, I plot all these triangles and I need to sum the cumulative area under the curve of the triangles.
I try to use the area function, but I couldn't find how to sum their areas.
EDIT: I need to plot the sum of the areas on a red line in the same graphics. So I don't want a number like 20 cm²... I would like something like that:
I suggest that you interpolate to create all your individual triangles and then add the results. First you will need to augment your x and y matrices with the beginning (the origin) and end points like so:
m = 30; %// This is your max point, maybe set it using max(x(:))?
X = [zeros(size(x,1),1), x, ones(size(x,1),1)*m];
Y = [zeros(size(y,1),1), y, zeros(size(y,1),1)];
then perform all the interpolations (I'll sum as I go):
xi = 0:0.1:m;
A = zeros(1,size(xi,2)); %// initialization
for row = 1:size(x,1)
A = A + interp1(X(row,:), Y(row,:), xi);
end
and finally plot:
plot(x,y,'k')
hold on
plot(xi,A,'r','linewidth',2)
using your example data this gives:

Indexing during assignment

Say I have this sample data
A =
1.0000 6.0000 180.0000 12.0000
1.0000 5.9200 190.0000 11.0000
1.0000 5.5800 170.0000 12.0000
1.0000 5.9200 165.0000 10.0000
2.0000 5.0000 100.0000 6.0000
2.0000 5.5000 150.0000 8.0000
2.0000 5.4200 130.0000 7.0000
2.0000 5.7500 150.0000 9.0000
I wish to calculate the variance of each column, grouped by class (the first column).
I have this working with the following code, but it uses hard coded indices, requiring knowledge of the number of samples per class and they must be in specific order.
Is there a better way to do this?
variances = zeros(2,4);
variances = [1.0 var(A(1:4,2)), var(A(1:4,3)), var(A(1:4,4));
2.0 var(A(5:8,2)), var(A(5:8,3)), var(A(5:8,4))];
disp(variances);
1.0 3.5033e-02 1.2292e+02 9.1667e-01
2.0 9.7225e-02 5.5833e+02 1.6667e+00
Separate the class labels and the data into different variables.
cls = A(:, 1);
data = A(:, 2:end);
Get the list of class labels
labels = unique(cls);
Compute the variances
variances = zeros(length(labels), 3);
for i = 1:length(labels)
variances(i, :) = var(data(cls == labels(i), :)); % note the use of logical indexing
end
I've done a fair bit of this type of stuff over the years, but to be able to judge, better vs. best, it would help to know what you expect to change in the data set or structure.
Otherwise, if no change is anticipated and the hard code works, stick with it.
Easy, peasy. Use consolidator. It is on the file exchange.
A = [1.0000 6.0000 180.0000 12.0000
1.0000 5.9200 190.0000 11.0000
1.0000 5.5800 170.0000 12.0000
1.0000 5.9200 165.0000 10.0000
2.0000 5.0000 100.0000 6.0000
2.0000 5.5000 150.0000 8.0000
2.0000 5.4200 130.0000 7.0000
2.0000 5.7500 150.0000 9.0000];
[C1,var234] = consolidator(A(:,1),A(:,2:4),#var)
C1 =
1
2
var234 =
0.035033 122.92 0.91667
0.097225 558.33 1.6667
We can test the variances produced, since we know the grouping.
var(A(1:4,2:4))
ans =
0.035033 122.92 0.91667
var(A(5:8,2:4))
ans =
0.097225 558.33 1.6667
It is efficient too.