Tallying co-incidences of numbers in columns of a matrix - MATLAB - matlab

I have a matrix (A) in the form of (much larger in reality):
205 204 201
202 208 202
How can I tally the co-incidence of numbers on a column-by-column basis and then output this to a matrix?
I'd want the final matrix to run from min(A):max(A) (or be able to specify a specific range) across the top and down the side and for it to tally co-incidences of numbers in each column. Using the above example:
200 201 202 203 204 205 206 207 208
200 0 0 0 0 0 0 0 0 0
201 0 0 1 0 0 0 0 0 0
202 0 0 0 0 0 1 0 0 0
203 0 0 0 0 0 0 0 0 0
204 0 0 0 0 0 0 0 0 1
205 0 0 0 0 0 0 0 0 0
206 0 0 0 0 0 0 0 0 0
207 0 0 0 0 0 0 0 0 0
208 0 0 0 0 0 0 0 0 0
(Matrix labels are not required)
Two important points: The tallying needs to be non-duplicating and occur in numerical order. For example a column containing:
205
202
Will tally this as a 202 occurring with 205 (as shown in the above matrix) but NOT 205 with 202 - the duplicate reciprocal. When deciding what number to use as the reference, it should be the smallest.
EDIT:

sparse to the rescue!
Let your data and desired range be defined as
A = [ 205 204 201
202 208 202 ]; %// data. Two-row matrix
limits = [200 208]; %// desired range. It needn't include all values of A
Then
lim1 = limits(1)-1;
s = limits(2)-lim1;
cols = all((A>=limits(1)) & (A<=limits(2)), 1);
B = sort(A(:,cols), 1, 'descend')-lim1;
R = full(sparse(B(2,:), B(1,:), 1, s, s));
gives
R =
0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
Alternatively, you can dispense with sort and use matrix addition followed by triu to obtain the same result (possibly faster):
lim1 = limits(1)-1;
s = limits(2)-lim1;
cols = all( (A>=limits(1)) & (A<=limits(2)) , 1);
R = full(sparse(A(2,cols)-lim1, A(1,cols)-lim1, 1, s, s));
R = triu(R + R.');
Both approaches handle repeated columns (up to sorting), correctly increasing their tally. For example,
A = [205 204 201
201 208 205]
gives
R =
0 0 0 0 0 0 0 0 0
0 0 0 0 0 2 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0

See if this is what you were after -
range1 = 200:208 %// Set the range
A = A(:,all(A>=min(range1)) & all(A<=max(range1))) %// select A with columns
%// that fall within range1
A_off = A-range1(1)+1 %// Get the offsetted indices from A
A_off_sort = sort(A_off,1) %// sort offset indices to satisfy "smallest" criteria
out = zeros(numel(range1)); %// storage for output matrix
idx = sub2ind(size(out),A_off_sort(1,:),A_off_sort(2,:)) %// get the indices to be set
unqidx = unique(idx)
out(unqidx) = histc(idx,unqidx) %// set coincidences
With
A = [205 204 201
201 208 205]
this gets -
out =
0 0 0 0 0 0 0 0 0
0 0 0 0 0 2 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
Few performance-oriented tricks could be used here -
I. Replace
out = zeros(numel(range1));
with
out(numel(range1),numel(range1)) = 0;
II. Replace
idx = sub2ind(size(out),A_off_sort(1,:),A_off_sort(2,:))
with
idx = (A_off_sort(2,:)-1)*numel(range1)+A_off_sort(1,:)

What about a solution using accumarray? I would first sort each column independently, then use the first row as first dimension into the final accumulation matrix, then the second row as the second dimension into the final accumulation matrix. Something like:
limits = 200:208;
A = A(:,all(A>=min(limits)) & all(A<=max(limits))); %// Borrowed from Divakar
%// Sort the columns individually and bring down to 1-indexing
B = sort(A, 1) - limits(1) + 1;
%// Create co-occurrence matrix
C = accumarray(B.', 1, [numel(limits) numel(limits)]);
With:
A = [205 204 201
202 208 202]
This is the output:
C =
0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
With duplicates (borrowed from Luis Mendo):
A = [205 204 201
201 208 205]
Output:
C =
0 0 0 0 0 0 0 0 0
0 0 0 0 0 2 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0

Related

How to draw 2 merging trees using an adjacency matrix in Matlab

I have an adjacency matrix describing two trees that merges in the middle. An exemple for 10 nodes:
The corresponding adjacency matrix is a 10x10 matrix where the first row correspond to the first node (start of the first tree, node #1) and the last row to the root of the second tree (end of the second tree, node #10).
Here is the adjacency matrix corresponding to a larger example with 22 nodes:
0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0
I'm trying to plot this adjacency matrix as the picture showed above using Matlab. Matlab as some tools for plotting trees, for example the code given in:
https://blogs.mathworks.com/cleve/2017/03/20/morse-code-binary-trees-and-graphs/
However, using the previous matrix (let's label it 'A') and the following code:
G = digraph(A);
Gp = plot(G);
does not produce a tree, but a graph (not ordered as a tree).
Thus, how to produce a picture of a tree (as showed above) using 'A' in Matlab?
Please note that I also have matrices describing trees where the degree between the children nodes are 3 (or more) rather than 2.
Zero-out half of your adjacency matrix to make the connection one-way.
By default, MATLAB tries to decide the layout of graphs automatically, based on the structure of your graph. There are a few different graph layouts you can choose from.
The option you wanted is the 'Layered' layout; but I tested it with your example, and it definitely still doesn't look like a tree. The reason being that your adjacency matrix is symmetrical, and the connection is two-way. This confuses MATLAB when placing the nodes, and it doesn't think it's a tree.
The easy fix, is you can zero-out the lower triangular half of your adjacency matrix. I used the function tril for this.
% Create a lower triangular matrix with the dimension of A,
idx = tril(ones(size(A)));
% Make it a logical array to select matrix elements with
idx = logical(idx);
% Select the defined lower triangular part, and set that to zero
A(idx) = 0;
% Generate-Plot graph as you did
G = digraph(A);
plot(G)
Result

Avoid restarting for-loop

I have a folder with pictures. For each picture, I want to take the maximum value and add it to a new matrix (I created a zeros-matrix, so the zeroes will be replaced with the new values).
This is my code:
function handles = original(hObject, eventdata, handles)
handles.weed=handles.selected;
pic=imread(handles.me);
handles.pic=pic;
axes(handles.axes1)
imshow(pic);
num=max(pic(:))
zeroMat = zeros(1,70);
handles.zeroMat = zeroMat;
for i =1:3
if zeroMat(1,i)~= 0;
i=i+1
else
zeroMat(1,i)=num
break
end
end
zeroMat(1,i)=num
Every time I select a new picture, the zeromat restarts itself to a new zeros-matrix. I know why it happens, but unfortunately I don't know how to overcome it.
This is the output:
pic1:
zeroMat =
Columns 1 through 20
255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Columns 21 through 40
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Columns 41 through 60
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Columns 61 through 70
0 0 0 0 0 0 0 0 0 0
pic2:
Columns 1 through 20
203 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Columns 21 through 40
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Columns 41 through 60
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Columns 61 through 70
0 0 0 0 0 0 0 0 0 0
I can't tell how this function is being invoked, so can't advice how to change up the logic. A rough fix could be to include the line
if ~isfield(handles,'zeroMat')
handles.zeroMat = zeros(1,70);
end % if
which should create handles.zeroMat the first time the function is run. You could then do something like
firstNonzero = find(handles.zeroMat > 0, 1, 'first'); % 'first' not needed, default
handles.zeroMat(firstNonzero) = max(pic(:));

Read from a file into a vector in matlab using importdata()

My input file looks like this:
# FILE:app/src/f1.c
2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 24 32 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
# FILE:src/f2.c
1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 24 31 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
...............
I want to read the headers i.e., the lines which start with #, and the vectors present below the headers into lists. I tried the using importdata() as below. But this gives me only the first header and first vector. I need to read it till the end of the file.
filename = 'output.txt';
A = importdata(filename);
disp(A.rowheaders);
disp(A.data);
EDIT: A = importdata(filename,'#'); This solved my problem
I believe the fgetl command should do the trick.
I would put it in a for loop with two fgetl commands, one for the metadata line and one for the numerical data line.
EDIT: Added example
fid = fopen('test.txt');
celHeaders = {};
celData = {};
while(~feof(fid))
celHeaders{end+1} = fgetl(fid);
celData{end+1} = fgetl(fid);
end
fclose(fid);
disp(celHeaders)
disp(celData)
This is assuming that your text file doesn't include additional lines above or below the data.

Numerical errors when solving Ax=b in MATLAB

I am attempting to solve the system Ax = b in MATLAB, where A is a 30x30 triangular matrix with (nonzero) values ranging from 1e-14 to 0.7, and b is a 30-element column vector with values ranging from 1e-3 to 1e3. When I enter x = A\b, I get an answer and no warning messages, but the answer is not reasonable (looks like just random numbers at the bottom of the vector). I presume this is due to numerical errors.
Message 5 on this page suggests decomposing/scaling the matrix in order to avoid numerical errors, but I haven't been able to figure out how to calculate the scaling matrices.
So the question is: Is this indeed an example of numerical instability, and if so, how can I rescale my matrix A, or change how MATLAB is performing the calculation, to avoid it?
Here is the matrix and vector that are producing the issue:
A =
Columns 1 through 15
0.69 0.4278 0.19893 0.082223 0.031861 0.011852 0.0042866 0.0015187 0.00052965 0.00018243 6.221e-05 2.1038e-05 7.0653e-06 2.3587e-06 7.8344e-07
0 0.4761 0.44277 0.27452 0.14183 0.065953 0.028624 0.011831 0.0047156 0.0018273 0.00069233 0.00025755 9.4356e-05 3.4126e-05 1.2206e-05
0 0 0.32851 0.40735 0.3157 0.19573 0.10618 0.052668 0.02449 0.010846 0.004623 0.0019108 0.00077007 0.00030383 0.00011773
0 0 0 0.22667 0.35134 0.32675 0.23635 0.14653 0.081766 0.042246 0.02058 0.0095696 0.0042851 0.0018597 0.00078615
0 0 0 0 0.1564 0.29091 0.31564 0.26093 0.182 0.11284 0.064129 0.03408 0.017168 0.0082788 0.0038496
0 0 0 0 0 0.10792 0.23418 0.29039 0.27006 0.2093 0.14274 0.088499 0.05095 0.02764 0.014281
0 0 0 0 0 0 0.074464 0.18467 0.25761 0.2662 0.22694 0.16884 0.1134 0.070311 0.040868
0 0 0 0 0 0 0 0.05138 0.14335 0.22219 0.25256 0.23488 0.18931 0.13694 0.090965
0 0 0 0 0 0 0 0 0.035452 0.1099 0.18738 0.23235 0.2341 0.2032 0.15748
0 0 0 0 0 0 0 0 0 0.024462 0.083415 0.15515 0.20842 0.22614 0.21031
0 0 0 0 0 0 0 0 0 0 0.016879 0.062789 0.12652 0.18303 0.21277
0 0 0 0 0 0 0 0 0 0 0 0.011646 0.046935 0.10185 0.15786
0 0 0 0 0 0 0 0 0 0 0 0 0.008036 0.034876 0.081087
0 0 0 0 0 0 0 0 0 0 0 0 0 0.0055448 0.025783
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0038259
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Columns 16 through 30
2.5906e-07 8.5327e-08 2.8007e-08 9.1646e-09 2.9906e-09 9.7342e-10 3.1613e-10 1.0246e-10 3.3142e-11 1.0702e-11 3.4504e-12 1.1108e-12 3.5709e-13 1.1465e-13 3.6767e-14
4.3246e-06 1.5194e-06 5.2988e-07 1.8359e-07 6.3236e-08 2.1667e-08 7.3883e-09 2.5085e-09 8.4833e-10 2.8585e-10 9.5998e-11 3.214e-11 1.073e-11 3.5726e-12 1.1866e-12
4.492e-05 1.6909e-05 6.2902e-06 2.3156e-06 8.445e-07 3.0543e-07 1.0963e-07 3.9084e-08 1.3847e-08 4.8779e-09 1.7094e-09 5.9615e-10 2.0698e-10 7.1568e-11 2.4651e-11
0.00032494 0.00013173 5.2503e-05 2.0616e-05 7.9887e-06 3.0592e-06 1.1591e-06 4.3497e-07 1.6181e-07 5.9715e-08 2.1877e-08 7.9615e-09 2.8794e-09 1.0354e-09 3.7037e-10
0.0017358 0.00076232 0.00032721 0.00013766 5.69e-05 2.3151e-05 9.2878e-06 3.679e-06 1.4406e-06 5.5824e-07 2.1426e-07 8.1515e-08 3.0763e-08 1.1523e-08 4.2867e-09
0.0070833 0.0033935 0.001578 0.00071495 0.00031662 0.00013741 5.8573e-05 2.4566e-05 1.0154e-05 4.1418e-06 1.6691e-06 6.6527e-07 2.6248e-07 1.0259e-07 3.9755e-08
0.022523 0.01187 0.0060211 0.0029554 0.0014095 0.00065541 0.00029799 0.00013279 5.8116e-05 2.5022e-05 1.0615e-05 4.4423e-06 1.8361e-06 7.5031e-07 3.0339e-07
0.056398 0.033024 0.018428 0.0098671 0.005098 0.0025529 0.0012436 0.00059114 0.00027488 0.00012531 5.6113e-05 2.4719e-05 1.0728e-05 4.5926e-06 1.9414e-06
0.11158 0.073506 0.045573 0.026843 0.01513 0.0082078 0.0043059 0.0021929 0.0010877 0.00052686 0.00024979 0.00011615 5.3064e-05 2.3852e-05 1.0563e-05
0.17385 0.13089 0.091294 0.059747 0.037043 0.021923 0.012459 0.0068335 0.0036315 0.0018763 0.00094518 0.00046536 0.00022441 0.00010618 4.9374e-05
0.21107 0.18539 0.14778 0.10881 0.074955 0.048796 0.030253 0.017976 0.010288 0.0056949 0.0030601 0.0016008 0.00081734 0.00040822 0.00019981
0.19575 0.20632 0.19188 0.16145 0.12513 0.090508 0.061727 0.04001 0.024806 0.014788 0.0085139 0.0047507 0.0025773 0.0013629 0.00070418
0.13406 0.17663 0.19712 0.1935 0.17139 0.13947 0.10569 0.075354 0.050967 0.032916 0.020408 0.012201 0.0070603 0.003967 0.0021702
0.063943 0.11233 0.1567 0.18459 0.19074 0.17739 0.15122 0.1198 0.089133 0.062798 0.042179 0.027157 0.016837 0.010091 0.0058655
0.018977 0.050003 0.093006 0.13695 0.16982 0.18425 0.17952 0.15999 0.13226 0.1025 0.075107 0.052387 0.034978 0.022461 0.013926
0.0026399 0.013912 0.038815 0.076207 0.11812 0.15379 0.17481 0.17806 0.16559 0.14259 0.11493 0.087452 0.063257 0.043745 0.029059
0 0.0018215 0.010164 0.029933 0.061862 0.10068 0.13733 0.16319 0.17345 0.16803 0.15048 0.12595 0.099387 0.074457 0.053266
0 0 0.0012569 0.0074028 0.022949 0.049799 0.084907 0.12108 0.15014 0.16622 0.16747 0.15575 0.13519 0.11049 0.085626
0 0 0 0.00086723 0.0053768 0.017502 0.039787 0.07092 0.10553 0.13631 0.15695 0.16421 0.15837 0.14237 0.12037
0 0 0 0 0.00059839 0.0038955 0.013284 0.031571 0.058722 0.091019 0.12227 0.1462 0.15862 0.15845 0.14736
0 0 0 0 0 0.00041289 0.0028159 0.010039 0.024896 0.048236 0.077756 0.10847 0.1345 0.15115 0.15618
0 0 0 0 0 0 0.00028489 0.0020313 0.0075564 0.019521 0.039334 0.065845 0.095256 0.12234 0.14222
0 0 0 0 0 0 0 0.00019658 0.0014625 0.0056673 0.015226 0.031861 0.05531 0.082873 0.1101
0 0 0 0 0 0 0 0 0.00013564 0.0010512 0.0042363 0.011819 0.025648 0.046115 0.071478
0 0 0 0 0 0 0 0 0 9.359e-05 0.00075433 0.0031569 0.0091339 0.020528 0.038183
0 0 0 0 0 0 0 0 0 0 6.4577e-05 0.00054051 0.0023458 0.0070296 0.016344
0 0 0 0 0 0 0 0 0 0 0 4.4558e-05 0.00038676 0.0017385 0.0053894
0 0 0 0 0 0 0 0 0 0 0 0 3.0745e-05 0.0002764 0.0012852
0 0 0 0 0 0 0 0 0 0 0 0 0 2.1214e-05 0.00019729
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1.4638e-05
b =
3712
246.89
43.304
22.55
14.897
10.066
6.8138
4.6131
3.1232
2.1146
1.4316
0.96927
0.65623
0.44429
0.3008
0.20365
0.13788
0.093351
0.063202
0.04279
0.02897
0.019614
0.013279
0.0089906
0.006087
0.0041211
0.0027902
0.001889
0.0012789
0.00086589
A .mat file with the full-precision variables may be found here.
Here are the results I'm getting on my machine (Matlab R2013a on OS X 10.10.5):
>> x=A\b
x =
5087.6
433.99
64.166
27.995
19.494
14.546
10.934
8.2265
6.1834
4.6933
3.2779
3.8272
-3.5375
23.953
-79.278
254.22
-702.1
1713.2
-3658.2
6822.7
-11046
15412
-18349
18393
-15244
10181
-5273.4
1992.3
-489.85
59.155
Although norm(A*x-b) returns a value on the order of 1e-13, the results are not physically reasonable given the problem I am trying to solve (values in x should be monotonically decreasing, and none should be negative). As an example, here is a similar dataset that returns a correct (looking) solution with the same matrix A:
>> c
c =
5142.1
339.52
22.417
1.4802
0.097731
0.0064529
0.00042607
2.8132e-05
1.8575e-06
1.2265e-07
8.0979e-09
5.3469e-10
3.5304e-11
2.331e-12
1.5391e-13
1.0162e-14
6.7099e-16
4.4304e-17
2.9253e-18
1.9315e-19
1.2753e-20
8.4205e-22
5.5598e-23
3.671e-24
2.4239e-25
1.6004e-26
1.0567e-27
6.9771e-29
4.6068e-30
3.0418e-31
>> x = A\c
x =
7029.1
653.25
60.709
5.642
0.52434
0.04873
0.0045287
0.00042087
3.9114e-05
3.635e-06
3.3782e-07
3.1395e-08
2.9177e-09
2.7116e-10
2.52e-11
2.342e-12
2.1765e-13
2.0227e-14
1.8798e-15
1.747e-16
1.6236e-17
1.5089e-18
1.4023e-19
1.3033e-20
1.21e-21
1.1339e-22
9.9766e-24
1.1858e-24
2.3902e-26
2.078e-26

"""Diagonal""" -1/+1 Matrix

I need to construct the tech cycle constraint matrix Aa and the right side ba. The aim is building the technology cycle matrices in order to solve the scheduling linear problem constrained by Ax<=b. In this case -1 and +1 in A refers to the coefficients of the constraints of the problem such as starting times and precedences
TC = [1,2,3,4,6,7;1,2,5,4,6,7;2,5,6,7,0,0]; % Technology cycle
CT = [100,60,200,160,80,120;100,60,150,120,60,150;50,120,40,30,0,0]; % Cycle time
n_jb = size(TC,1); % number of jobs
n_op = sum(TC~=0,2); % number of operations for each job
N_op = sum(n_op); % total number of operations
c=1; % indice for constraints in Aa
Op=1; % counter for overall operation
n_tf = N_op - n_jb- sum(n_op==1); % number of job transfer between machines (also number of tech cycle constraint numbers)
Aa = zeros(n_tf,N_op); % Constraint matrx for tech cycle
ba = zeros(n_tf,1); % The right vector of the constraint function: Aa*x<=ba
for j=1:n_jb
if n_op(j)>1
for op=1:n_op(j)-1
Aa(c,Op)=-1;
Aa(c,Op+1)=1;
ba(c,1)=CT(j,op);
c=c+1;
Op=Op+1;
end
else
Op=Op+1;
end
Op=Op+1;
end
The output, like Aa is 3 """diagonal""" -1/+1 matrices:
-1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 -1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 -1 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 -1 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 -1 1 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 -1 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 -1 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 -1 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 -1 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 -1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 -1 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1
In order to be more precise in the following there is an image: showing the 3 different part of the matrix Aa. My question is: Is there a way to build the same this avoiding loops since A is not a 3x1 but will definitely become 30-50x1?
You can use diag to create the positive and negative ones. The second input to diag is to shift the diagonal to the side. In this case, 1 to the right.
Use cumsum to find the rows you want to remove. For n = [6, 6, 4], you want to remove the 6th, 12th and 16th row.
n = [6, 6, 4];
cols = sum(n);
A = -eye(cols) + diag(ones(cols-1,1), 1);
A(cumsum(n),:) = []
A =
-1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 -1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 -1 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 -1 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 -1 1 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 -1 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 -1 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 -1 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 -1 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 -1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 -1 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1