-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcolocalization_matrix.cpp
More file actions
149 lines (115 loc) · 4.8 KB
/
colocalization_matrix.cpp
File metadata and controls
149 lines (115 loc) · 4.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include "colocalization_matrix.h"
#include <QApplication>
//#include "UploadWindow.h"
#include <Eigen/Dense>
#include <math.h>
#include <thread>
//given an eigen matrix, returns an eigen matrix with the distance between points
double distance(double x1, double x2, double y1, double y2) {
return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
};
//STEP 1
//given an eigen matrix, returns an eigen matrix with the distance between points
Eigen::MatrixXd matrix_distance(Eigen::MatrixXd A){
Eigen::MatrixXd A_distance(A.rows(),A.rows());
for(int i=0;i<A.rows();i++){
A_distance.col(i)=(A.rowwise() - A.row(i)).matrix().rowwise().norm();
}
return A_distance;
};
double max (double a, double b){
if (a<b){return b;}
return a;
};
//returns the linkage value of coordinates (x1,y1) and (x2,y2) given m and p
double linkage(double d, double m, double p) {
return pow((max(0,m-d))/m, p);
}
//STEP 2
//given an eigen matrix of the distance between points and the values m and p, returns an eigen matrix with the linkage values
Eigen::MatrixXd matrix_linkage(const Eigen::MatrixXd &A_distance, double m, double p){
//MatrixXd A_distance = matrix_distance(A);
Eigen::MatrixXd A_linkage(A_distance.rows(), A_distance.rows());
for (int i = 0; i < A_distance.rows(); i++){
for (int j = 0; j < A_distance.rows(); j++){
A_linkage(i,j) = linkage(A_distance(i,j), m, p);
}
}
return A_linkage;
}
//STEP 3
// given an eigen matrix containing the linkage values (kxk) and a eigen matrix containing the gene - beams values (nxk)
// returns an nxk matrix indicating average gene expression in neighbouring beams
Eigen::MatrixXd combine_linkage(const Eigen::MatrixXd &A_linkage, const Eigen::MatrixXd &A_expression){
int k = A_linkage.rows();
int n = A_expression.rows();
Eigen::MatrixXd A_combine(n,k);
// iterate through columns of A_combine
for(int j = 0; j < k; j++){
double row_total = A_linkage.row(j).sum();
VectorXd dot_product_results = (A_linkage.row(j) * A_expression.transpose()).transpose();
// Divide the dot product results by the row total
dot_product_results /= row_total;
// Assign the results to the corresponding row of A_combine
A_combine.col(j) = dot_product_results;
}
return A_combine;
} // end method
//STEP 4
//given two eigen matrices, the expression matrix the neighboring expression matrix from step 3, compare the columns of these matrices
//by using a special functions with certain desirable characteristics to obtain a tensor. Both matrices have dimension n_genes*n_beams,
//while the tensor will have dimension n_beams*n_genes*n_genes.
double important_function(double x_i, double Y, double a=2, double b=0.5){
return -a*abs(x_i-Y) + b*(x_i+Y);
}
Eigen::MatrixXd comparison_old(const Eigen::MatrixXd &expression, const Eigen::MatrixXd &neighbors, double a, double b){
int n_beams=expression.cols();
int n_genes=expression.rows();
//taking the mean over the beams and returning the matrix
Eigen::MatrixXd mat_new(n_genes,n_genes);
for(int i=0;i<n_genes; i++){
if(i%100==0){
}
for(int j=0;j<n_genes;j++){
std::vector<double> vec_for_average;
for (int beam=0;beam<n_beams;beam++){
vec_for_average.push_back(important_function(expression(i,beam), neighbors(j,beam), a, b));
}
mat_new(i,j)=reduce(vec_for_average.begin(), vec_for_average.end()) / n_beams;
}
}
return mat_new;
}
//STEP 5
// given a matrix that is built from the expression and the linkage (neighbourig) matrix in step 4
// normalize with row mean and 2-base logarithm and returns nxn enrichement score matrix
// ignore zero values to avoid neg infinity
//this step currently crashes the program
// TODO: determine whether method should modify given matrix or create new matrix
Eigen::MatrixXd enrichment(const Eigen::MatrixXd &A){
int N = A.rows();
// array to store the row sums (N size of matrix)
double S_A[N];
// initialize array
for(int i = 0; i < N; i++){
S_A[i] = 0;
}// end for i
// iterate through matrix A columnwise (stored in col major)
for(int j = 0; j < N; j++){
for(int i = 0; i < N; i++){
// add normalized value to row mean array
S_A[i] += A(i,j)/N;
}// end for i
}// end for j
// initialize enrichment score matrix
Eigen::MatrixXd A_enrichment(N,N);
// iterate through matrix A columnwise (stored in col major)
for(int j = 0; j < N; j++){
for(int i = 0; i < N; i++){
// add normalized value to row mean array
A_enrichment(i,j) = log2(A(i,j)/S_A[i]+1);
}// end for i
}// end for j
// return matrix containing enrichment score
return A_enrichment;
}