How to create a constant vector by variant arrays of numbers? - matlab

I have a vector ("d") which I want to place it's content to a matrix ("dis"), I have the problem to create "dis" matrix. "dis" should be like
dis=[
1 2 3 4 5 6 7 8 9 10 11 12
0 1 2 3 4 5 6 7 8 9 10 11
0 0 1 2 3 4 5 6 7 8 9 10
0 0 0 1 2 3 4 5 6 7 8 9
0 0 0 0 1 2 3 4 5 6 7 8
0 0 0 0 0 1 2 3 4 5 6 7
0 0 0 0 0 0 1 2 3 4 5 6
0 0 0 0 0 0 0 1 2 3 4 5
0 0 0 0 0 0 0 0 1 2 3 4
0 0 0 0 0 0 0 0 0 1 2 3
0 0 0 0 0 0 0 0 0 0 1 2
0 0 0 0 0 0 0 0 0 0 0 1];
n=[0,0;1,0;2,0;3,0;4,0;5,0;6,0;7,0;8,0;9,0;10,0;11,0;12,0];
d=pdist(n,'euclidean');
l=length(n)-1;
dis=[];
for k=1:length(n)-1
dis=[dis;d((k-1)*l-(k*((k-1)/2))+k):d(k*l-((k+1)*k/2)+k)];
end

The problem is that you are not padding dis with the zeros.
You can replace
dis=[];
for k=1:length(n)-1
dis=[dis;d((k-1)*l-(k*((k-1)/2))+k):d(k*l-((k+1)*k/2)+k)];
end
with
dis = zeros(l);
for k=1:l
dis(k,k:end) = d((k-1)*l-(k*((k-1)/2))+k):d(k*l-((k+1)*k/2)+k)
end

Using squareform form #beaker comment above, you can write:
dis = triu(squareform(d));
dis = dis(1:length(dis)-1,2:length(dis));
Does this solves the problem?

Related

using maltab to plot a matrix

I have a matrix. The entries are all integers. For example, my matrix would look like this
M = 1 1 1 2 2 2 2 3 3
1 1 1 2 2 2 2 3 0
4 4 4 5 5 5 5 0 0
4 4 4 5 5 5 0 0 0
4 4 4 5 5 0 0 0 0
4 4 4 5 0 0 0 0 0
6 6 6 0 0 0 0 0 0
6 6 0 0 0 0 0 0 0
6 0 0 0 0 0 0 0 0
I wonder if matlab has some neat function to plot the boundary of these sets generated by this matrix?
I think you are looking for a variation of contour plot. Don't forget that it will flip Y axis.
contour(M)
g = gca;
g.YDir = 'reverse';
for jj=1:size(M,1)
for ii=1:size(M,2)
text(jj,ii,num2str(M(ii,jj)));
end
end

How to use points data plot a colorful area?

