Finding the transfer matrix of a system - matrix

I have the following system
Which represent a system of 4 known inputs with 12 known outputs.
What methods can I use to find the transfer matrix, can I use the neural network or something like that or it is only possible with matrix algebra?
Any help would be appreciated
thanks in advance

No need to use neural network, matrix algebra is enough!
Your question can be formulated as an optimization problem, i.e., minimize f(T) = norm(y - T*x) given y and x. If you have sufficient data pairs (x,y), then you can solve T.
Another easy way is to use generalized inverse of matrix to solve the transfer matrix T, i.e., T = Y*ginv(X). Here I will show you an example in language R
library(MASS)
Y <- matrix(1:36,nrow = 9)
X <- matrix(1:16,nrow = 4)
T <- Y %*% ginv(X)
where
> X
[,1] [,2] [,3] [,4]
[1,] 1 5 9 13
[2,] 2 6 10 14
[3,] 3 7 11 15
[4,] 4 8 12 16
> Y
[,1] [,2] [,3] [,4]
[1,] 1 10 19 28
[2,] 2 11 20 29
[3,] 3 12 21 30
[4,] 4 13 22 31
[5,] 5 14 23 32
[6,] 6 15 24 33
[7,] 7 16 25 34
[8,] 8 17 26 35
[9,] 9 18 27 36
and the transfer T is solved as
> T
[,1] [,2] [,3] [,4]
[1,] 1.95 1.025 0.1 -0.825
[2,] 1.65 0.925 0.2 -0.525
[3,] 1.35 0.825 0.3 -0.225
[4,] 1.05 0.725 0.4 0.075
[5,] 0.75 0.625 0.5 0.375
[6,] 0.45 0.525 0.6 0.675
[7,] 0.15 0.425 0.7 0.975
[8,] -0.15 0.325 0.8 1.275
[9,] -0.45 0.225 0.9 1.575
To verify the obtained T, you can use
> norm(Y - T%*%X,"2")
[1] 1.178746e-13
which is close to 0, indicating that the obtained T is valid.

Related

R: summing specific elements in a symmetrical matrix

If I have a correlation matrix, I know I can use upper.tri or lower.tri to sum all values, but is there a way to sum just specific parts of the matrix?
For example, a correlation matrix of 5 variables:
> Matrix
[,1] [,2] [,3] [,4] [,5]
[1,] 0 4 3 1 2
[2,] 4 0 3 2 1
[3,] 3 3 0 2 1
[4,] 1 2 2 0 1
[5,] 2 1 1 1 0
If the first 2 variables belong to one group, while 3-5 belong to another, is there a way to just ask for the sum of the inter-group values? e.g., 3+3+1+2+2+1 = 12.
A long winded answer but hopefully generic one to help you!
matrix <- matrix (c(0,4,3,1,2,4,0,3,2,1,3,3,0,2,1,1,2,2,0,1,2,1,1,1,0), nrow=5, ncol=5)
group <- list(group1=c(1,2), group2=c(3,4,5))
sum_matrix <- matrix(data <- rep(NA), nrow = length(group), ncol= length(group))
for (i in 1:length(group))
{
for(j in 1:length(group))
{
ifelse(i==j, sum_matrix[i,j]<- NA, sum_matrix[i,j] <- sum(matrix[group[[i]], group[[j]] ]) )
}
}
sum_matrix
sum(matrix[group2, group1])
sum(matrix[group1, group2])

R: recursive indexing failed at level 2

I created a list of matrix, I want to be able to apply operations with they, one thing I want to do is combine them using operator like cbin and rbind among others, one way to do it it's the next, but i just want to save the matrixs in the list and apply operations without writing everyone.
'Combinedmatrix<-cbind(elementlist[[1]],...,elementlist[[n]])'
Is there a way to do the same instead writing each element of the list?
I tried the next
'(i in 1:length(list)){combinedmatrix<-cbind(list[[i]])}'
in this case it only takes the last element and do nothing more,
the other way I tried was:
'i<-1:length(list)'
'combinedmatrix<-cbind(list[[i]])}'
in this case appear
'Error in list[[i]] : recursive indexing failed at level 2'
You can use reduce() from the purrr package. Assuming mlist is your list of matrices:
library(purrr)
reduce(mlist,rbind)
With example data:
> mlist <- list(matrix(1:9,nrow=3),matrix(1:9,nrow=3),matrix(1:9,nrow=3))
> mlist
[[1]]
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
[[2]]
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
[[3]]
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
> reduce(mlist,rbind)
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
[4,] 1 4 7
[5,] 2 5 8
[6,] 3 6 9
[7,] 1 4 7
[8,] 2 5 8
[9,] 3 6 9

plot matrix with lines gnuplot