I have an array, data, in MATLAB just like following:
data = [0 0 0 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1;
0 0 0 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1;
0 0 0 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1;
0 0 0 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1;
0 0 0 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1;
0 0 0 3 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1;
0 0 0 0 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1;
0 0 0 0 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1;
0 0 0 0 3 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1;
0 0 0 0 3 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1;
0 0 0 0 3 3 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1;
0 0 0 0 3 3 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1;
0 0 0 0 3 3 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1;
0 0 0 0 0 3 3 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1;
0 0 0 0 0 3 3 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1;
0 0 0 0 0 3 3 3 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1;
0 0 0 0 0 3 3 3 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1;
0 0 0 0 0 3 3 3 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1;
0 0 0 0 0 0 3 3 3 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1;
0 0 0 0 0 0 3 3 3 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1;
0 0 0 0 0 0 3 3 3 3 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 1 1 1 1;
0 0 0 0 0 0 3 3 3 3 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 1 1 1 1;
0 0 0 0 0 0 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 1 1 1];
Numbers in this matrix stand for color. For example:
1 → red
0 → white
it not must be these colors, anyway,
different number → different color
I want to show on a two-dimensional plane.
I use for environment plot points (but these are discrete points, not a region).
If I use surf(data), it will have a 3D plot:
I can rotate this 3D plot and view above, just like:
This image is what I want plot on 2D plane.
Is there any way to plot on a 2D plane directly?
You may want a contour plot. You can get this by:
[X, Y] = meshgrid(1:size(data,2), 1:size(data,1));
contourf(X,Y,data);
For a more square and distinct look you could try:
scatter(reshape(X,[],1), reshape(Y,[],1), 1200, reshape(data,[1],1), 'square', 'filled');
axis equal
However, this solution requires that you to trial-and-error the size (1200) which will be dependent on the screen size of your plot.
Finally, in newer Matlab versions (R2017b+) you may use heatmap for these types of plots (https://se.mathworks.com/help/matlab/ref/heatmap.html) E.g.:
heatmap(data, 'CellLabelColor', 'none')

Finding the non-intersecting rows in a matrix

I want to find the non-intersecting rows in a large matrix. As an example:
A=[1 5 3; 3 4 5; 7 9 10;4 5 6;11 2 8; 3 5 10]
In this matrix, the non-intersecting rows are: [1 5 3], [11 2 8] and [7 9 10]. How can I program this in Matlab in a fast way?
If I may bsxfun -
M = squeeze(any(bsxfun(#eq,A,permute(unique(A),[3 2 1])),2))
[~,row_idx] = max(M,[],1)
out = A(sum(M,2).' == histc(row_idx,1:size(A,1)),:)
Sample step-by-step run -
A =
1 5 3
3 4 5
7 9 10
4 5 6
11 2 8
3 5 10
M =
1 0 1 0 1 0 0 0 0 0 0
0 0 1 1 1 0 0 0 0 0 0
0 0 0 0 0 0 1 0 1 1 0
0 0 0 1 1 1 0 0 0 0 0
0 1 0 0 0 0 0 1 0 0 1
0 0 1 0 1 0 0 0 0 1 0
row_idx =
1 5 1 2 1 4 3 5 3 3 5
out =
1 5 3
7 9 10
11 2 8
You can look for rows that adding them to union of previous rows increases the number of elements in the union by the number of columns (i.e. all elements in that row are new):
B = [];
C = zeros(1,size(A,1));
for k=1:size(A,1),
B1 = union(B, A(k,:));
C(k) = numel(B1)-numel(B);
B=B1;
end
result = A(C==size(A,2),:);

Concatenating binary bits into a number

I want to concatenate last four bits of binary into a number i have tried the following code
x8=magic(4)
x8_n=dec2bin(x8)
m=x8_n-'0'
which gives me the following output
m =
1 0 0 0 0
0 0 1 0 1
0 1 0 0 1
0 0 1 0 0
0 0 0 1 0
0 1 0 1 1
0 0 1 1 1
0 1 1 1 0
0 0 0 1 1
0 1 0 1 0
0 0 1 1 0
0 1 1 1 1
0 1 1 0 1
0 1 0 0 0
0 1 1 0 0
0 0 0 0 1
now i want to take every last 4 bits it each row and convert it into an integer
n = 4; %// number of bits you want
result = m(:,end-n+1:end) * pow2(n-1:-1:0).'; %'// matrix multiplication
Anyway, it would be easier to use mod on x8 directly, without the intermediate step of m:
result = mod(x8(:), 2^n);
In your example:
result =
0
5
9
4
2
11
7
14
3
10
6
15
13
8
12
1
This could be another approach -
n = 4; %%// number of bits you want
out = bin2dec(num2str(m(:,end-n+1:end)))
Output -
out =
0
5
9
4
2
11
7
14
3
10
6
15
13
8
12
1

read data and save it in a single matrix

i have below .dat file, i want matlab reads data in the 'REQUESTS/DURATIONS:' part and save them in a single matrix in size (32,7). i don't know which function to use ,i don't know how to do it. please help me.
file with basedata : j30_17.bas
initial value random generator: 79602564
projects : 1
jobs (incl. supersource/sink ): 32
horizon : 141
RESOURCES
- renewable : 4 R
- nonrenewable : 0 N
- doubly constrained : 0 D
REQUESTS/DURATIONS:
jobnr. mode duration R 1 R 2 R 3 R 4
------------------------------------------------------------------------
1 1 0 0 0 0 0
2 1 1 0 0 0 5
3 1 1 0 3 0 0
4 1 1 8 0 0 0
5 1 7 0 0 2 0
6 1 6 0 0 0 3
7 1 4 1 0 0 0
8 1 5 0 0 10 0
9 1 8 0 0 3 0
10 1 7 0 0 0 1
11 1 8 9 0 0 0
12 1 1 7 0 0 0
13 1 2 0 3 0 0
14 1 3 0 0 0 6
15 1 10 0 7 0 0
16 1 10 3 0 0 0
17 1 2 0 0 3 0
18 1 10 0 0 4 0
19 1 1 0 0 0 3
20 1 1 0 0 7 0
21 1 7 0 2 0 0
22 1 9 0 0 0 10
23 1 9 0 0 7 0
24 1 4 0 4 0 0
25 1 4 0 3 0 0
26 1 1 0 0 4 0
27 1 1 9 0 0 0
28 1 8 0 0 0 9
29 1 1 0 0 0 1
30 1 2 0 8 0 0
31 1 7 0 4 0 0
32 1 0 0 0 0 0
************************************************************************
RESOURCEAVAILABILITIES:
R 1 R 2 R 3 R 4
10 8 13 12
************************************************************************
If you skip the header, textscan() will stop reading the file once the actual type of data does not correspond to the one specified in format, i.e. when all those asterisks begin:
fid = fopen('C:\...\test.txt');
data = textscan(fid, '%f%f%f%f%f%f%f','HeaderLines',15);
fclose(fid);
I'm not sure about older versions, but 2013a can import text files by right clicking a file under the "Current Folder" panel and selecting "Import Data...". The import wizard will open up and allow you to select the range of data to import. Select the matrix option, and click "Import Selection."
To save your matrix, just use the save command.
This approach works well for single files that you just need to read quickly, but not for a large repetetive task.