I'm making a chart but I would like to use lines rather than points.
Using the style of lines, all the points are connected and the graph has a network appearance, which I don't want.
set grid
set ticslevel 0.1
set samples 51, 51
set isosamples 20, 20
set border 1+2+4+8
unset key
splot 'matrix.dat' matrix
part of data to matrix plot
0.261 0.665 0.225 0.382 0.255 0.574 0.356
0.338 0.845 0.0363 0.167 0.727 0.0805 0.764
0.225 0.196 0.107 0.153 0.347 0.338 0.168
0.157 0.443 0.0671 0.135 0.312 0.408 0.362
0.151 0.281 0.0572 0.103 0.309 0.49 0.242
0.12 0.336 0.0604 0.173 0.19 0.395 0.153
0.119 0.173 0.0336 0.145 0.156 0.219 0.177
0.123 0.0452 0.0165 0.149 0.0932 0.0663 0.133
0.123 0.0741 0.00373 0.136 0.0346 0.485 0.131
0.111 0.241 0.0124 0.105 0.0127 1.01 0.122
0.096 0.475 0.0194 0.0569 0.0284 1.67 0.102
0.0777 0.773 0.0175 0.00929 0.0375 2.42 0.0831
0.059 1.11 0.0123 0.0322 0.0408 3.23 0.0635
0.0438 1.48 6.44E-4 0.0659 0.0265 4.07 0.0445
0.0349 1.92 0.0192 0.078 0.00585 4.92 0.0254
0.0392 2.42 0.0446 0.0632 0.0306 5.73 0.00774
0.0518 2.97 0.0745 0.031 0.0729 6.46 0.00716
This cannot be done automatically. You must determine the rows and columns of your matrix. First, to get the number of rows, use
stats 'matrix.dat' using 1 nooutput
rows = STATS_records
For the number of columns, use then
stats 'matrix.dat' matrix nooutput
cols = STATS_records/rows
And now plot every line
unset key
splot for [i=0:cols-1] 'matrix.dat' matrix every ::i::i lt 1 with lines
Result (with 4.6.4) is:
I think Christoph's solution is just what you need, but to make the point clear, by providing the matrix and using splot matrix alone will just generate a mesh.
So you will need to specify the lines with complete X, Y and Z vectors and then plot them using splot with lines/linespoints. I'm adding an example below in case it may be helpful for anyone else.
You arrange your data file as follows:
10 1 0.261 2 0.665 3 0.225 4 0.382 5 0.255 6 0.574 7 0.356
20 1 0.338 2 0.845 3 0.0363 4 0.167 5 0.727 6 0.0805 7 0.764
30 1 0.225 2 0.196 3 0.107 4 0.153 5 0.347 6 0.338 7 0.168
40 1 0.157 2 0.443 3 0.0671 4 0.135 5 0.312 6 0.408 7 0.362
And then plot as follows:
set grid
set ticslevel 0.1
#set samples 51, 51
#set isosamples 20, 20
#set border 1+2+4+8
unset key
splot 'matrix.dat' using 1:2:3 with linespoints, \
'matrix.dat' using 1:4:5 with linespoints, \
'matrix.dat' using 1:6:7 with linespoints, \
'matrix.dat' using 1:8:9 with linespoints, \
'matrix.dat' using 1:10:11 with linespoints, \
'matrix.dat' using 1:12:13 with linespoints, \
'matrix.dat' using 1:14:15 with linespoints
With the resultant plot

Filter Data In a Cleaner/More Efficient Way

I have a set of data with a bunch of columns. Something like the following (in reality my data has about half a million rows):
big = [
1 1 0.93 0.58;
1 2 0.40 0.34;
1 3 0.26 0.31;
1 4 0.40 0.26;
2 1 0.60 0.04;
2 2 0.84 0.55;
2 3 0.53 0.72;
2 4 0.00 0.39;
3 1 0.27 0.51;
3 2 0.46 0.18;
3 3 0.61 0.01;
3 4 0.07 0.04;
4 1 0.26 0.43;
4 2 0.77 0.91;
4 3 0.49 0.80;
4 4 0.40 0.55;
5 1 0.77 0.40;
5 2 0.91 0.28;
5 3 0.80 0.65;
5 4 0.05 0.06;
6 1 0.41 0.37;
6 2 0.11 0.87;
6 3 0.78 0.61;
6 4 0.87 0.51
];
Now, let's say I want to get rid of the rows where the first column is a 3 or a 6.
I'm doing that like so:
filterRows = [3 6];
for i = filterRows
big = big(~ismember(1:size(big,1), find(big(:,1) == i)), :);
end
Which works, but the loop makes me think I'm missing a more efficient trick. Is there a better way to do this?
Originally I tried:
big(find(big(:,1) == filterRows ),:) = [];
but of course that doesn't work.
Use logical indexing:
rows = (big(:, 1) == 3 | big(:, 1) == 6);
big(rows, :) = [];
In the general case, where the values of the first column are stored in filterRows, you can generate the logical vector rows with ismember:
rows = ismember(big(:, 1), filterRows);
or with bsxfun:
rows = any(bsxfun(#eq, big(:, 1), filterRows(:).'), 2);

Vertical white lines when plotting heatmap in TIFF

When I plot a matrix with the image function as a TIFF file, I often get vertical or horizontal lines.
My matrix is of 150000 rows x 2000 columns, the lines also appears when plotting matrices of 150000 rows x 100 columns. The results are the same.
Where do the lines come from? Is this some sort of pixelated artifact? I get them almost all the time.
The matrix looks like this:
V999 V1000 V1001 V1002 V1003 V1004 V1005 V1006 V1007 V1008 V1009 V1010
[1,] 1 4 0 0 15 15 15 15 8 0 1 0
[2,] 0 3 12 5 15 15 15 1 15 4 0 2
[3,] 0 0 0 3 6 15 15 15 15 15 0 3
[4,] 3 6 15 15 15 15 15 0 3 15 15 2
[5,] 15 15 15 0 3 15 15 2 1 5 8 11
[6,] 2 1 5 8 11 15 15 15 0 0 4 3
tiff("test.tiff", width=450, height=1100)
image(t(mc), col = col1, main="950-1500"
dev.off()
Any hints/comments will be much appreciated.
You're seeing an aliasing artifact from the x11() display. You can try dragging the window to make it bigger or smaller and eventually you'll find a window size height and width that is compatible with your desired resolution.

Resources