source/ 000755 00000000000 11651624136 0005771 5 ustar source/.classpath 000644 00000000460 11651513342 0007750 0 ustar
source/.project 000644 00000000557 11447142476 0007454 0 ustar
JGromacs
org.eclipse.jdt.core.javabuilder
org.eclipse.jdt.core.javanature
source/copyright.txt 000644 00000002363 11533224464 0010545 0 ustar JGromacs v1.0. is written by Marton Munz and Philip C Biggin
Copyright (c) University of Oxford, United Kingdom
visit http://sbcb.bioch.ox.ac.uk/jgromacs/
JGromacs v1.0 is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
JGromacs v1.0. is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with JGromacs v1.0. If not, see .
JGromacs v1.0. includes the Java linear algebra package JAMA which
has the following Copyright Notice:
JAMA is a cooperative product of The MathWorks and the National
Institute of Standards and Technology (NIST) which has been released
to the public domain. Neither The MathWorks nor NIST assumes any
responsibility whatsoever for its use by other parties, and makes
no guarantees, expressed or implied, about its quality, reliability,
or any other characteristic.
source/jama/ 000755 00000000000 11651624136 0006701 5 ustar source/jama/CholeskyDecomposition.java 000644 00000013175 11446723554 0014077 0 ustar package jama;
/** Cholesky Decomposition.
For a symmetric, positive definite matrix A, the Cholesky decomposition
is an lower triangular matrix L so that A = L*L'.
If the matrix is not symmetric or positive definite, the constructor
returns a partial decomposition and sets an internal flag that may
be queried by the isSPD() method.
*/
public class CholeskyDecomposition implements java.io.Serializable {
/* ------------------------
Class variables
* ------------------------ */
/** Array for internal storage of decomposition.
@serial internal array storage.
*/
private double[][] L;
/** Row and column dimension (square matrix).
@serial matrix dimension.
*/
private int n;
/** Symmetric and positive definite flag.
@serial is symmetric and positive definite flag.
*/
private boolean isspd;
/* ------------------------
Constructor
* ------------------------ */
/** Cholesky algorithm for symmetric and positive definite matrix.
@param A Square, symmetric matrix.
@return Structure to access L and isspd flag.
*/
public CholeskyDecomposition (Matrix Arg) {
// Initialize.
double[][] A = Arg.getArray();
n = Arg.getRowDimension();
L = new double[n][n];
isspd = (Arg.getColumnDimension() == n);
// Main loop.
for (int j = 0; j < n; j++) {
double[] Lrowj = L[j];
double d = 0.0;
for (int k = 0; k < j; k++) {
double[] Lrowk = L[k];
double s = 0.0;
for (int i = 0; i < k; i++) {
s += Lrowk[i]*Lrowj[i];
}
Lrowj[k] = s = (A[j][k] - s)/L[k][k];
d = d + s*s;
isspd = isspd & (A[k][j] == A[j][k]);
}
d = A[j][j] - d;
isspd = isspd & (d > 0.0);
L[j][j] = Math.sqrt(Math.max(d,0.0));
for (int k = j+1; k < n; k++) {
L[j][k] = 0.0;
}
}
}
/* ------------------------
Temporary, experimental code.
* ------------------------ *\
\** Right Triangular Cholesky Decomposition.
For a symmetric, positive definite matrix A, the Right Cholesky
decomposition is an upper triangular matrix R so that A = R'*R.
This constructor computes R with the Fortran inspired column oriented
algorithm used in LINPACK and MATLAB. In Java, we suspect a row oriented,
lower triangular decomposition is faster. We have temporarily included
this constructor here until timing experiments confirm this suspicion.
*\
\** Array for internal storage of right triangular decomposition. **\
private transient double[][] R;
\** Cholesky algorithm for symmetric and positive definite matrix.
@param A Square, symmetric matrix.
@param rightflag Actual value ignored.
@return Structure to access R and isspd flag.
*\
public CholeskyDecomposition (Matrix Arg, int rightflag) {
// Initialize.
double[][] A = Arg.getArray();
n = Arg.getColumnDimension();
R = new double[n][n];
isspd = (Arg.getColumnDimension() == n);
// Main loop.
for (int j = 0; j < n; j++) {
double d = 0.0;
for (int k = 0; k < j; k++) {
double s = A[k][j];
for (int i = 0; i < k; i++) {
s = s - R[i][k]*R[i][j];
}
R[k][j] = s = s/R[k][k];
d = d + s*s;
isspd = isspd & (A[k][j] == A[j][k]);
}
d = A[j][j] - d;
isspd = isspd & (d > 0.0);
R[j][j] = Math.sqrt(Math.max(d,0.0));
for (int k = j+1; k < n; k++) {
R[k][j] = 0.0;
}
}
}
\** Return upper triangular factor.
@return R
*\
public Matrix getR () {
return new Matrix(R,n,n);
}
\* ------------------------
End of temporary code.
* ------------------------ */
/* ------------------------
Public Methods
* ------------------------ */
/** Is the matrix symmetric and positive definite?
@return true if A is symmetric and positive definite.
*/
public boolean isSPD () {
return isspd;
}
/** Return triangular factor.
@return L
*/
public Matrix getL () {
return new Matrix(L,n,n);
}
/** Solve A*X = B
@param B A Matrix with as many rows as A and any number of columns.
@return X so that L*L'*X = B
@exception IllegalArgumentException Matrix row dimensions must agree.
@exception RuntimeException Matrix is not symmetric positive definite.
*/
public Matrix solve (Matrix B) {
if (B.getRowDimension() != n) {
throw new IllegalArgumentException("Matrix row dimensions must agree.");
}
if (!isspd) {
throw new RuntimeException("Matrix is not symmetric positive definite.");
}
// Copy right hand side.
double[][] X = B.getArrayCopy();
int nx = B.getColumnDimension();
// Solve L*Y = B;
for (int k = 0; k < n; k++) {
for (int j = 0; j < nx; j++) {
for (int i = 0; i < k ; i++) {
X[k][j] -= X[i][j]*L[k][i];
}
X[k][j] /= L[k][k];
}
}
// Solve L'*X = Y;
for (int k = n-1; k >= 0; k--) {
for (int j = 0; j < nx; j++) {
for (int i = k+1; i < n ; i++) {
X[k][j] -= X[i][j]*L[i][k];
}
X[k][j] /= L[k][k];
}
}
return new Matrix(X,n,nx);
}
}
source/jama/EigenvalueDecomposition.java 000644 00000066170 11446723646 0014407 0 ustar package jama;
import jama.util.*;
/** Eigenvalues and eigenvectors of a real matrix.
If A is symmetric, then A = V*D*V' where the eigenvalue matrix D is
diagonal and the eigenvector matrix V is orthogonal.
I.e. A = V.times(D.times(V.transpose())) and
V.times(V.transpose()) equals the identity matrix.
If A is not symmetric, then the eigenvalue matrix D is block diagonal
with the real eigenvalues in 1-by-1 blocks and any complex eigenvalues,
lambda + i*mu, in 2-by-2 blocks, [lambda, mu; -mu, lambda]. The
columns of V represent the eigenvectors in the sense that A*V = V*D,
i.e. A.times(V) equals V.times(D). The matrix V may be badly
conditioned, or even singular, so the validity of the equation
A = V*D*inverse(V) depends upon V.cond().
**/
public class EigenvalueDecomposition implements java.io.Serializable {
/* ------------------------
Class variables
* ------------------------ */
/** Row and column dimension (square matrix).
@serial matrix dimension.
*/
private int n;
/** Symmetry flag.
@serial internal symmetry flag.
*/
private boolean issymmetric;
/** Arrays for internal storage of eigenvalues.
@serial internal storage of eigenvalues.
*/
private double[] d, e;
/** Array for internal storage of eigenvectors.
@serial internal storage of eigenvectors.
*/
private double[][] V;
/** Array for internal storage of nonsymmetric Hessenberg form.
@serial internal storage of nonsymmetric Hessenberg form.
*/
private double[][] H;
/** Working storage for nonsymmetric algorithm.
@serial working storage for nonsymmetric algorithm.
*/
private double[] ort;
/* ------------------------
Private Methods
* ------------------------ */
// Symmetric Householder reduction to tridiagonal form.
private void tred2 () {
// This is derived from the Algol procedures tred2 by
// Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
// Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
// Fortran subroutine in EISPACK.
for (int j = 0; j < n; j++) {
d[j] = V[n-1][j];
}
// Householder reduction to tridiagonal form.
for (int i = n-1; i > 0; i--) {
// Scale to avoid under/overflow.
double scale = 0.0;
double h = 0.0;
for (int k = 0; k < i; k++) {
scale = scale + Math.abs(d[k]);
}
if (scale == 0.0) {
e[i] = d[i-1];
for (int j = 0; j < i; j++) {
d[j] = V[i-1][j];
V[i][j] = 0.0;
V[j][i] = 0.0;
}
} else {
// Generate Householder vector.
for (int k = 0; k < i; k++) {
d[k] /= scale;
h += d[k] * d[k];
}
double f = d[i-1];
double g = Math.sqrt(h);
if (f > 0) {
g = -g;
}
e[i] = scale * g;
h = h - f * g;
d[i-1] = f - g;
for (int j = 0; j < i; j++) {
e[j] = 0.0;
}
// Apply similarity transformation to remaining columns.
for (int j = 0; j < i; j++) {
f = d[j];
V[j][i] = f;
g = e[j] + V[j][j] * f;
for (int k = j+1; k <= i-1; k++) {
g += V[k][j] * d[k];
e[k] += V[k][j] * f;
}
e[j] = g;
}
f = 0.0;
for (int j = 0; j < i; j++) {
e[j] /= h;
f += e[j] * d[j];
}
double hh = f / (h + h);
for (int j = 0; j < i; j++) {
e[j] -= hh * d[j];
}
for (int j = 0; j < i; j++) {
f = d[j];
g = e[j];
for (int k = j; k <= i-1; k++) {
V[k][j] -= (f * e[k] + g * d[k]);
}
d[j] = V[i-1][j];
V[i][j] = 0.0;
}
}
d[i] = h;
}
// Accumulate transformations.
for (int i = 0; i < n-1; i++) {
V[n-1][i] = V[i][i];
V[i][i] = 1.0;
double h = d[i+1];
if (h != 0.0) {
for (int k = 0; k <= i; k++) {
d[k] = V[k][i+1] / h;
}
for (int j = 0; j <= i; j++) {
double g = 0.0;
for (int k = 0; k <= i; k++) {
g += V[k][i+1] * V[k][j];
}
for (int k = 0; k <= i; k++) {
V[k][j] -= g * d[k];
}
}
}
for (int k = 0; k <= i; k++) {
V[k][i+1] = 0.0;
}
}
for (int j = 0; j < n; j++) {
d[j] = V[n-1][j];
V[n-1][j] = 0.0;
}
V[n-1][n-1] = 1.0;
e[0] = 0.0;
}
// Symmetric tridiagonal QL algorithm.
private void tql2 () {
// This is derived from the Algol procedures tql2, by
// Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
// Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
// Fortran subroutine in EISPACK.
for (int i = 1; i < n; i++) {
e[i-1] = e[i];
}
e[n-1] = 0.0;
double f = 0.0;
double tst1 = 0.0;
double eps = Math.pow(2.0,-52.0);
for (int l = 0; l < n; l++) {
// Find small subdiagonal element
tst1 = Math.max(tst1,Math.abs(d[l]) + Math.abs(e[l]));
int m = l;
while (m < n) {
if (Math.abs(e[m]) <= eps*tst1) {
break;
}
m++;
}
// If m == l, d[l] is an eigenvalue,
// otherwise, iterate.
if (m > l) {
int iter = 0;
do {
iter = iter + 1; // (Could check iteration count here.)
// Compute implicit shift
double g = d[l];
double p = (d[l+1] - g) / (2.0 * e[l]);
double r = Maths.hypot(p,1.0);
if (p < 0) {
r = -r;
}
d[l] = e[l] / (p + r);
d[l+1] = e[l] * (p + r);
double dl1 = d[l+1];
double h = g - d[l];
for (int i = l+2; i < n; i++) {
d[i] -= h;
}
f = f + h;
// Implicit QL transformation.
p = d[m];
double c = 1.0;
double c2 = c;
double c3 = c;
double el1 = e[l+1];
double s = 0.0;
double s2 = 0.0;
for (int i = m-1; i >= l; i--) {
c3 = c2;
c2 = c;
s2 = s;
g = c * e[i];
h = c * p;
r = Maths.hypot(p,e[i]);
e[i+1] = s * r;
s = e[i] / r;
c = p / r;
p = c * d[i] - s * g;
d[i+1] = h + s * (c * g + s * d[i]);
// Accumulate transformation.
for (int k = 0; k < n; k++) {
h = V[k][i+1];
V[k][i+1] = s * V[k][i] + c * h;
V[k][i] = c * V[k][i] - s * h;
}
}
p = -s * s2 * c3 * el1 * e[l] / dl1;
e[l] = s * p;
d[l] = c * p;
// Check for convergence.
} while (Math.abs(e[l]) > eps*tst1);
}
d[l] = d[l] + f;
e[l] = 0.0;
}
// Sort eigenvalues and corresponding vectors.
for (int i = 0; i < n-1; i++) {
int k = i;
double p = d[i];
for (int j = i+1; j < n; j++) {
if (d[j] < p) {
k = j;
p = d[j];
}
}
if (k != i) {
d[k] = d[i];
d[i] = p;
for (int j = 0; j < n; j++) {
p = V[j][i];
V[j][i] = V[j][k];
V[j][k] = p;
}
}
}
}
// Nonsymmetric reduction to Hessenberg form.
private void orthes () {
// This is derived from the Algol procedures orthes and ortran,
// by Martin and Wilkinson, Handbook for Auto. Comp.,
// Vol.ii-Linear Algebra, and the corresponding
// Fortran subroutines in EISPACK.
int low = 0;
int high = n-1;
for (int m = low+1; m <= high-1; m++) {
// Scale column.
double scale = 0.0;
for (int i = m; i <= high; i++) {
scale = scale + Math.abs(H[i][m-1]);
}
if (scale != 0.0) {
// Compute Householder transformation.
double h = 0.0;
for (int i = high; i >= m; i--) {
ort[i] = H[i][m-1]/scale;
h += ort[i] * ort[i];
}
double g = Math.sqrt(h);
if (ort[m] > 0) {
g = -g;
}
h = h - ort[m] * g;
ort[m] = ort[m] - g;
// Apply Householder similarity transformation
// H = (I-u*u'/h)*H*(I-u*u')/h)
for (int j = m; j < n; j++) {
double f = 0.0;
for (int i = high; i >= m; i--) {
f += ort[i]*H[i][j];
}
f = f/h;
for (int i = m; i <= high; i++) {
H[i][j] -= f*ort[i];
}
}
for (int i = 0; i <= high; i++) {
double f = 0.0;
for (int j = high; j >= m; j--) {
f += ort[j]*H[i][j];
}
f = f/h;
for (int j = m; j <= high; j++) {
H[i][j] -= f*ort[j];
}
}
ort[m] = scale*ort[m];
H[m][m-1] = scale*g;
}
}
// Accumulate transformations (Algol's ortran).
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
V[i][j] = (i == j ? 1.0 : 0.0);
}
}
for (int m = high-1; m >= low+1; m--) {
if (H[m][m-1] != 0.0) {
for (int i = m+1; i <= high; i++) {
ort[i] = H[i][m-1];
}
for (int j = m; j <= high; j++) {
double g = 0.0;
for (int i = m; i <= high; i++) {
g += ort[i] * V[i][j];
}
// Double division avoids possible underflow
g = (g / ort[m]) / H[m][m-1];
for (int i = m; i <= high; i++) {
V[i][j] += g * ort[i];
}
}
}
}
}
// Complex scalar division.
private transient double cdivr, cdivi;
private void cdiv(double xr, double xi, double yr, double yi) {
double r,d;
if (Math.abs(yr) > Math.abs(yi)) {
r = yi/yr;
d = yr + r*yi;
cdivr = (xr + r*xi)/d;
cdivi = (xi - r*xr)/d;
} else {
r = yr/yi;
d = yi + r*yr;
cdivr = (r*xr + xi)/d;
cdivi = (r*xi - xr)/d;
}
}
// Nonsymmetric reduction from Hessenberg to real Schur form.
private void hqr2 () {
// This is derived from the Algol procedure hqr2,
// by Martin and Wilkinson, Handbook for Auto. Comp.,
// Vol.ii-Linear Algebra, and the corresponding
// Fortran subroutine in EISPACK.
// Initialize
int nn = this.n;
int n = nn-1;
int low = 0;
int high = nn-1;
double eps = Math.pow(2.0,-52.0);
double exshift = 0.0;
double p=0,q=0,r=0,s=0,z=0,t,w,x,y;
// Store roots isolated by balanc and compute matrix norm
double norm = 0.0;
for (int i = 0; i < nn; i++) {
if (i < low | i > high) {
d[i] = H[i][i];
e[i] = 0.0;
}
for (int j = Math.max(i-1,0); j < nn; j++) {
norm = norm + Math.abs(H[i][j]);
}
}
// Outer loop over eigenvalue index
int iter = 0;
while (n >= low) {
// Look for single small sub-diagonal element
int l = n;
while (l > low) {
s = Math.abs(H[l-1][l-1]) + Math.abs(H[l][l]);
if (s == 0.0) {
s = norm;
}
if (Math.abs(H[l][l-1]) < eps * s) {
break;
}
l--;
}
// Check for convergence
// One root found
if (l == n) {
H[n][n] = H[n][n] + exshift;
d[n] = H[n][n];
e[n] = 0.0;
n--;
iter = 0;
// Two roots found
} else if (l == n-1) {
w = H[n][n-1] * H[n-1][n];
p = (H[n-1][n-1] - H[n][n]) / 2.0;
q = p * p + w;
z = Math.sqrt(Math.abs(q));
H[n][n] = H[n][n] + exshift;
H[n-1][n-1] = H[n-1][n-1] + exshift;
x = H[n][n];
// Real pair
if (q >= 0) {
if (p >= 0) {
z = p + z;
} else {
z = p - z;
}
d[n-1] = x + z;
d[n] = d[n-1];
if (z != 0.0) {
d[n] = x - w / z;
}
e[n-1] = 0.0;
e[n] = 0.0;
x = H[n][n-1];
s = Math.abs(x) + Math.abs(z);
p = x / s;
q = z / s;
r = Math.sqrt(p * p+q * q);
p = p / r;
q = q / r;
// Row modification
for (int j = n-1; j < nn; j++) {
z = H[n-1][j];
H[n-1][j] = q * z + p * H[n][j];
H[n][j] = q * H[n][j] - p * z;
}
// Column modification
for (int i = 0; i <= n; i++) {
z = H[i][n-1];
H[i][n-1] = q * z + p * H[i][n];
H[i][n] = q * H[i][n] - p * z;
}
// Accumulate transformations
for (int i = low; i <= high; i++) {
z = V[i][n-1];
V[i][n-1] = q * z + p * V[i][n];
V[i][n] = q * V[i][n] - p * z;
}
// Complex pair
} else {
d[n-1] = x + p;
d[n] = x + p;
e[n-1] = z;
e[n] = -z;
}
n = n - 2;
iter = 0;
// No convergence yet
} else {
// Form shift
x = H[n][n];
y = 0.0;
w = 0.0;
if (l < n) {
y = H[n-1][n-1];
w = H[n][n-1] * H[n-1][n];
}
// Wilkinson's original ad hoc shift
if (iter == 10) {
exshift += x;
for (int i = low; i <= n; i++) {
H[i][i] -= x;
}
s = Math.abs(H[n][n-1]) + Math.abs(H[n-1][n-2]);
x = y = 0.75 * s;
w = -0.4375 * s * s;
}
// MATLAB's new ad hoc shift
if (iter == 30) {
s = (y - x) / 2.0;
s = s * s + w;
if (s > 0) {
s = Math.sqrt(s);
if (y < x) {
s = -s;
}
s = x - w / ((y - x) / 2.0 + s);
for (int i = low; i <= n; i++) {
H[i][i] -= s;
}
exshift += s;
x = y = w = 0.964;
}
}
iter = iter + 1; // (Could check iteration count here.)
// Look for two consecutive small sub-diagonal elements
int m = n-2;
while (m >= l) {
z = H[m][m];
r = x - z;
s = y - z;
p = (r * s - w) / H[m+1][m] + H[m][m+1];
q = H[m+1][m+1] - z - r - s;
r = H[m+2][m+1];
s = Math.abs(p) + Math.abs(q) + Math.abs(r);
p = p / s;
q = q / s;
r = r / s;
if (m == l) {
break;
}
if (Math.abs(H[m][m-1]) * (Math.abs(q) + Math.abs(r)) <
eps * (Math.abs(p) * (Math.abs(H[m-1][m-1]) + Math.abs(z) +
Math.abs(H[m+1][m+1])))) {
break;
}
m--;
}
for (int i = m+2; i <= n; i++) {
H[i][i-2] = 0.0;
if (i > m+2) {
H[i][i-3] = 0.0;
}
}
// Double QR step involving rows l:n and columns m:n
for (int k = m; k <= n-1; k++) {
boolean notlast = (k != n-1);
if (k != m) {
p = H[k][k-1];
q = H[k+1][k-1];
r = (notlast ? H[k+2][k-1] : 0.0);
x = Math.abs(p) + Math.abs(q) + Math.abs(r);
if (x != 0.0) {
p = p / x;
q = q / x;
r = r / x;
}
}
if (x == 0.0) {
break;
}
s = Math.sqrt(p * p + q * q + r * r);
if (p < 0) {
s = -s;
}
if (s != 0) {
if (k != m) {
H[k][k-1] = -s * x;
} else if (l != m) {
H[k][k-1] = -H[k][k-1];
}
p = p + s;
x = p / s;
y = q / s;
z = r / s;
q = q / p;
r = r / p;
// Row modification
for (int j = k; j < nn; j++) {
p = H[k][j] + q * H[k+1][j];
if (notlast) {
p = p + r * H[k+2][j];
H[k+2][j] = H[k+2][j] - p * z;
}
H[k][j] = H[k][j] - p * x;
H[k+1][j] = H[k+1][j] - p * y;
}
// Column modification
for (int i = 0; i <= Math.min(n,k+3); i++) {
p = x * H[i][k] + y * H[i][k+1];
if (notlast) {
p = p + z * H[i][k+2];
H[i][k+2] = H[i][k+2] - p * r;
}
H[i][k] = H[i][k] - p;
H[i][k+1] = H[i][k+1] - p * q;
}
// Accumulate transformations
for (int i = low; i <= high; i++) {
p = x * V[i][k] + y * V[i][k+1];
if (notlast) {
p = p + z * V[i][k+2];
V[i][k+2] = V[i][k+2] - p * r;
}
V[i][k] = V[i][k] - p;
V[i][k+1] = V[i][k+1] - p * q;
}
} // (s != 0)
} // k loop
} // check convergence
} // while (n >= low)
// Backsubstitute to find vectors of upper triangular form
if (norm == 0.0) {
return;
}
for (n = nn-1; n >= 0; n--) {
p = d[n];
q = e[n];
// Real vector
if (q == 0) {
int l = n;
H[n][n] = 1.0;
for (int i = n-1; i >= 0; i--) {
w = H[i][i] - p;
r = 0.0;
for (int j = l; j <= n; j++) {
r = r + H[i][j] * H[j][n];
}
if (e[i] < 0.0) {
z = w;
s = r;
} else {
l = i;
if (e[i] == 0.0) {
if (w != 0.0) {
H[i][n] = -r / w;
} else {
H[i][n] = -r / (eps * norm);
}
// Solve real equations
} else {
x = H[i][i+1];
y = H[i+1][i];
q = (d[i] - p) * (d[i] - p) + e[i] * e[i];
t = (x * s - z * r) / q;
H[i][n] = t;
if (Math.abs(x) > Math.abs(z)) {
H[i+1][n] = (-r - w * t) / x;
} else {
H[i+1][n] = (-s - y * t) / z;
}
}
// Overflow control
t = Math.abs(H[i][n]);
if ((eps * t) * t > 1) {
for (int j = i; j <= n; j++) {
H[j][n] = H[j][n] / t;
}
}
}
}
// Complex vector
} else if (q < 0) {
int l = n-1;
// Last vector component imaginary so matrix is triangular
if (Math.abs(H[n][n-1]) > Math.abs(H[n-1][n])) {
H[n-1][n-1] = q / H[n][n-1];
H[n-1][n] = -(H[n][n] - p) / H[n][n-1];
} else {
cdiv(0.0,-H[n-1][n],H[n-1][n-1]-p,q);
H[n-1][n-1] = cdivr;
H[n-1][n] = cdivi;
}
H[n][n-1] = 0.0;
H[n][n] = 1.0;
for (int i = n-2; i >= 0; i--) {
double ra,sa,vr,vi;
ra = 0.0;
sa = 0.0;
for (int j = l; j <= n; j++) {
ra = ra + H[i][j] * H[j][n-1];
sa = sa + H[i][j] * H[j][n];
}
w = H[i][i] - p;
if (e[i] < 0.0) {
z = w;
r = ra;
s = sa;
} else {
l = i;
if (e[i] == 0) {
cdiv(-ra,-sa,w,q);
H[i][n-1] = cdivr;
H[i][n] = cdivi;
} else {
// Solve complex equations
x = H[i][i+1];
y = H[i+1][i];
vr = (d[i] - p) * (d[i] - p) + e[i] * e[i] - q * q;
vi = (d[i] - p) * 2.0 * q;
if (vr == 0.0 & vi == 0.0) {
vr = eps * norm * (Math.abs(w) + Math.abs(q) +
Math.abs(x) + Math.abs(y) + Math.abs(z));
}
cdiv(x*r-z*ra+q*sa,x*s-z*sa-q*ra,vr,vi);
H[i][n-1] = cdivr;
H[i][n] = cdivi;
if (Math.abs(x) > (Math.abs(z) + Math.abs(q))) {
H[i+1][n-1] = (-ra - w * H[i][n-1] + q * H[i][n]) / x;
H[i+1][n] = (-sa - w * H[i][n] - q * H[i][n-1]) / x;
} else {
cdiv(-r-y*H[i][n-1],-s-y*H[i][n],z,q);
H[i+1][n-1] = cdivr;
H[i+1][n] = cdivi;
}
}
// Overflow control
t = Math.max(Math.abs(H[i][n-1]),Math.abs(H[i][n]));
if ((eps * t) * t > 1) {
for (int j = i; j <= n; j++) {
H[j][n-1] = H[j][n-1] / t;
H[j][n] = H[j][n] / t;
}
}
}
}
}
}
// Vectors of isolated roots
for (int i = 0; i < nn; i++) {
if (i < low | i > high) {
for (int j = i; j < nn; j++) {
V[i][j] = H[i][j];
}
}
}
// Back transformation to get eigenvectors of original matrix
for (int j = nn-1; j >= low; j--) {
for (int i = low; i <= high; i++) {
z = 0.0;
for (int k = low; k <= Math.min(j,high); k++) {
z = z + V[i][k] * H[k][j];
}
V[i][j] = z;
}
}
}
/* ------------------------
Constructor
* ------------------------ */
/** Check for symmetry, then construct the eigenvalue decomposition
@param A Square matrix
@return Structure to access D and V.
*/
public EigenvalueDecomposition (Matrix Arg) {
double[][] A = Arg.getArray();
n = Arg.getColumnDimension();
V = new double[n][n];
d = new double[n];
e = new double[n];
issymmetric = true;
for (int j = 0; (j < n) & issymmetric; j++) {
for (int i = 0; (i < n) & issymmetric; i++) {
issymmetric = (A[i][j] == A[j][i]);
}
}
if (issymmetric) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
V[i][j] = A[i][j];
}
}
// Tridiagonalize.
tred2();
// Diagonalize.
tql2();
} else {
H = new double[n][n];
ort = new double[n];
for (int j = 0; j < n; j++) {
for (int i = 0; i < n; i++) {
H[i][j] = A[i][j];
}
}
// Reduce to Hessenberg form.
orthes();
// Reduce Hessenberg to real Schur form.
hqr2();
}
}
/* ------------------------
Public Methods
* ------------------------ */
/** Return the eigenvector matrix
@return V
*/
public Matrix getV () {
return new Matrix(V,n,n);
}
/** Return the real parts of the eigenvalues
@return real(diag(D))
*/
public double[] getRealEigenvalues () {
return d;
}
/** Return the imaginary parts of the eigenvalues
@return imag(diag(D))
*/
public double[] getImagEigenvalues () {
return e;
}
/** Return the block diagonal eigenvalue matrix
@return D
*/
public Matrix getD () {
Matrix X = new Matrix(n,n);
double[][] D = X.getArray();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
D[i][j] = 0.0;
}
D[i][i] = d[i];
if (e[i] > 0) {
D[i][i+1] = e[i];
} else if (e[i] < 0) {
D[i][i-1] = e[i];
}
}
return X;
}
}
source/jama/LUDecomposition.java 000644 00000020443 11446723600 0012622 0 ustar package jama;
/** LU Decomposition.
For an m-by-n matrix A with m >= n, the LU decomposition is an m-by-n
unit lower triangular matrix L, an n-by-n upper triangular matrix U,
and a permutation vector piv of length m so that A(piv,:) = L*U.
If m < n, then L is m-by-m and U is m-by-n.
The LU decompostion with pivoting always exists, even if the matrix is
singular, so the constructor will never fail. The primary use of the
LU decomposition is in the solution of square systems of simultaneous
linear equations. This will fail if isNonsingular() returns false.
*/
public class LUDecomposition implements java.io.Serializable {
/* ------------------------
Class variables
* ------------------------ */
/** Array for internal storage of decomposition.
@serial internal array storage.
*/
private double[][] LU;
/** Row and column dimensions, and pivot sign.
@serial column dimension.
@serial row dimension.
@serial pivot sign.
*/
private int m, n, pivsign;
/** Internal storage of pivot vector.
@serial pivot vector.
*/
private int[] piv;
/* ------------------------
Constructor
* ------------------------ */
/** LU Decomposition
@param A Rectangular matrix
@return Structure to access L, U and piv.
*/
public LUDecomposition (Matrix A) {
// Use a "left-looking", dot-product, Crout/Doolittle algorithm.
LU = A.getArrayCopy();
m = A.getRowDimension();
n = A.getColumnDimension();
piv = new int[m];
for (int i = 0; i < m; i++) {
piv[i] = i;
}
pivsign = 1;
double[] LUrowi;
double[] LUcolj = new double[m];
// Outer loop.
for (int j = 0; j < n; j++) {
// Make a copy of the j-th column to localize references.
for (int i = 0; i < m; i++) {
LUcolj[i] = LU[i][j];
}
// Apply previous transformations.
for (int i = 0; i < m; i++) {
LUrowi = LU[i];
// Most of the time is spent in the following dot product.
int kmax = Math.min(i,j);
double s = 0.0;
for (int k = 0; k < kmax; k++) {
s += LUrowi[k]*LUcolj[k];
}
LUrowi[j] = LUcolj[i] -= s;
}
// Find pivot and exchange if necessary.
int p = j;
for (int i = j+1; i < m; i++) {
if (Math.abs(LUcolj[i]) > Math.abs(LUcolj[p])) {
p = i;
}
}
if (p != j) {
for (int k = 0; k < n; k++) {
double t = LU[p][k]; LU[p][k] = LU[j][k]; LU[j][k] = t;
}
int k = piv[p]; piv[p] = piv[j]; piv[j] = k;
pivsign = -pivsign;
}
// Compute multipliers.
if (j < m & LU[j][j] != 0.0) {
for (int i = j+1; i < m; i++) {
LU[i][j] /= LU[j][j];
}
}
}
}
/* ------------------------
Temporary, experimental code.
------------------------ *\
\** LU Decomposition, computed by Gaussian elimination.
This constructor computes L and U with the "daxpy"-based elimination
algorithm used in LINPACK and MATLAB. In Java, we suspect the dot-product,
Crout algorithm will be faster. We have temporarily included this
constructor until timing experiments confirm this suspicion.
@param A Rectangular matrix
@param linpackflag Use Gaussian elimination. Actual value ignored.
@return Structure to access L, U and piv.
*\
public LUDecomposition (Matrix A, int linpackflag) {
// Initialize.
LU = A.getArrayCopy();
m = A.getRowDimension();
n = A.getColumnDimension();
piv = new int[m];
for (int i = 0; i < m; i++) {
piv[i] = i;
}
pivsign = 1;
// Main loop.
for (int k = 0; k < n; k++) {
// Find pivot.
int p = k;
for (int i = k+1; i < m; i++) {
if (Math.abs(LU[i][k]) > Math.abs(LU[p][k])) {
p = i;
}
}
// Exchange if necessary.
if (p != k) {
for (int j = 0; j < n; j++) {
double t = LU[p][j]; LU[p][j] = LU[k][j]; LU[k][j] = t;
}
int t = piv[p]; piv[p] = piv[k]; piv[k] = t;
pivsign = -pivsign;
}
// Compute multipliers and eliminate k-th column.
if (LU[k][k] != 0.0) {
for (int i = k+1; i < m; i++) {
LU[i][k] /= LU[k][k];
for (int j = k+1; j < n; j++) {
LU[i][j] -= LU[i][k]*LU[k][j];
}
}
}
}
}
\* ------------------------
End of temporary code.
* ------------------------ */
/* ------------------------
Public Methods
* ------------------------ */
/** Is the matrix nonsingular?
@return true if U, and hence A, is nonsingular.
*/
public boolean isNonsingular () {
for (int j = 0; j < n; j++) {
if (LU[j][j] == 0)
return false;
}
return true;
}
/** Return lower triangular factor
@return L
*/
public Matrix getL () {
Matrix X = new Matrix(m,n);
double[][] L = X.getArray();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (i > j) {
L[i][j] = LU[i][j];
} else if (i == j) {
L[i][j] = 1.0;
} else {
L[i][j] = 0.0;
}
}
}
return X;
}
/** Return upper triangular factor
@return U
*/
public Matrix getU () {
Matrix X = new Matrix(n,n);
double[][] U = X.getArray();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i <= j) {
U[i][j] = LU[i][j];
} else {
U[i][j] = 0.0;
}
}
}
return X;
}
/** Return pivot permutation vector
@return piv
*/
public int[] getPivot () {
int[] p = new int[m];
for (int i = 0; i < m; i++) {
p[i] = piv[i];
}
return p;
}
/** Return pivot permutation vector as a one-dimensional double array
@return (double) piv
*/
public double[] getDoublePivot () {
double[] vals = new double[m];
for (int i = 0; i < m; i++) {
vals[i] = (double) piv[i];
}
return vals;
}
/** Determinant
@return det(A)
@exception IllegalArgumentException Matrix must be square
*/
public double det () {
if (m != n) {
throw new IllegalArgumentException("Matrix must be square.");
}
double d = (double) pivsign;
for (int j = 0; j < n; j++) {
d *= LU[j][j];
}
return d;
}
/** Solve A*X = B
@param B A Matrix with as many rows as A and any number of columns.
@return X so that L*U*X = B(piv,:)
@exception IllegalArgumentException Matrix row dimensions must agree.
@exception RuntimeException Matrix is singular.
*/
public Matrix solve (Matrix B) {
if (B.getRowDimension() != m) {
throw new IllegalArgumentException("Matrix row dimensions must agree.");
}
if (!this.isNonsingular()) {
throw new RuntimeException("Matrix is singular.");
}
// Copy right hand side with pivoting
int nx = B.getColumnDimension();
Matrix Xmat = B.getMatrix(piv,0,nx-1);
double[][] X = Xmat.getArray();
// Solve L*Y = B(piv,:)
for (int k = 0; k < n; k++) {
for (int i = k+1; i < n; i++) {
for (int j = 0; j < nx; j++) {
X[i][j] -= X[k][j]*LU[i][k];
}
}
}
// Solve U*X = Y;
for (int k = n-1; k >= 0; k--) {
for (int j = 0; j < nx; j++) {
X[k][j] /= LU[k][k];
}
for (int i = 0; i < k; i++) {
for (int j = 0; j < nx; j++) {
X[i][j] -= X[k][j]*LU[i][k];
}
}
}
return Xmat;
}
}
source/jama/Matrix.java 000644 00000072220 11446723624 0011017 0 ustar package jama;
import java.text.NumberFormat;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
import java.text.FieldPosition;
import java.io.PrintWriter;
import java.io.BufferedReader;
import java.io.StreamTokenizer;
import jama.util.*;
/**
Jama = Java Matrix class.
The Java Matrix Class provides the fundamental operations of numerical
linear algebra. Various constructors create Matrices from two dimensional
arrays of double precision floating point numbers. Various "gets" and
"sets" provide access to submatrices and matrix elements. Several methods
implement basic matrix arithmetic, including matrix addition and
multiplication, matrix norms, and element-by-element array operations.
Methods for reading and printing matrices are also included. All the
operations in this version of the Matrix Class involve real matrices.
Complex matrices may be handled in a future version.
Five fundamental matrix decompositions, which consist of pairs or triples
of matrices, permutation vectors, and the like, produce results in five
decomposition classes. These decompositions are accessed by the Matrix
class to compute solutions of simultaneous linear equations, determinants,
inverses and other matrix functions. The five decompositions are:
= n) throw new java.io.IOException
("Row " + v.size() + " is too long.");
row[j++] = Double.valueOf(tokenizer.sval).doubleValue();
} while (tokenizer.nextToken() == StreamTokenizer.TT_WORD);
if (j < n) throw new java.io.IOException
("Row " + v.size() + " is too short.");
}
int m = v.size(); // Now we've got the number of rows.
double[][] A = new double[m][];
v.copyInto(A); // copy the rows out of the vector
return new Matrix(A);
}
/* ------------------------
Private Methods
* ------------------------ */
/** Check if size(A) == size(B) **/
private void checkMatrixDimensions (Matrix B) {
if (B.m != m || B.n != n) {
throw new IllegalArgumentException("Matrix dimensions must agree.");
}
}
}
source/jama/QRDecomposition.java 000644 00000013650 11446723614 0012633 0 ustar package jama;
import jama.util.*;
/** QR Decomposition.
For an m-by-n matrix A with m >= n, the QR decomposition is an m-by-n
orthogonal matrix Q and an n-by-n upper triangular matrix R so that
A = Q*R.
The QR decompostion always exists, even if the matrix does not have
full rank, so the constructor will never fail. The primary use of the
QR decomposition is in the least squares solution of nonsquare systems
of simultaneous linear equations. This will fail if isFullRank()
returns false.
*/
public class QRDecomposition implements java.io.Serializable {
/* ------------------------
Class variables
* ------------------------ */
/** Array for internal storage of decomposition.
@serial internal array storage.
*/
private double[][] QR;
/** Row and column dimensions.
@serial column dimension.
@serial row dimension.
*/
private int m, n;
/** Array for internal storage of diagonal of R.
@serial diagonal of R.
*/
private double[] Rdiag;
/* ------------------------
Constructor
* ------------------------ */
/** QR Decomposition, computed by Householder reflections.
@param A Rectangular matrix
@return Structure to access R and the Householder vectors and compute Q.
*/
public QRDecomposition (Matrix A) {
// Initialize.
QR = A.getArrayCopy();
m = A.getRowDimension();
n = A.getColumnDimension();
Rdiag = new double[n];
// Main loop.
for (int k = 0; k < n; k++) {
// Compute 2-norm of k-th column without under/overflow.
double nrm = 0;
for (int i = k; i < m; i++) {
nrm = Maths.hypot(nrm,QR[i][k]);
}
if (nrm != 0.0) {
// Form k-th Householder vector.
if (QR[k][k] < 0) {
nrm = -nrm;
}
for (int i = k; i < m; i++) {
QR[i][k] /= nrm;
}
QR[k][k] += 1.0;
// Apply transformation to remaining columns.
for (int j = k+1; j < n; j++) {
double s = 0.0;
for (int i = k; i < m; i++) {
s += QR[i][k]*QR[i][j];
}
s = -s/QR[k][k];
for (int i = k; i < m; i++) {
QR[i][j] += s*QR[i][k];
}
}
}
Rdiag[k] = -nrm;
}
}
/* ------------------------
Public Methods
* ------------------------ */
/** Is the matrix full rank?
@return true if R, and hence A, has full rank.
*/
public boolean isFullRank () {
for (int j = 0; j < n; j++) {
if (Rdiag[j] == 0)
return false;
}
return true;
}
/** Return the Householder vectors
@return Lower trapezoidal matrix whose columns define the reflections
*/
public Matrix getH () {
Matrix X = new Matrix(m,n);
double[][] H = X.getArray();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (i >= j) {
H[i][j] = QR[i][j];
} else {
H[i][j] = 0.0;
}
}
}
return X;
}
/** Return the upper triangular factor
@return R
*/
public Matrix getR () {
Matrix X = new Matrix(n,n);
double[][] R = X.getArray();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i < j) {
R[i][j] = QR[i][j];
} else if (i == j) {
R[i][j] = Rdiag[i];
} else {
R[i][j] = 0.0;
}
}
}
return X;
}
/** Generate and return the (economy-sized) orthogonal factor
@return Q
*/
public Matrix getQ () {
Matrix X = new Matrix(m,n);
double[][] Q = X.getArray();
for (int k = n-1; k >= 0; k--) {
for (int i = 0; i < m; i++) {
Q[i][k] = 0.0;
}
Q[k][k] = 1.0;
for (int j = k; j < n; j++) {
if (QR[k][k] != 0) {
double s = 0.0;
for (int i = k; i < m; i++) {
s += QR[i][k]*Q[i][j];
}
s = -s/QR[k][k];
for (int i = k; i < m; i++) {
Q[i][j] += s*QR[i][k];
}
}
}
}
return X;
}
/** Least squares solution of A*X = B
@param B A Matrix with as many rows as A and any number of columns.
@return X that minimizes the two norm of Q*R*X-B.
@exception IllegalArgumentException Matrix row dimensions must agree.
@exception RuntimeException Matrix is rank deficient.
*/
public Matrix solve (Matrix B) {
if (B.getRowDimension() != m) {
throw new IllegalArgumentException("Matrix row dimensions must agree.");
}
if (!this.isFullRank()) {
throw new RuntimeException("Matrix is rank deficient.");
}
// Copy right hand side
int nx = B.getColumnDimension();
double[][] X = B.getArrayCopy();
// Compute Y = transpose(Q)*B
for (int k = 0; k < n; k++) {
for (int j = 0; j < nx; j++) {
double s = 0.0;
for (int i = k; i < m; i++) {
s += QR[i][k]*X[i][j];
}
s = -s/QR[k][k];
for (int i = k; i < m; i++) {
X[i][j] += s*QR[i][k];
}
}
}
// Solve R*X = Y;
for (int k = n-1; k >= 0; k--) {
for (int j = 0; j < nx; j++) {
X[k][j] /= Rdiag[k];
}
for (int i = 0; i < k; i++) {
for (int j = 0; j < nx; j++) {
X[i][j] -= X[k][j]*QR[i][k];
}
}
}
return (new Matrix(X,n,nx).getMatrix(0,n-1,0,nx-1));
}
}
source/jama/SingularValueDecomposition.java 000644 00000037442 11640633466 0015100 0 ustar package jama;
import jama.util.*;
/** Singular Value Decomposition.
For an m-by-n matrix A with m >= n, the singular value decomposition is
an m-by-n orthogonal matrix U, an n-by-n diagonal matrix S, and
an n-by-n orthogonal matrix V so that A = U*S*V'.
The singular values, sigma[k] = S[k][k], are ordered so that
sigma[0] >= sigma[1] >= ... >= sigma[n-1].
The singular value decompostion always exists, so the constructor will
never fail. The matrix condition number and the effective numerical
rank can be computed from this decomposition.
*/
public class SingularValueDecomposition implements java.io.Serializable {
/* ------------------------
Class variables
* ------------------------ */
/** Arrays for internal storage of U and V.
@serial internal storage of U.
@serial internal storage of V.
*/
private double[][] U, V;
/** Array for internal storage of singular values.
@serial internal storage of singular values.
*/
private double[] s;
/** Row and column dimensions.
@serial row dimension.
@serial column dimension.
*/
private int m, n;
/* ------------------------
Constructor
* ------------------------ */
/** Construct the singular value decomposition
@param A Rectangular matrix
@return Structure to access U, S and V.
*/
public SingularValueDecomposition (Matrix Arg) {
// Derived from LINPACK code.
// Initialize.
double[][] A = Arg.getArrayCopy();
m = Arg.getRowDimension();
n = Arg.getColumnDimension();
/* Apparently the failing cases are only a proper subset of (m= n"); }
*/
int nu = Math.min(m,n);
s = new double [Math.min(m+1,n)];
U = new double [m][nu];
V = new double [n][n];
double[] e = new double [n];
double[] work = new double [m];
boolean wantu = true;
boolean wantv = true;
// Reduce A to bidiagonal form, storing the diagonal elements
// in s and the super-diagonal elements in e.
int nct = Math.min(m-1,n);
int nrt = Math.max(0,Math.min(n-2,m));
for (int k = 0; k < Math.max(nct,nrt); k++) {
if (k < nct) {
// Compute the transformation for the k-th column and
// place the k-th diagonal in s[k].
// Compute 2-norm of k-th column without under/overflow.
s[k] = 0;
for (int i = k; i < m; i++) {
s[k] = Maths.hypot(s[k],A[i][k]);
}
if (s[k] != 0.0) {
if (A[k][k] < 0.0) {
s[k] = -s[k];
}
for (int i = k; i < m; i++) {
A[i][k] /= s[k];
}
A[k][k] += 1.0;
}
s[k] = -s[k];
}
for (int j = k+1; j < n; j++) {
if ((k < nct) & (s[k] != 0.0)) {
// Apply the transformation.
double t = 0;
for (int i = k; i < m; i++) {
t += A[i][k]*A[i][j];
}
t = -t/A[k][k];
for (int i = k; i < m; i++) {
A[i][j] += t*A[i][k];
}
}
// Place the k-th row of A into e for the
// subsequent calculation of the row transformation.
e[j] = A[k][j];
}
if (wantu & (k < nct)) {
// Place the transformation in U for subsequent back
// multiplication.
for (int i = k; i < m; i++) {
U[i][k] = A[i][k];
}
}
if (k < nrt) {
// Compute the k-th row transformation and place the
// k-th super-diagonal in e[k].
// Compute 2-norm without under/overflow.
e[k] = 0;
for (int i = k+1; i < n; i++) {
e[k] = Maths.hypot(e[k],e[i]);
}
if (e[k] != 0.0) {
if (e[k+1] < 0.0) {
e[k] = -e[k];
}
for (int i = k+1; i < n; i++) {
e[i] /= e[k];
}
e[k+1] += 1.0;
}
e[k] = -e[k];
if ((k+1 < m) & (e[k] != 0.0)) {
// Apply the transformation.
for (int i = k+1; i < m; i++) {
work[i] = 0.0;
}
for (int j = k+1; j < n; j++) {
for (int i = k+1; i < m; i++) {
work[i] += e[j]*A[i][j];
}
}
for (int j = k+1; j < n; j++) {
double t = -e[j]/e[k+1];
for (int i = k+1; i < m; i++) {
A[i][j] += t*work[i];
}
}
}
if (wantv) {
// Place the transformation in V for subsequent
// back multiplication.
for (int i = k+1; i < n; i++) {
V[i][k] = e[i];
}
}
}
}
// Set up the final bidiagonal matrix or order p.
int p = Math.min(n,m+1);
if (nct < n) {
s[nct] = A[nct][nct];
}
if (m < p) {
s[p-1] = 0.0;
}
if (nrt+1 < p) {
e[nrt] = A[nrt][p-1];
}
e[p-1] = 0.0;
// If required, generate U.
if (wantu) {
for (int j = nct; j < nu; j++) {
for (int i = 0; i < m; i++) {
U[i][j] = 0.0;
}
U[j][j] = 1.0;
}
for (int k = nct-1; k >= 0; k--) {
if (s[k] != 0.0) {
for (int j = k+1; j < nu; j++) {
double t = 0;
for (int i = k; i < m; i++) {
t += U[i][k]*U[i][j];
}
t = -t/U[k][k];
for (int i = k; i < m; i++) {
U[i][j] += t*U[i][k];
}
}
for (int i = k; i < m; i++ ) {
U[i][k] = -U[i][k];
}
U[k][k] = 1.0 + U[k][k];
for (int i = 0; i < k-1; i++) {
U[i][k] = 0.0;
}
} else {
for (int i = 0; i < m; i++) {
U[i][k] = 0.0;
}
U[k][k] = 1.0;
}
}
}
// If required, generate V.
if (wantv) {
for (int k = n-1; k >= 0; k--) {
if ((k < nrt) & (e[k] != 0.0)) {
for (int j = k+1; j < nu; j++) {
double t = 0;
for (int i = k+1; i < n; i++) {
t += V[i][k]*V[i][j];
}
t = -t/V[k+1][k];
for (int i = k+1; i < n; i++) {
V[i][j] += t*V[i][k];
}
}
}
for (int i = 0; i < n; i++) {
V[i][k] = 0.0;
}
V[k][k] = 1.0;
}
}
// Main iteration loop for the singular values.
int pp = p-1;
int iter = 0;
double eps = Math.pow(2.0,-52.0);
double tiny = Math.pow(2.0,-966.0);
while (p > 0) {
int k,kase;
// Here is where a test for too many iterations would go.
// This section of the program inspects for
// negligible elements in the s and e arrays. On
// completion the variables kase and k are set as follows.
// kase = 1 if s(p) and e[k-1] are negligible and k= -1; k--) {
if (k == -1) {
break;
}
if (Math.abs(e[k]) <=
tiny + eps*(Math.abs(s[k]) + Math.abs(s[k+1]))) {
e[k] = 0.0;
break;
}
}
if (k == p-2) {
kase = 4;
} else {
int ks;
for (ks = p-1; ks >= k; ks--) {
if (ks == k) {
break;
}
double t = (ks != p ? Math.abs(e[ks]) : 0.) +
(ks != k+1 ? Math.abs(e[ks-1]) : 0.);
if (Math.abs(s[ks]) <= tiny + eps*t) {
s[ks] = 0.0;
break;
}
}
if (ks == k) {
kase = 3;
} else if (ks == p-1) {
kase = 1;
} else {
kase = 2;
k = ks;
}
}
k++;
// Perform the task indicated by kase.
switch (kase) {
// Deflate negligible s(p).
case 1: {
double f = e[p-2];
e[p-2] = 0.0;
for (int j = p-2; j >= k; j--) {
double t = Maths.hypot(s[j],f);
double cs = s[j]/t;
double sn = f/t;
s[j] = t;
if (j != k) {
f = -sn*e[j-1];
e[j-1] = cs*e[j-1];
}
if (wantv) {
for (int i = 0; i < n; i++) {
t = cs*V[i][j] + sn*V[i][p-1];
V[i][p-1] = -sn*V[i][j] + cs*V[i][p-1];
V[i][j] = t;
}
}
}
}
break;
// Split at negligible s(k).
case 2: {
double f = e[k-1];
e[k-1] = 0.0;
for (int j = k; j < p; j++) {
double t = Maths.hypot(s[j],f);
double cs = s[j]/t;
double sn = f/t;
s[j] = t;
f = -sn*e[j];
e[j] = cs*e[j];
if (wantu) {
for (int i = 0; i < m; i++) {
t = cs*U[i][j] + sn*U[i][k-1];
U[i][k-1] = -sn*U[i][j] + cs*U[i][k-1];
U[i][j] = t;
}
}
}
}
break;
// Perform one qr step.
case 3: {
// Calculate the shift.
double scale = Math.max(Math.max(Math.max(Math.max(
Math.abs(s[p-1]),Math.abs(s[p-2])),Math.abs(e[p-2])),
Math.abs(s[k])),Math.abs(e[k]));
double sp = s[p-1]/scale;
double spm1 = s[p-2]/scale;
double epm1 = e[p-2]/scale;
double sk = s[k]/scale;
double ek = e[k]/scale;
double b = ((spm1 + sp)*(spm1 - sp) + epm1*epm1)/2.0;
double c = (sp*epm1)*(sp*epm1);
double shift = 0.0;
if ((b != 0.0) | (c != 0.0)) {
shift = Math.sqrt(b*b + c);
if (b < 0.0) {
shift = -shift;
}
shift = c/(b + shift);
}
double f = (sk + sp)*(sk - sp) + shift;
double g = sk*ek;
// Chase zeros.
for (int j = k; j < p-1; j++) {
double t = Maths.hypot(f,g);
double cs = f/t;
double sn = g/t;
if (j != k) {
e[j-1] = t;
}
f = cs*s[j] + sn*e[j];
e[j] = cs*e[j] - sn*s[j];
g = sn*s[j+1];
s[j+1] = cs*s[j+1];
if (wantv) {
for (int i = 0; i < n; i++) {
t = cs*V[i][j] + sn*V[i][j+1];
V[i][j+1] = -sn*V[i][j] + cs*V[i][j+1];
V[i][j] = t;
}
}
t = Maths.hypot(f,g);
cs = f/t;
sn = g/t;
s[j] = t;
f = cs*e[j] + sn*s[j+1];
s[j+1] = -sn*e[j] + cs*s[j+1];
g = sn*e[j+1];
e[j+1] = cs*e[j+1];
if (wantu && (j < m-1)) {
for (int i = 0; i < m; i++) {
t = cs*U[i][j] + sn*U[i][j+1];
U[i][j+1] = -sn*U[i][j] + cs*U[i][j+1];
U[i][j] = t;
}
}
}
e[p-2] = f;
iter = iter + 1;
}
break;
// Convergence.
case 4: {
// Make the singular values positive.
if (s[k] <= 0.0) {
s[k] = (s[k] < 0.0 ? -s[k] : 0.0);
if (wantv) {
for (int i = 0; i <= pp; i++) {
V[i][k] = -V[i][k];
}
}
}
// Order the singular values.
while (k < pp) {
if (s[k] >= s[k+1]) {
break;
}
double t = s[k];
s[k] = s[k+1];
s[k+1] = t;
if (wantv && (k < n-1)) {
for (int i = 0; i < n; i++) {
t = V[i][k+1]; V[i][k+1] = V[i][k]; V[i][k] = t;
}
}
if (wantu && (k < m-1)) {
for (int i = 0; i < m; i++) {
t = U[i][k+1]; U[i][k+1] = U[i][k]; U[i][k] = t;
}
}
k++;
}
iter = 0;
p--;
}
break;
}
}
}
/* ------------------------
Public Methods
* ------------------------ */
/** Return the left singular vectors
@return U
*/
public Matrix getU () {
return new Matrix(U,m,Math.min(m+1,n));
}
/** Return the right singular vectors
@return V
*/
public Matrix getV () {
return new Matrix(V,n,n);
}
/** Return the one-dimensional array of singular values
@return diagonal of S.
*/
public double[] getSingularValues () {
return s;
}
/** Return the diagonal matrix of singular values
@return S
*/
public Matrix getS () {
Matrix X = new Matrix(n,n);
double[][] S = X.getArray();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
S[i][j] = 0.0;
}
S[i][i] = this.s[i];
}
return X;
}
/** Two norm
@return max(S)
*/
public double norm2 () {
return s[0];
}
/** Two norm condition number
@return max(S)/min(S)
*/
public double cond () {
return s[0]/s[Math.min(m,n)-1];
}
/** Effective numerical matrix rank
@return Number of nonnegligible singular values.
*/
public int rank () {
double eps = Math.pow(2.0,-52.0);
double tol = Math.max(m,n)*s[0]*eps;
int r = 0;
for (int i = 0; i < s.length; i++) {
if (s[i] > tol) {
r++;
}
}
return r;
}
}
source/jama/util/ 000755 00000000000 11651624136 0007656 5 ustar source/jama/util/Maths.java 000644 00000000706 11446723636 0011607 0 ustar package jama.util;
public class Maths {
/** sqrt(a^2 + b^2) without under/overflow. **/
public static double hypot(double a, double b) {
double r;
if (Math.abs(a) > Math.abs(b)) {
r = b/a;
r = Math.abs(a)*Math.sqrt(1+r*r);
} else if (b != 0) {
r = a/b;
r = Math.abs(b)*Math.sqrt(1+r*r);
} else {
r = 0.0;
}
return r;
}
}
source/jgromacs/ 000755 00000000000 11651624136 0007576 5 ustar source/jgromacs/analysis/ 000755 00000000000 11651624136 0011421 5 ustar source/jgromacs/analysis/Angles.java 000644 00000045174 11647040056 0013506 0 ustar /**
*
* Written by Márton Münz and Philip C Biggin
* Copyright (c) University of Oxford, United Kingdom
* Visit http://sbcb.bioch.ox.ac.uk/jgromacs/
*
* This source code file is part of JGromacs v1.0.
*
* JGromacs v1.0 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* JGromacs v1.0. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with JGromacs v1.0. If not, see .
*
*/
package jgromacs.analysis;
import java.util.ArrayList;
import jama.Matrix;
import jgromacs.data.Angle;
import jgromacs.data.Point3D;
import jgromacs.data.Residue;
import jgromacs.data.Structure;
import jgromacs.data.Trajectory;
/**
* Collection of methods for analysing angles
*
*/
public class Angles {
/**
* Calculates the angle between two vectors
* @param v1 first vector
* @param v2 second vector
* @return angle between vectors
*/
public static Angle getAngleBetweenVectors(Point3D v1, Point3D v2){
double inner = v1.innerProduct(v2);
double lengths = v1.length()*v2.length();
double angleInRad = Math.acos(inner/lengths);
Angle ret = new Angle();
ret.setInRadians(angleInRad);
return ret;
}
/**
* Calculates the angle between two planes defined by points A, B, C and points B, C, D
* @param A point A
* @param B point B
* @param C point C
* @param D point D
* @return angle between planes
*/
public static Angle getAngleBetweenPlanes(Point3D A, Point3D B, Point3D C, Point3D D){
Point3D normal1 = getNormalVectorOfPlane(B, A, C);
Point3D normal2 = getNormalVectorOfPlane(C, B, D);
return getAngleBetweenVectors(normal1, normal2);
}
/**
* Calculates the normal vector of a plane defined by the C,A and C,B vectors
* @param C point C
* @param A point A
* @param B point B
* @return normal vector
*/
private static Point3D getNormalVectorOfPlane(Point3D C, Point3D A, Point3D B){
Point3D v1 = A.minus(C);
Point3D v2 = B.minus(C);
return v1.crossProduct(v2);
}
/**
* Calculates dihedral angle Phi of residue #i of a structure
* @param s structure
* @return dihedral angle Phi
*/
public static Angle getDihedralPhi(Structure s, int i){
if (i<=0) return new Angle();
Residue res = s.getResidue(i);
Residue resMinus = s.getResidue(i-1);
Point3D A = resMinus.getCTerminalCarbon().getCoordinates();
Point3D B = res.getNTerminalNitrogen().getCoordinates();
Point3D C = res.getAlphaCarbon().getCoordinates();
Point3D D = res.getCTerminalCarbon().getCoordinates();
Point3D b1 = B.minus(A);
Point3D b2 = C.minus(B);
Point3D b3 = D.minus(C);
double x = (b1.multiplyByScalar(b2.length())).innerProduct(b2.crossProduct(b3));
double y = (b1.crossProduct(b2)).innerProduct(b2.crossProduct(b3));
double angle = Math.atan2(x, y);
Angle ret = new Angle();
ret.setInRadians(angle);
return ret;
}
/**
* Calculates dihedral angle Psi of residue #i of a structure
* @param s structure
* @return dihedral angle Psi
*/
public static Angle getDihedralPsi(Structure s, int i){
if (i>=s.getNumberOfResidues()) return new Angle();
Residue res = s.getResidue(i);
Residue resPlus = s.getResidue(i+1);
Point3D A = res.getNTerminalNitrogen().getCoordinates();
Point3D B = res.getAlphaCarbon().getCoordinates();
Point3D C = res.getCTerminalCarbon().getCoordinates();
Point3D D = resPlus.getNTerminalNitrogen().getCoordinates();
Point3D b1 = B.minus(A);
Point3D b2 = C.minus(B);
Point3D b3 = D.minus(C);
double x = (b1.multiplyByScalar(b2.length())).innerProduct(b2.crossProduct(b3));
double y = (b1.crossProduct(b2)).innerProduct(b2.crossProduct(b3));
double angle = Math.atan2(x, y);
Angle ret = new Angle();
ret.setInRadians(angle);
return ret;
}
/**
* Calculates dihedral angle Omega of residue #i of a structure
* @param s structure
* @return dihedral angle Omega
*/
public static Angle getDihedralOmega(Structure s, int i){
if (i>=s.getNumberOfResidues()) return new Angle();
Residue res = s.getResidue(i);
Residue resPlus = s.getResidue(i+1);
Point3D A = res.getAlphaCarbon().getCoordinates();
Point3D B = res.getCTerminalCarbon().getCoordinates();
Point3D C = resPlus.getNTerminalNitrogen().getCoordinates();
Point3D D = resPlus.getAlphaCarbon().getCoordinates();
Point3D b1 = B.minus(A);
Point3D b2 = C.minus(B);
Point3D b3 = D.minus(C);
double x = (b1.multiplyByScalar(b2.length())).innerProduct(b2.crossProduct(b3));
double y = (b1.crossProduct(b2)).innerProduct(b2.crossProduct(b3));
double angle = Math.atan2(x, y);
Angle ret = new Angle();
ret.setInRadians(angle);
return ret;
}
/**
* Calculates side chain dihedral angle Chi1 of residue #i of a structure
* The residue can be ARG,ASN,ASP,CYS,GLN,GLU,HIS,ILE,LEU,LYS,MET,PHE,PRO,SER,THR,TRP,TYR or VAL
* @param s structure
* @return dihedral angle Chi1
*/
public static Angle getDihedralChi1(Structure s, int i){
Residue res = s.getResidue(i);
String code = res.getResidueType().get3LetterCode().toUpperCase();
if (code.equals("ALA")||code.equals("GLY")) return null;
Point3D A = res.getNTerminalNitrogen().getCoordinates();
Point3D B = res.getAlphaCarbon().getCoordinates();
Point3D C = res.getBetaCarbon().getCoordinates();
Point3D D = new Point3D();
if (code.equals("ARG")) D = res.getGammaCarbon().getCoordinates();
else if (code.equals("ASN")) D = res.getGammaCarbon().getCoordinates();
else if (code.equals("ASP")) D = res.getGammaCarbon().getCoordinates();
else if (code.equals("CYS")) D = res.getAtomByName("SG").getCoordinates();
else if (code.equals("GLN")) D = res.getGammaCarbon().getCoordinates();
else if (code.equals("GLU")) D = res.getGammaCarbon().getCoordinates();
else if (code.equals("HIS")) D = res.getGammaCarbon().getCoordinates();
else if (code.equals("ILE")) D = res.getAtomByName("CG1").getCoordinates();
else if (code.equals("LEU")) D = res.getGammaCarbon().getCoordinates();
else if (code.equals("LYS")) D = res.getGammaCarbon().getCoordinates();
else if (code.equals("MET")) D = res.getGammaCarbon().getCoordinates();
else if (code.equals("PHE")) D = res.getGammaCarbon().getCoordinates();
else if (code.equals("PRO")) D = res.getGammaCarbon().getCoordinates();
else if (code.equals("SER")) D = res.getAtomByName("OG").getCoordinates();
else if (code.equals("THR")) D = res.getAtomByName("OG1").getCoordinates();
else if (code.equals("TRP")) D = res.getGammaCarbon().getCoordinates();
else if (code.equals("TYR")) D = res.getGammaCarbon().getCoordinates();
else if (code.equals("VAL")) D = res.getAtomByName("CG1").getCoordinates();
else return null;
Point3D b1 = B.minus(A);
Point3D b2 = C.minus(B);
Point3D b3 = D.minus(C);
double x = (b1.multiplyByScalar(b2.length())).innerProduct(b2.crossProduct(b3));
double y = (b1.crossProduct(b2)).innerProduct(b2.crossProduct(b3));
double angle = Math.atan2(x, y);
Angle ret = new Angle();
ret.setInRadians(angle);
return ret;
}
/**
* Calculates side chain dihedral angle Chi2 of residue #i of a structure
* The residue can only be ARG,ASN,ASP,GLN,GLU,HIS,ILE,LEU,LYS,MET,PHE,PRO,TRP or TYR
* @param s structure
* @return dihedral angle Chi2
*/
public static Angle getDihedralChi2(Structure s, int i){
Residue res = s.getResidue(i);
String code = res.getResidueType().get3LetterCode().toUpperCase();
if (code.equals("ALA")||code.equals("GLY")||code.equals("CYS")||code.equals("SER")||code.equals("THR")||code.equals("VAL")) return null;
Point3D A = res.getAlphaCarbon().getCoordinates();
Point3D B = res.getBetaCarbon().getCoordinates();
Point3D C;
if (code.equals("ILE")) C = res.getAtomByName("CG1").getCoordinates();
else C = res.getGammaCarbon().getCoordinates();
Point3D D = new Point3D();
if (code.equals("ARG")) D = res.getDeltaCarbon().getCoordinates();
if (code.equals("ASN")) D = res.getAtomByName("OD1").getCoordinates();
if (code.equals("ASP")) D = res.getAtomByName("OD1").getCoordinates();
if (code.equals("GLN")) D = res.getDeltaCarbon().getCoordinates();
if (code.equals("GLU")) D = res.getDeltaCarbon().getCoordinates();
if (code.equals("HIS")) D = res.getAtomByName("ND1").getCoordinates();
if (code.equals("ILE")) D = res.getDeltaCarbon().getCoordinates();
if (code.equals("LEU")) D = res.getAtomByName("CD1").getCoordinates();
if (code.equals("LYS")) D = res.getDeltaCarbon().getCoordinates();
if (code.equals("MET")) D = res.getAtomByName("SD").getCoordinates();
if (code.equals("PHE")) D = res.getAtomByName("CD1").getCoordinates();
if (code.equals("PRO")) D = res.getDeltaCarbon().getCoordinates();
if (code.equals("TRP")) D = res.getAtomByName("CD1").getCoordinates();
if (code.equals("TYR")) D = res.getAtomByName("CD1").getCoordinates();
Point3D b1 = B.minus(A);
Point3D b2 = C.minus(B);
Point3D b3 = D.minus(C);
double x = (b1.multiplyByScalar(b2.length())).innerProduct(b2.crossProduct(b3));
double y = (b1.crossProduct(b2)).innerProduct(b2.crossProduct(b3));
double angle = Math.atan2(x, y);
Angle ret = new Angle();
ret.setInRadians(angle);
return ret;
}
/**
* Calculates side chain dihedral angle Chi3 of residue #i of a structure
* The residue can only be ARG,GLN,GLU,LYS or MET
* @param s structure
* @return dihedral angle Chi3
*/
public static Angle getDihedralChi3(Structure s, int i){
Residue res = s.getResidue(i);
String code = res.getResidueType().get3LetterCode().toUpperCase();
if (!(code.equals("ARG")||code.equals("GLN")||code.equals("GLU")||code.equals("LYS")||code.equals("MET"))) return null;
Point3D A = res.getBetaCarbon().getCoordinates();
Point3D B = res.getGammaCarbon().getCoordinates();
Point3D C = new Point3D();
Point3D D = new Point3D();
if (code.equals("ARG")) {
C = res.getDeltaCarbon().getCoordinates();
D = res.getAtomByName("NE").getCoordinates();
}
if (code.equals("GLN")) {
C = res.getDeltaCarbon().getCoordinates();
D = res.getAtomByName("OE1").getCoordinates();
}
if (code.equals("GLU")) {
C = res.getDeltaCarbon().getCoordinates();
D = res.getAtomByName("OE1").getCoordinates();
}
if (code.equals("LYS")) {
C = res.getDeltaCarbon().getCoordinates();
D = res.getAtomByName("CE").getCoordinates();
}
if (code.equals("MET")) {
C = res.getAtomByName("SD").getCoordinates();
D = res.getAtomByName("CE").getCoordinates();
}
Point3D b1 = B.minus(A);
Point3D b2 = C.minus(B);
Point3D b3 = D.minus(C);
double x = (b1.multiplyByScalar(b2.length())).innerProduct(b2.crossProduct(b3));
double y = (b1.crossProduct(b2)).innerProduct(b2.crossProduct(b3));
double angle = Math.atan2(x, y);
Angle ret = new Angle();
ret.setInRadians(angle);
return ret;
}
/**
* Calculates side chain dihedral angle Chi4 of residue #i of a structure
* The residue can only be ARG or LYS
* @param s structure
* @return dihedral angle Chi4
*/
public static Angle getDihedralChi4(Structure s, int i){
Residue res = s.getResidue(i);
String code = res.getResidueType().get3LetterCode().toUpperCase();
if (!(code.equals("ARG")||code.equals("LYS"))) return null;
Point3D A = res.getGammaCarbon().getCoordinates();
Point3D B = res.getDeltaCarbon().getCoordinates();
Point3D C = new Point3D();
Point3D D = new Point3D();
if (code.equals("ARG")) {
C = res.getAtomByName("NE").getCoordinates();
D = res.getAtomByName("CZ").getCoordinates();
}
if (code.equals("LYS")) {
C = res.getAtomByName("CE").getCoordinates();
D = res.getAtomByName("NZ").getCoordinates();
}
Point3D b1 = B.minus(A);
Point3D b2 = C.minus(B);
Point3D b3 = D.minus(C);
double x = (b1.multiplyByScalar(b2.length())).innerProduct(b2.crossProduct(b3));
double y = (b1.crossProduct(b2)).innerProduct(b2.crossProduct(b3));
double angle = Math.atan2(x, y);
Angle ret = new Angle();
ret.setInRadians(angle);
return ret;
}
/**
* Calculates side chain dihedral angle Chi5 of residue #i of a structure
* The residue can only be ARG
* @param s structure
* @return dihedral angle Chi5
*/
public static Angle getDihedralChi5(Structure s, int i){
Residue res = s.getResidue(i);
String code = res.getResidueType().get3LetterCode().toUpperCase();
if (code.equals("ARG")){
Point3D A = res.getDeltaCarbon().getCoordinates();
Point3D B = res.getAtomByName("NE").getCoordinates();
Point3D C = res.getAtomByName("CZ").getCoordinates();
Point3D D = res.getAtomByName("NH1").getCoordinates();
Point3D b1 = B.minus(A);
Point3D b2 = C.minus(B);
Point3D b3 = D.minus(C);
double x = (b1.multiplyByScalar(b2.length())).innerProduct(b2.crossProduct(b3));
double y = (b1.crossProduct(b2)).innerProduct(b2.crossProduct(b3));
double angle = Math.atan2(x, y);
Angle ret = new Angle();
ret.setInRadians(angle);
return ret;
}
else return null;
}
/**
* Calculates the time series of dihedral angle Phi of residue #i over a trajectory
* @param t trajectory
* @return time series of Phi
*/
public static ArrayList getDihedralPhiTimeSeries(Trajectory t, int i){
ArrayList ret = new ArrayList();
for (int k = 0; k < t.getNumberOfFrames(); k++) {
Structure frame = t.getFrameAsStructure(k);
ret.add(getDihedralPhi(frame, i));
}
return ret;
}
/**
* Calculates the time series of dihedral angle Psi of residue #i over a trajectory
* @param t trajectory
* @return time series of Psi
*/
public static ArrayList getDihedralPsiTimeSeries(Trajectory t, int i){
ArrayList ret = new ArrayList();
for (int k = 0; k < t.getNumberOfFrames(); k++) {
Structure frame = t.getFrameAsStructure(k);
ret.add(getDihedralPsi(frame, i));
}
return ret;
}
/**
* Calculates the time series of dihedral angle Omega of residue #i over a trajectory
* @param t trajectory
* @return time series of Omega
*/
public static ArrayList getDihedralOmegaTimeSeries(Trajectory t, int i){
ArrayList ret = new ArrayList();
for (int k = 0; k < t.getNumberOfFrames(); k++) {
Structure frame = t.getFrameAsStructure(k);
ret.add(getDihedralOmega(frame, i));
}
return ret;
}
/**
* Calculates the time series of dihedral angle Chi1 of residue #i over a trajectory
* The residue can be ARG,ASN,ASP,CYS,GLN,GLU,HIS,ILE,LEU,LYS,MET,PHE,PRO,SER,THR,TRP,TYR or VAL
* @param t trajectory
* @return time series of Chi1
*/
public static ArrayList getDihedralChi1TimeSeries(Trajectory t, int i){
ArrayList ret = new ArrayList();
for (int k = 0; k < t.getNumberOfFrames(); k++) {
Structure frame = t.getFrameAsStructure(k);
ret.add(getDihedralChi1(frame, i));
}
return ret;
}
/**
* Calculates the time series of dihedral angle Chi2 of residue #i over a trajectory
* The residue can only be ARG,ASN,ASP,GLN,GLU,HIS,ILE,LEU,LYS,MET,PHE,PRO,TRP or TYR
* @param t trajectory
* @return time series of Chi2
*/
public static ArrayList getDihedralChi2TimeSeries(Trajectory t, int i){
ArrayList ret = new ArrayList();
for (int k = 0; k < t.getNumberOfFrames(); k++) {
Structure frame = t.getFrameAsStructure(k);
ret.add(getDihedralChi2(frame, i));
}
return ret;
}
/**
* Calculates the time series of dihedral angle Chi3 of residue #i over a trajectory
* The residue can only be ARG,GLN,GLU,LYS or MET
* @param t trajectory
* @return time series of Chi3
*/
public static ArrayList getDihedralChi3TimeSeries(Trajectory t, int i){
ArrayList ret = new ArrayList();
for (int k = 0; k < t.getNumberOfFrames(); k++) {
Structure frame = t.getFrameAsStructure(k);
ret.add(getDihedralChi3(frame, i));
}
return ret;
}
/**
* Calculates the time series of dihedral angle Chi4 of residue #i over a trajectory
* The residue can only be ARG or LYS
* @param t trajectory
* @return time series of Chi4
*/
public static ArrayList getDihedralChi4TimeSeries(Trajectory t, int i){
ArrayList ret = new ArrayList();
for (int k = 0; k < t.getNumberOfFrames(); k++) {
Structure frame = t.getFrameAsStructure(k);
ret.add(getDihedralChi4(frame, i));
}
return ret;
}
/**
* Calculates the time series of dihedral angle Chi5 of residue #i over a trajectory
* The residue can only be ARG
* @param t trajectory
* @return time series of Chi5
*/
public static ArrayList getDihedralChi5TimeSeries(Trajectory t, int i){
ArrayList ret = new ArrayList();
for (int k = 0; k < t.getNumberOfFrames(); k++) {
Structure frame = t.getFrameAsStructure(k);
ret.add(getDihedralChi5(frame, i));
}
return ret;
}
/**
* Calculates the time series of torsion angle over a trajectory defined by four atoms
* @param t trajectory
* @param atom1 index of first atom
* @param atom2 index of second atom
* @param atom3 index of third atom
* @param atom4 index of fourth atom
* @return time series of torsion angle
*/
public static ArrayList getTorsionAngleTimeSeries(Trajectory t, int atom1, int atom2, int atom3, int atom4){
ArrayList ret = new ArrayList();
for (int k = 0; k < t.getNumberOfFrames(); k++) {
Structure frame = t.getFrameAsStructure(k);
Point3D A = frame.getAtomByIndex(atom1).getCoordinates();
Point3D B = frame.getAtomByIndex(atom2).getCoordinates();
Point3D C = frame.getAtomByIndex(atom3).getCoordinates();
Point3D D = frame.getAtomByIndex(atom4).getCoordinates();
ret.add(getAngleBetweenPlanes(A, B, C, D));
}
return ret;
}
/**
* Calculates the Ramachandran Plot of a structure
* @param s structure (a polypeptide chain)
* @return (N-2)x2 matrix of (phi,psi) pairs
*/
public static Matrix getRamachandranPlot(Structure s){
Matrix ret = new Matrix(s.getNumberOfResidues()-2,2);
for (int i = 1; i < s.getNumberOfResidues()-1; i++) {
Angle phi = getDihedralPhi(s, i);
Angle psi = getDihedralPsi(s, i);
ret.set(i-1, 0, phi.getInDegrees());
ret.set(i-1, 1, psi.getInDegrees());
}
return ret;
}
}
source/jgromacs/analysis/Distances.java 000644 00000062056 11645275612 0014216 0 ustar /**
*
* Written by Márton Münz and Philip C Biggin
* Copyright (c) University of Oxford, United Kingdom
* Visit http://sbcb.bioch.ox.ac.uk/jgromacs/
*
* This source code file is part of JGromacs v1.0.
*
* JGromacs v1.0 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* JGromacs v1.0. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with JGromacs v1.0. If not, see .
*
*/
package jgromacs.analysis;
import java.util.ArrayList;
import jgromacs.data.Atom;
import jgromacs.data.FrameIndexSet;
import jgromacs.data.IndexSet;
import jgromacs.data.Point3D;
import jgromacs.data.PointList;
import jgromacs.data.Residue;
import jgromacs.data.Structure;
import jgromacs.data.Trajectory;
import jama.Matrix;
/**
* Collection of methods for analysing distances
*
*/
public class Distances {
public static final int ALPHACARBON = 1;
public static final int CLOSEST = 2;
public static final int CLOSESTHEAVY = 3;
// Distance matrices
/**
* Calculates the distance matrix from a point list
* @param points point list
* @return distance matrix
*/
public static Matrix getDistanceMatrix(PointList points){
Matrix ret = new Matrix(points.getNumberOfPoints(),points.getNumberOfPoints(),0);
for (int i = 0; i < points.getNumberOfPoints(); i++) {
for (int j = i+1; j < points.getNumberOfPoints(); j++) {
ret.set(i, j, points.getPoint(i).distance(points.getPoint(j)));
ret.set(j, i, ret.get(i, j));
}
}
return ret;
}
/**
* Calculates the distance matrix of all atoms in a structure
* @param s structure
* @return distance matrix
*/
public static Matrix getAtomicDistanceMatrix(Structure s){
PointList points = s.getAllAtomCoordinates();
return getDistanceMatrix(points);
}
/**
* Calculates the distance matrix of atoms of given indices in a structure
* @param s structure
* @param indices index set
* @return distance matrix
*/
public static Matrix getAtomicDistanceMatrix(Structure s, IndexSet indices){
int dim = indices.getNumberOfIndices();
Matrix ret = new Matrix(dim,dim,0);
ArrayList indexList = indices.getAsArrayList();
for (int i = 0; i < dim; i++) {
Atom atomI = s.getAtomByIndex(indexList.get(i));
for (int j = i+1; j < dim; j++) {
Atom atomJ = s.getAtomByIndex(indexList.get(j));
ret.set(i, j, atomI.distance(atomJ));
ret.set(j, i, ret.get(i, j));
}
}
return ret;
}
/**
* Calculates the distance matrix between two sets of atoms
* @param s structure
* @param indices1 index set 1
* @param indices2 index set 2
* @return distance matrix
*/
public static Matrix getAtomicDistanceMatrix(Structure s, IndexSet indices1, IndexSet indices2){
int dim1 = indices1.getNumberOfIndices();
int dim2 = indices2.getNumberOfIndices();
Matrix ret = new Matrix(dim1,dim2,0);
ArrayList indexList1 = indices1.getAsArrayList();
ArrayList indexList2 = indices2.getAsArrayList();
for (int i = 0; i < dim1; i++) {
Atom atomI = s.getAtomByIndex(indexList1.get(i));
for (int j = 0; j < dim2; j++) {
Atom atomJ = s.getAtomByIndex(indexList2.get(j));
ret.set(i, j, atomI.distance(atomJ));
}
}
return ret;
}
/**
* Calculates the distance matrix of residues in a structure by the given method
* @param s structure
* @param distanceBetween which atoms are used for calculating the distances (ALPHACARBON: alpha carbon atoms,
* CLOSEST: closest atoms of two residues, CLOSESTHEAVY: closest heavy atoms of two residues)
* @return distance matrix
*/
public static Matrix getResidueDistanceMatrix(Structure s, int distanceBetween){
int dim = s.getNumberOfResidues();
Matrix ret = new Matrix(dim,dim,0);
for (int i = 0; i < dim; i++) {
Residue resI = s.getResidue(i);
for (int j = i+1; j < dim; j++) {
Residue resJ = s.getResidue(j);
double dist = 0;
if (distanceBetween==ALPHACARBON) dist = resI.distanceAlphaCarbons(resJ);
if (distanceBetween==CLOSEST) dist = resI.distanceClosest(resJ);
if (distanceBetween==CLOSESTHEAVY) dist = resI.distanceClosestHeavy(resJ);
ret.set(i, j, dist);
ret.set(j, i, dist);
}
}
return ret;
}
/**
* Calculates the mean distance matrix of all atoms in a trajectory
* @param t trajecotry
* @return mean distance matrix
*/
public static Matrix getMeanAtomicDistanceMatrix(Trajectory t){
int dim = t.getNumberOfAtoms();
Matrix ret = new Matrix(dim,dim,0);
for (int i = 0; i < t.getNumberOfFrames(); i++) {
PointList frame = t.getFrameAsPointList(i);
Matrix Di = getDistanceMatrix(frame);
ret = ret.plus(Di);
}
return ret.times(1.0/t.getNumberOfFrames());
}
/**
* Calculates the mean distance matrix of atoms of given indices in a trajectory
* @param t trajecotry
* @param indices index set
* @return mean distance matrix
*/
public static Matrix getMeanAtomicDistanceMatrix(Trajectory t, IndexSet indices){
ArrayList indexList = t.getFrameAsStructure(0).convertIndicesToArrayListIndices(indices);
int dim = indexList.size();
Matrix ret = new Matrix(dim,dim,0);
for (int i = 0; i < t.getNumberOfFrames(); i++) {
PointList frame = t.getFrameAsPointList(i).getSubList(indexList);
Matrix Di = getDistanceMatrix(frame);
ret = ret.plus(Di);
}
return ret.times(1.0/t.getNumberOfFrames());
}
/**
* Calculates the mean distance matrix of residues in a trajectory by the given method
* @param t trajectory
* @param distanceBetween which atoms are used for calculating the distances (ALPHACARBON: alpha carbon atoms,
* CLOSEST: closest atoms of two residues, CLOSESTHEAVY: closest heavy atoms of two residues)
* @return mean distance matrix
*/
public static Matrix getMeanResidueDistanceMatrix(Trajectory t, int distanceBetween){
int dim = t.getNumberOfResidues();
Matrix ret = new Matrix(dim,dim,0);
for (int i = 0; i < t.getNumberOfFrames(); i++) {
Structure frame = t.getFrameAsStructure(i);
Matrix Di = getResidueDistanceMatrix(frame, distanceBetween);
ret = ret.plus(Di);
}
return ret.times(1.0/t.getNumberOfFrames());
}
// Contact matrices
/**
* Calculates the contact matrix from a point list
* @param points point list
* @param cutoff distance cutoff
* @return contact matrix
*/
public static Matrix getContactMatrix(PointList points, double cutoff){
Matrix distM = getDistanceMatrix(points);
Matrix ret = new Matrix(distM.getRowDimension(),distM.getColumnDimension(),0);
for (int i = 0; i < distM.getRowDimension(); i++) {
for (int j = i; j < distM.getColumnDimension(); j++) {
if (distM.get(i, j)<=cutoff) ret.set(i, j, 1);
ret.set(j, i, ret.get(i, j));
}
}
return ret;
}
/**
* Calculates the contact matrix of residues in a structure by the given method
* @param s structure
* @param distanceBetween which atoms are used for calculating the distances (ALPHACARBON: alpha carbon atoms,
* CLOSEST: closest atoms of two residues, CLOSESTHEAVY: closest heavy atoms of two residues)
* @param cutoff distance cutoff
* @return contact matrix
*/
public static Matrix getContactMatrix(Structure s, int distanceBetween, double cutoff){
Matrix distM = getResidueDistanceMatrix(s,distanceBetween);
Matrix ret = new Matrix(distM.getRowDimension(),distM.getColumnDimension(),0);
for (int i = 0; i < distM.getRowDimension(); i++) {
for (int j = i; j < distM.getColumnDimension(); j++) {
if (distM.get(i, j)<=cutoff) ret.set(i, j, 1);
ret.set(j, i, ret.get(i, j));
}
}
return ret;
}
/**
* Calculates the contact matrix based on the mean residue distance matrix in a trajectory
* @param t trajectory
* @param distanceBetween which atoms are used for calculating the distances (ALPHACARBON: alpha carbon atoms,
* CLOSEST: closest atoms of two residues, CLOSESTHEAVY: closest heavy atoms of two residues)
* @param cutoff distance cutoff
* @return contact matrix
*/
public static Matrix getContactOfMeanMatrix(Trajectory t, int distanceBetween, double cutoff){
Matrix distM = getMeanResidueDistanceMatrix(t, distanceBetween);
Matrix ret = new Matrix(distM.getRowDimension(),distM.getColumnDimension(),0);
for (int i = 0; i < distM.getRowDimension(); i++) {
for (int j = i; j < distM.getColumnDimension(); j++) {
if (distM.get(i, j)<=cutoff) ret.set(i, j, 1);
ret.set(j, i, ret.get(i, j));
}
}
return ret;
}
/**
* Calculates the contact matrix of residues where two residues are said to be in contact if they are in contact
* in at least the given percentage of frames of the trajectory
* @param t trajectory
* @param distanceBetween which atoms are used for calculating the distances (ALPHACARBON: alpha carbon atoms,
* CLOSEST: closest atoms of two residues, CLOSESTHEAVY: closest heavy atoms of two residues)
* @param cutoff distance cutoff
* @param frequency minimal frequency of frames in which two residues are in contact
* @return contact matrix
*/
public static Matrix getFrequencyContactMatrix(Trajectory t, int distanceBetween, double cutoff, double frequency){
int dim = t.getNumberOfResidues();
Matrix ret = new Matrix(dim,dim,0);
for (int i = 0; i < t.getNumberOfFrames(); i++) {
Structure frame = t.getFrameAsStructure(i);
Matrix Ci = getContactMatrix(frame, distanceBetween, cutoff);
ret = ret.plus(Ci);
}
ret = ret.times(1.0/t.getNumberOfFrames());
for (int i = 0; i < dim; i++) {
for (int j = i+1; j < dim; j++) {
if (ret.get(i, j)>=frequency) ret.set(i, j, 1);
else ret.set(i, j, 0);
ret.set(j, i, ret.get(i, j));
}
}
return ret;
}
// Distance distributions / time series
/**
* Returns the time series of the distance of two atoms in a trajectory
* @param t trajectory
* @param atomindex1 index of first atom
* @param atomindex2 index of second atom
* @return time series of distance
*/
public static ArrayList getDistanceTimeSeries(Trajectory t, int atomindex1, int atomindex2){
ArrayList ret = new ArrayList();
IndexSet indices = new IndexSet();
indices.addIndex(atomindex1);
indices.addIndex(atomindex2);
ArrayList listindices = t.getFrameAsStructure(0).convertIndicesToArrayListIndices(indices);
int listIndex1 = listindices.get(0);
int listIndex2;
if (listindices.size()>1) listIndex2 = listindices.get(1);
else listIndex2=listIndex1;
for (int i = 0; i < t.getNumberOfFrames(); i++) {
Point3D point1 = t.getFrameAsPointList(i).getPoint(listIndex1);
Point3D point2 = t.getFrameAsPointList(i).getPoint(listIndex2);
double d = point1.distance(point2);
ret.add(d);
}
return ret;
}
/**
* Returns the time series of the distance of a single atom and a set of atoms in a trajectory
* @param t trajectory
* @param atomindex index of atom
* @param referenceset index set of reference atoms
* @return time series of distance
*/
public static ArrayList getDistanceTimeSeries(Trajectory t, int atomindex, IndexSet referenceset){
ArrayList ret = new ArrayList();
for (int i = 0; i < t.getNumberOfFrames(); i++) {
double d = Distances.getDistanceOfAtomToAtomSet(t.getFrameAsStructure(i), atomindex, referenceset);
ret.add(d);
}
return ret;
}
/**
* Returns the time series of the distance of two sets of atoms in a trajectory
* @param t trajectory
* @param indices1 first index set
* @param indices2 second index set
* @return time series of distance
*/
public static ArrayList getDistanceTimeSeries(Trajectory t, IndexSet indices1, IndexSet indices2){
ArrayList ret = new ArrayList();
for (int i = 0; i < t.getNumberOfFrames(); i++) {
double d = Distances.getDistanceOfTwoAtomSets(t.getFrameAsStructure(i), indices1, indices2);
ret.add(d);
}
return ret;
}
/**
* Returns the mean of the distance of two atoms in a trajectory
* @param t trajectory
* @param atomindex1 index of first atom
* @param atomindex2 index of second atom
* @return mean of distance
*/
public static double getMeanDistance(Trajectory t, int atomindex1, int atomindex2){
double ret = 0;
ArrayList distr = getDistanceTimeSeries(t, atomindex1, atomindex2);
for (int i = 0; i < distr.size(); i++) ret+=distr.get(i);
return ret/distr.size();
}
/**
* Returns the variance of the distance of two atoms in a trajectory
* @param t trajectory
* @param atomindex1 index of first atom
* @param atomindex2 index of second atom
* @return variance of distance
*/
public static double getVarianceOfDistance(Trajectory t, int atomindex1, int atomindex2){
double mean = 0;
ArrayList distr = getDistanceTimeSeries(t, atomindex1, atomindex2);
for (int i = 0; i < distr.size(); i++) mean+=distr.get(i);
mean = mean/distr.size();
double ret = 0;
for (int i = 0; i < distr.size(); i++) ret+=Math.pow(distr.get(i)-mean,2);
return ret/distr.size();
}
/**
* Returns the minimal distance of two atoms in a trajectory
* @param t trajectory
* @param atomindex1 index of first atom
* @param atomindex2 index of second atom
* @return minimal distance
*/
public static double getMinimalDistance(Trajectory t, int atomindex1, int atomindex2){
double ret = 999999;
ArrayList distr = getDistanceTimeSeries(t, atomindex1, atomindex2);
for (int i = 0; i < distr.size(); i++) {
double value = distr.get(i);
if (value distr = getDistanceTimeSeries(t, atomindex1, atomindex2);
for (int i = 0; i < distr.size(); i++) {
double value = distr.get(i);
if (value>ret) ret=value;
}
return ret;
}
/**
* Returns the range (max-min) of the distance of two atoms in a trajectory
* @param t trajectory
* @param atomindex1 index of first atom
* @param atomindex2 index of second atom
* @return size of distance interval
*/
public static double getDistanceRange(Trajectory t, int atomindex1, int atomindex2){
double min = 999999;
double max = -999999;
ArrayList distr = getDistanceTimeSeries(t, atomindex1, atomindex2);
for (int i = 0; i < distr.size(); i++) {
double value = distr.get(i);
if (value>max) max=value;
if (value atoms = atomIndices.getAsArrayList();
for (int j = 0; j < atoms.size(); j++) {
Atom atom = s.getAtomByIndex(atoms.get(j));
if (isInProximity(s, atom, referenceIndices, radius)) ret.addIndex(atom.getIndex());
}
return ret;
}
private static boolean isInProximity(Structure s, Atom atom, IndexSet referenceindices, double radius){
ArrayList indexList = s.convertIndicesToArrayListIndices(referenceindices);
for (int i = 0; i < indexList.size(); i++) {
int index = indexList.get(i);
if (s.getAtom(index).distance(atom)<=radius) return true;
}
return false;
}
// Misc
/**
* Returns the frame in which two atoms are closest to each other in a simulation
* @param t trajectory
* @param atomindex1 index of first atom
* @param atomindex2 index of second atom
* @return frame of trajectory
*/
public static PointList findFrameWhereClosest(Trajectory t, int atomindex1, int atomindex2){
int best = 0;
double min = 99999;
for (int i = 0; i < t.getNumberOfFrames(); i++) {
Structure frame = t.getFrameAsStructure(i);
double dist = frame.getAtomByIndex(atomindex1).distance(frame.getAtomByIndex(atomindex2));
if (distmax){
max = dist;
best = i;
}
}
return t.getFrameAsPointList(best);
}
/**
* Calculates the distance of an atom to a reference set of atoms (i.e. the minimum of all pairwise distances)
* @param s structure
* @param atomindex index of atom
* @param referenceset index set of reference atoms
* @return minimal distance
*/
public static double getDistanceOfAtomToAtomSet(Structure s, int atomindex, IndexSet referenceset){
double ret = 999999;
Atom atom = s.getAtomByIndex(atomindex);
ArrayList indexList = referenceset.getAsArrayList();
for (int i = 0; i < indexList.size(); i++) {
Atom refatom = s.getAtomByIndex(indexList.get(i));
double dist = atom.distance(refatom);
if (dist indexList1 = indices1.getAsArrayList();
ArrayList indexList2 = indices2.getAsArrayList();
for (int i = 0; i < indexList1.size(); i++) {
Atom atom1 = s.getAtomByIndex(indexList1.get(i));
for (int j = 0; j < indexList2.size(); j++) {
Atom atom2 = s.getAtomByIndex(indexList2.get(j));
double dist = atom1.distance(atom2);
if (dist indexList = atomset.getAsArrayList();
for (int i = 0; i < indexList.size(); i++) {
double dist = getDistanceOfAtomToAtomSet(s, indexList.get(i), referenceset);
if (dist=cutoff) ret.addFrame(i);
}
String name1 = atomindex1+t.getFirstFrameAsStructure().getAtomByIndex(atomindex1).getName();
String name2 = atomindex2+t.getFirstFrameAsStructure().getAtomByIndex(atomindex2).getName();
ret.setName("Distant["+cutoff+"]["+name1+","+name2+"]");
return ret;
}
/**
* Returns the list of frames in the trajectory where an atoms is closer to a reference point than a given cutoff
* @param t trajectory
* @param atomindex index of atom
* @param point reference point
* @param cutoff distance cutoff
* @return frame list
*/
public static FrameIndexSet getFramesWhereAtomIsCloseToPoint(Trajectory t, int atomindex, Point3D point, double cutoff){
FrameIndexSet ret = new FrameIndexSet();
for (int i = 0; i < t.getNumberOfFrames(); i++) {
Structure frame = t.getFrameAsStructure(i);
if (frame.getAtomByIndex(atomindex).getCoordinates().distance(point)<=cutoff) ret.addFrame(i);
}
String name = atomindex+t.getFirstFrameAsStructure().getAtomByIndex(atomindex).getName();
ret.setName("Close["+cutoff+"]["+name+","+point+"]");
return ret;
}
/**
* Returns the list of frames in the trajectory where an atoms is more distant from a reference point than a given cutoff
* @param t trajectory
* @param atomindex index of atom
* @param point reference point
* @param cutoff distance cutoff
* @return frame list
*/
public static FrameIndexSet getFramesWhereAtomIsDistantFromPoint(Trajectory t, int atomindex, Point3D point, double cutoff){
FrameIndexSet ret = new FrameIndexSet();
for (int i = 0; i < t.getNumberOfFrames(); i++) {
Structure frame = t.getFrameAsStructure(i);
if (frame.getAtomByIndex(atomindex).getCoordinates().distance(point)>=cutoff) ret.addFrame(i);
}
String name = atomindex+t.getFirstFrameAsStructure().getAtomByIndex(atomindex).getName();
ret.setName("Distant["+cutoff+"]["+name+","+point+"]");
return ret;
}
}
source/jgromacs/analysis/Dynamics.java 000644 00000064734 11647140720 0014046 0 ustar /**
*
* Written by Márton Münz and Philip C Biggin
* Copyright (c) University of Oxford, United Kingdom
* Visit http://sbcb.bioch.ox.ac.uk/jgromacs/
*
* This source code file is part of JGromacs v1.0.
*
* JGromacs v1.0 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* JGromacs v1.0. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with JGromacs v1.0. If not, see .
*
*/
package jgromacs.analysis;
import java.util.ArrayList;
import jgromacs.data.IndexSet;
import jgromacs.data.Point3D;
import jgromacs.data.PointList;
import jgromacs.data.Structure;
import jgromacs.data.Trajectory;
import jama.EigenvalueDecomposition;
import jama.Matrix;
/**
* Collection of methods for analysing molecular motions
*
*/
public class Dynamics {
// Covariance and correlation matrices
/**
* Calculates the 3Nx3N coordinate covariance matrix from a trajectory and a reference frame for superposition
* @param t trajectory
* @param reference reference frame
* @return coordinate covariance matrix
*/
public static Matrix getCoordinateCovarianceMatrix(Trajectory t, PointList reference){
int numofatoms = t.getNumberOfAtoms();
int numofframes = t.getNumberOfFrames();
Matrix ret = new Matrix(3*numofatoms,3*numofatoms,0);
t = Superposition.superposeTo(t, reference);
PointList mean = t.getMeanFrame();
for (int i = 0; i < numofframes; i++) {
PointList frame = t.getFrameAsPointList(i);
for (int k = 0; k < numofatoms; k++) {
Point3D pointk = frame.getPoint(k);
Point3D meank = mean.getPoint(k);
double dx_k = pointk.getX()-meank.getX();
double dy_k = pointk.getY()-meank.getY();
double dz_k = pointk.getZ()-meank.getZ();
for (int j = k; j < numofatoms; j++) {
Point3D pointj = frame.getPoint(j);
Point3D averagej = mean.getPoint(j);
double dx_j = pointj.getX()-averagej.getX();
double dy_j = pointj.getY()-averagej.getY();
double dz_j = pointj.getZ()-averagej.getZ();
ret.set(k*3, j*3, ret.get(k*3, j*3)+dx_k*dx_j);
ret.set(k*3, j*3+1, ret.get(k*3, j*3+1)+dx_k*dy_j);
ret.set(k*3, j*3+2, ret.get(k*3, j*3+2)+dx_k*dz_j);
ret.set(k*3+1, j*3, ret.get(k*3+1, j*3)+dy_k*dx_j);
ret.set(k*3+1, j*3+1, ret.get(k*3+1, j*3+1)+dy_k*dy_j);
ret.set(k*3+1, j*3+2, ret.get(k*3+1, j*3+2)+dy_k*dz_j);
ret.set(k*3+2, j*3, ret.get(k*3+2, j*3)+dz_k*dx_j);
ret.set(k*3+2, j*3+1, ret.get(k*3+2, j*3+1)+dz_k*dy_j);
ret.set(k*3+2, j*3+2, ret.get(k*3+2, j*3+2)+dz_k*dz_j);
}
}
}
double n = numofframes; // numofframes-1;
ret = ret.times(1/n);
for (int i = 0; i < ret.getRowDimension(); i++) {
for (int j = i; j < ret.getColumnDimension(); j++) {
ret.set(j, i, ret.get(i,j));
}
}
return ret;
}
/**
* Calculates the NxN atomic covariance matrix from a trajectory and a reference frame for superposition
* @param t trajectory
* @param reference reference frame
* @return atomic covariance matrix
*/
public static Matrix getAtomicCovarianceMatrix(Trajectory t, PointList reference){
int numofatoms = t.getNumberOfAtoms();
int numofframes = t.getNumberOfFrames();
Matrix ret = new Matrix(numofatoms,numofatoms,0);
t = Superposition.superposeTo(t, reference);
PointList mean = t.getMeanFrame();
for (int i = 0; i < numofframes; i++) {
PointList frame = t.getFrameAsPointList(i);
for (int k = 0; k < numofatoms; k++) {
Point3D pointk = frame.getPoint(k);
Point3D meank = mean.getPoint(k);
Point3D devK = pointk.minus(meank);
for (int j = k; j < numofatoms; j++) {
Point3D pointj = frame.getPoint(j);
Point3D meanj = mean.getPoint(j);
Point3D devJ = pointj.minus(meanj);
double value = devK.innerProduct(devJ);
ret.set(k, j, ret.get(k, j)+value);
}
}
}
double n = numofframes; // numofframes-1
ret = ret.times(1/n);
for (int i = 0; i < ret.getRowDimension(); i++) {
for (int j = i; j < ret.getColumnDimension(); j++) {
ret.set(j, i, ret.get(i,j));
}
}
return ret;
}
/**
* Calculates the 3Nx3N coordinate correlation matrix from a trajectory and a reference frame for superposition
* @param t trajectory
* @param reference reference frame
* @return coordinate correlation matrix
*/
public static Matrix getCoordinateCorrelationMatrix(Trajectory t, PointList reference){
Matrix cov = getCoordinateCovarianceMatrix(t, reference);
Matrix ret = new Matrix(cov.getRowDimension(),cov.getColumnDimension());
for (int i = 0; i < ret.getRowDimension(); i++) {
for (int j = i; j < ret.getColumnDimension(); j++) {
ret.set(i, j, cov.get(i, j)/Math.sqrt(cov.get(i, i)*cov.get(j, j)));
ret.set(j, i, ret.get(i, j));
}
}
return ret;
}
/**
* Calculates the NxN atomic correlation matrix from a trajectory and a reference frame for superposition
* @param t trajectory
* @param reference reference frame
* @return atomic correlation matrix
*/
public static Matrix getAtomicCorrelationMatrix(Trajectory t, PointList reference){
Matrix cov = getAtomicCovarianceMatrix(t, reference);
Matrix ret = new Matrix(cov.getRowDimension(),cov.getColumnDimension());
for (int i = 0; i < ret.getRowDimension(); i++) {
for (int j = i; j < ret.getColumnDimension(); j++) {
ret.set(i, j, cov.get(i, j)/Math.sqrt(cov.get(i, i)*cov.get(j, j)));
ret.set(j, i, ret.get(i, j));
}
}
return ret;
}
/**
* Calculates the 3Nx3N coordinate covariance matrix from a trajectory using its first frame as the reference frame for superposition
* @param t trajectory
* @return coordinate covariance matrix
*/
public static Matrix getCoordinateCovarianceMatrix(Trajectory t){
return getCoordinateCovarianceMatrix(t,t.getFirstFrameAsPointList());
}
/**
* Calculates the NxN atomic covariance matrix from a trajectory using its first frame as the reference frame for superposition
* @param t trajectory
* @return atomic covariance matrix
*/
public static Matrix getAtomicCovarianceMatrix(Trajectory t){
return getAtomicCovarianceMatrix(t,t.getFirstFrameAsPointList());
}
/**
* Calculates the 3Nx3N coordinate correlation matrix from a trajectory using its first frame as the reference frame for superposition
* @param t trajectory
* @return coordinate correlation matrix
*/
public static Matrix getCoordinateCorrelationMatrix(Trajectory t){
return getCoordinateCorrelationMatrix(t,t.getFirstFrameAsPointList());
}
/**
* Calculates the NxN atomic correlation matrix from a trajectory using its first frame as the reference frame for superposition
* @param t trajectory
* @return atomic correlation matrix
*/
public static Matrix getAtomicCorrelationMatrix(Trajectory t){
return getAtomicCorrelationMatrix(t,t.getFirstFrameAsPointList());
}
// PCA and related
/**
* Calculates the principal components and the corresponding eigenvalues from a covariance matrix
* @param covariance covariance matrix
* @return a Matrix array containing D (block diagonal eigenvalue matrix) and V (principal component matrix)
*/
public static Matrix[] getPCA(Matrix covariance){
EigenvalueDecomposition evd = new EigenvalueDecomposition(covariance);
Matrix D = evd.getD();
Matrix V = evd.getV();
Matrix[] ret = new Matrix[2];
ret[0] = D;
ret[1] = V;
return ret;
}
/**
* Calculates the principal components and the corresponding eigenvalues from a trajectory
* @param t trajectory
* @return a Matrix array containing D (block diagonal eigenvalue matrix) and V (principal component matrix)
*/
public static Matrix[] getPCA(Trajectory t){
Matrix covariance = getCoordinateCovarianceMatrix(t);
return getPCA(covariance);
}
/**
* Calculates the cumulative variance profile from a trajectory
* @param t trajectory
* @return cumulative variance profile
*/
public static ArrayList getCumulativeVariances(Trajectory t){
ArrayList ret = new ArrayList();
Matrix[] result = Dynamics.getPCA(t);
Matrix D = result[0];
int dim = D.getRowDimension();
double N = D.trace();
double sum = 0;
for (int i = 0; i < dim; i++) {
sum+=D.get(dim-i-1, dim-i-1);
ret.add(sum/N);
}
return ret;
}
/**
* Calculates the cumulative variance profile from a covariance matrix
* @param covariance covariance matrix
* @return cumulative variance profile
*/
public static ArrayList getCumulativeVariances(Matrix covariance){
ArrayList ret = new ArrayList();
Matrix[] result = Dynamics.getPCA(covariance);
Matrix D = result[0];
int dim = D.getRowDimension();
double N = D.trace();
double sum = 0;
for (int i = 0; i < dim; i++) {
sum+=D.get(dim-i-1, dim-i-1);
ret.add(sum/N);
}
return ret;
}
/**
* Calculates the root mean square inner product (RMSIP) from two covariance matrices
* @param covariance1 first covariance matrix
* @param covariance2 second covariance matrix
* @param N number of principal components used from the first trajectory
* @param M number of principal components used from the second trajectory
* @return root mean square inner product (RMSIP)
*/
public static double getRootMeanSquareInnerProduct(Matrix covariance1, Matrix covariance2, int N, int M){
EigenvalueDecomposition evd1 = new EigenvalueDecomposition(covariance1);
Matrix V1 = evd1.getV();
EigenvalueDecomposition evd2 = new EigenvalueDecomposition(covariance2);
Matrix V2 = evd2.getV();
double ret = 0;
int dim = evd1.getD().getColumnDimension();
for (int i = dim-1; i >= dim-N; i--) {
for (int j = dim-1; j >= dim-M; j--)
ret+=product(V1,V2,i,j);
}
return Math.sqrt(ret/N);
}
private static double product(Matrix V1, Matrix V2, int i, int j){
double ret = 0;
for (int k = 0; k < V1.getRowDimension(); k++)
ret+=V1.get(k, i)*V2.get(k, j);
return ret*ret;
}
/**
* Calculates the root mean square inner product (RMSIP) from two trajectories
* @param t1 first trajectory
* @param t2 second trajectory
* @param N number of principal components used from the first trajectory
* @param M number of principal components used from the second trajectory
* @return root mean square inner product (RMSIP)
*/
public static double getRootMeanSquareInnerProduct(Trajectory t1, Trajectory t2, int N, int M){
Matrix covariance1 = getCoordinateCovarianceMatrix(t1);
Matrix covariance2 = getCoordinateCovarianceMatrix(t2);
return getRootMeanSquareInnerProduct(covariance1,covariance2,N,M);
}
/**
* Calculates the covariance overlap of two covariance matrices
* @param covariance1 first covariance matrix
* @param covariance2 second covariance matrix
* @param N number of dimensions used in the calculation
* @return covariance overlap
*/
public static double getCovarianceMatrixOverlap(Matrix covariance1, Matrix covariance2, int N){
EigenvalueDecomposition evd1 = new EigenvalueDecomposition(covariance1);
Matrix D1 = evd1.getD();
Matrix V1 = evd1.getV();
EigenvalueDecomposition evd2 = new EigenvalueDecomposition(covariance2);
Matrix D2 = evd2.getD();
Matrix V2 = evd2.getV();
double A = 0;
double B = 0;
int dim = D1.getRowDimension();
for (int i = dim-N; i < dim; i++) A+=(D1.get(i, i)+D2.get(i, i));
for (int i = dim-N; i < dim; i++) {
for (int j = dim-N; j < dim; j++) {
double x = 0;
for (int k = 0; k < dim; k++) x+=V1.get(k, i)*V2.get(k, j);
B+= Math.sqrt(Math.abs(D1.get(i, i)*D2.get(j, j)))*Math.pow(x, 2);
}
}
//return 1-Math.sqrt(Math.abs((A-2*B)/A));
return 1-Math.sqrt(A-2*B)/Math.sqrt(A);
}
/**
* Calculates the covariance overlap of two covariance matrices
* @param covariance1 first covariance matrix
* @param covariance2 second covariance matrix
* @return covariance overlap
*/
public static double getCovarianceMatrixOverlap(Matrix covariance1, Matrix covariance2){
EigenvalueDecomposition evd1 = new EigenvalueDecomposition(covariance1);
Matrix D1 = evd1.getD();
Matrix V1 = evd1.getV();
EigenvalueDecomposition evd2 = new EigenvalueDecomposition(covariance2);
Matrix D2 = evd2.getD();
Matrix V2 = evd2.getV();
double A = 0;
double B = 0;
int dim = D1.getRowDimension();
for (int i = 0; i < dim; i++) A+=(D1.get(i, i)+D2.get(i, i));
for (int i = 0; i < dim; i++) {
for (int j = 0; j < dim; j++) {
double x = 0;
for (int k = 0; k < dim; k++) x+=V1.get(k, i)*V2.get(k, j);
B+= Math.sqrt(Math.abs(D1.get(i, i)*D2.get(j, j)))*Math.pow(x, 2);
}
}
//return 1-Math.sqrt(Math.abs((A-2*B)/A));
return 1-Math.sqrt(A-2*B)/Math.sqrt(A);
}
/**
* Calculates the covariance overlap from two trajectories
* @param t1 first trajectory
* @param t2 second trajectory
* @param N number of dimensions used in the calculation
* @return covariance overlap
*/
public static double getCovarianceMatrixOverlap(Trajectory t1, Trajectory t2, int N){
Matrix covariance1 = getCoordinateCovarianceMatrix(t1);
Matrix covariance2 = getCoordinateCovarianceMatrix(t2);
return getCovarianceMatrixOverlap(covariance1, covariance2, N);
}
/**
* Calculates the covariance overlap from two trajectories
* @param t1 first trajectory
* @param t2 second trajectory
* @return covariance overlap
*/
public static double getCovarianceMatrixOverlap(Trajectory t1, Trajectory t2){
Matrix covariance1 = getCoordinateCovarianceMatrix(t1);
Matrix covariance2 = getCoordinateCovarianceMatrix(t2);
return getCovarianceMatrixOverlap(covariance1, covariance2);
}
// Fluctuations
/**
* Calculates the F fluctuation matrix (variances of distances) from a trajectory
* @param t trajectory
* @return F fluctuation matrix
*/
public static Matrix getFluctuationMatrix(Trajectory t){
int dim = t.getNumberOfAtoms();
Matrix ret = new Matrix(dim, dim, 0);
Matrix mean = Distances.getMeanAtomicDistanceMatrix(t);
for (int i = 0; i < t.getNumberOfFrames(); i++) {
PointList frame = t.getFrameAsPointList(i);
Matrix D = Distances.getDistanceMatrix(frame);
for (int j = 0; j < dim; j++) {
for (int k = j+1; k < dim; k++) {
ret.set(j, k, ret.get(j, k)+Math.pow(D.get(j, k)-mean.get(j, k),2));
}
}
}
ret = ret.times(1.0/t.getNumberOfFrames());
for (int i = 0; i < dim; i++) {
for (int j = i+1; j < dim; j++) {
ret.set(j, i, ret.get(i, j));
}
}
return ret;
}
/**
* Calculates the F fluctuation matrix (variances of distances) for a group of atoms
* @param t trajectory
* @param indices index set of atoms
* @return F fluctuation matrix
*/
public static Matrix getFluctuationMatrix(Trajectory t, IndexSet indices){
int dim = indices.getNumberOfIndices();
Matrix ret = new Matrix(dim, dim, 0);
Matrix mean = Distances.getMeanAtomicDistanceMatrix(t, indices);
for (int i = 0; i < t.getNumberOfFrames(); i++) {
Structure frame = t.getFrameAsStructure(i);
Matrix D = Distances.getAtomicDistanceMatrix(frame, indices);
for (int j = 0; j < dim; j++) {
for (int k = j+1; k < dim; k++) {
ret.set(j, k, ret.get(j, k)+Math.pow(D.get(j, k)-mean.get(j, k),2));
}
}
}
ret = ret.times(1.0/t.getNumberOfFrames());
for (int i = 0; i < dim; i++) {
for (int j = i+1; j < dim; j++) {
ret.set(j, i, ret.get(i, j));
}
}
return ret;
}
/**
* Calculates the fluctuation between two subsets of atoms defined as the mean of entries
* of the selected submatrix of matrix F (fluctuation matrix)
* @param t trajectory
* @param set1 first subset
* @param set2 second subset
* @return fluctuation between the two atom sets
*/
public static double getFluctuationOfSubsets(Trajectory t, IndexSet set1, IndexSet set2){
double ret = 0;
Matrix F = getFluctuationMatrix(t);
ArrayList indexList1 = t.getFrameAsStructure(0).convertIndicesToArrayListIndices(set1);
ArrayList indexList2 = t.getFrameAsStructure(0).convertIndicesToArrayListIndices(set2);
for (int i = 0; i < indexList1.size(); i++) {
for (int j = 0; j < indexList2.size(); j++) {
ret+=F.get(indexList1.get(i), indexList2.get(j));
}
}
return ret/(indexList1.size()*indexList2.size());
}
/**
* Calculates the RMSF profile from a trajectory and a reference frame for superposition
* @param t trajectory
* @param R reference frame
* @return RMSF profile
*/
public static ArrayList getRMSFprofile(Trajectory t, PointList R){
ArrayList ret = new ArrayList();
int numofatoms = t.getNumberOfAtoms();
for (int i = 0; i < numofatoms; i++) ret.add(0.0);
int K = t.getNumberOfFrames();
for (int k = 0; k < K; k++) {
PointList frame = t.getFrameAsPointList(k);
ArrayList RMSDi = Similarity.getRMSDiProfile(frame, R);
for (int i = 0; i < numofatoms; i++)
ret.set(i, ret.get(i)+Math.pow(RMSDi.get(i),2));
}
for (int i = 0; i < numofatoms; i++) ret.set(i, Math.sqrt(ret.get(i)/K));
return ret;
}
/**
* Calculates the RMSF profile from a trajectory and a reference frame for superposition
* @param t trajectory
* @param R reference frame
* @return RMSF profile
*/
public static ArrayList getRMSFprofile(Trajectory t, Structure R){
return getRMSFprofile(t,R.getAllAtomCoordinates());
}
/**
* Calculates the RMSF profile of a group of atoms from a trajectory and a reference frame for superposition
* @param t trajectory
* @param indicesT index set of atoms used from the trajectory
* @param R reference frame
* @param indicesR index set of atoms used from the reference frame
* @return RMSF profile
*/
public static ArrayList getRMSFprofile(Trajectory t, IndexSet indicesT, Structure R, IndexSet indicesR){
ArrayList ret = new ArrayList();
ArrayList indexListT = t.getFrameAsStructure(0).convertIndicesToArrayListIndices(indicesT);
ArrayList indexListR = R.convertIndicesToArrayListIndices(indicesR);
PointList reference = R.getAllAtomCoordinates().getSubList(indexListR);
int numofatoms = indexListT.size();
for (int i = 0; i < numofatoms; i++) ret.add(0.0);
int K = t.getNumberOfFrames();
for (int k = 0; k < K; k++) {
PointList frame = t.getFrameAsPointList(k).getSubList(indexListT);
ArrayList RMSDi = Similarity.getRMSDiProfile(frame, reference);
for (int i = 0; i < numofatoms; i++)
ret.set(i, ret.get(i)+Math.pow(RMSDi.get(i),2));
}
for (int i = 0; i < numofatoms; i++) ret.set(i, Math.sqrt(ret.get(i)/K));
return ret;
}
/**
* Calculates the RMSF profile from a trajectory by superposing all frames to a reference frame R
* and calculating the RMSDi deviations with regards to a reference frame Q
* @param t trajectory
* @param R reference frame to which all frames are superposed
* @param Q reference frame from which deviations are measured
* @return RMSF profile
*/
public static ArrayList getRMSFprofile(Trajectory t, PointList R, PointList Q){
ArrayList ret = new ArrayList();
int numofatoms = t.getNumberOfAtoms();
for (int i = 0; i < numofatoms; i++) ret.add(0.0);
int K = t.getNumberOfFrames();
for (int k = 0; k < K; k++) {
PointList frame = t.getFrameAsPointList(k);
PointList superposed = Superposition.superposeTo(frame, R);
ArrayList RMSDi = Similarity.getRMSDiProfileNoSuperposition(superposed, Q);
for (int i = 0; i < numofatoms; i++)
ret.set(i, ret.get(i)+Math.pow(RMSDi.get(i),2));
}
for (int i = 0; i < numofatoms; i++) ret.set(i, Math.sqrt(ret.get(i)/K));
return ret;
}
/**
* Calculates the RMSF profile from a trajectory by superposing all frames to a reference frame R
* and calculating the RMSDi deviations with regards to a reference frame Q
* @param t trajectory
* @param R reference frame to which all frames are superposed
* @param Q reference frame from which deviations are measured
* @return RMSF profile
*/
public static ArrayList getRMSFprofile(Trajectory t, Structure R, Structure Q){
return getRMSFprofile(t,R.getAllAtomCoordinates(),Q.getAllAtomCoordinates());
}
/**
* Calculates the RMSF profile from a trajectory by superposing all frames to a reference frame R
* and calculating the RMSDi deviations with regards to the mean structure
* @param t trajectory
* @param R reference frame
* @return RMSF profile
*/
public static ArrayList getRMSFaroundTheMeanProfile(Trajectory t, PointList R){
ArrayList ret = new ArrayList();
int numofatoms = t.getNumberOfAtoms();
for (int i = 0; i < numofatoms; i++) ret.add(0.0);
Trajectory superposed = Superposition.superposeTo(t, R);
PointList mean = superposed.getMeanFrame();
int K = superposed.getNumberOfFrames();
for (int k = 0; k < K; k++) {
PointList frame = superposed.getFrameAsPointList(k);
ArrayList RMSDi = Similarity.getRMSDiProfileNoSuperposition(frame, mean);
for (int i = 0; i < numofatoms; i++)
ret.set(i, ret.get(i)+Math.pow(RMSDi.get(i),2));
}
for (int i = 0; i < numofatoms; i++) ret.set(i, Math.sqrt(ret.get(i)/K));
return ret;
}
/**
* Calculates the RMSF profile from a trajectory by superposing all frames to a reference frame R
* and calculating the RMSDi deviations with regards to the mean structure
* @param t trajectory
* @param R reference frame
* @return RMSF profile
*/
public static ArrayList getRMSFaroundTheMeanProfile(Trajectory t, Structure R){
return getRMSFaroundTheMeanProfile(t,R.getAllAtomCoordinates());
}
// Dynamical networks (Sethi et al. 2009)
/**
* Calculates the dynamical network of a protein according to the definition of Sethi et al. 2009
* (Dynamical networks in tRNA:protein complexes, PNAS)
* @param t trajectory
* @param cutoff distance cutoff for the calculation of contact matrix
* @param frequency minimal frequency of frames in which two residues must be in contact
* @return weighted adjacency matrix of dynamical network
*/
public static Matrix getDynamicalNetwork(Trajectory t, double cutoff, double frequency){
int d = t.getNumberOfResidues();
Matrix Adjacency = new Matrix(d,d,0);
Matrix Contact = Distances.getFrequencyContactMatrix(t, Distances.CLOSESTHEAVY, cutoff, frequency);
IndexSet alphaCarbons = t.getFirstFrameAsStructure().getAlphaCarbonIndexSet();
t = t.getSubTrajectory(alphaCarbons);
Matrix Correlation = Dynamics.getAtomicCorrelationMatrix(t);
for (int i = 0; i < d; i++) {
for (int j = i+1; j < d; j++) {
//if (Contact.get(i, j)==1) Adjacency.set(i, j, Math.abs(Correlation.get(i, j)));
if (Contact.get(i, j)==1) Adjacency.set(i, j, -Math.log(Math.abs(Correlation.get(i, j))));
else Adjacency.set(i, j, Double.NaN);
Adjacency.set(j, i, Adjacency.get(i, j));
}
}
return Adjacency;
}
// Structural radius (Kuzmanic and Zagrovic, 2010)
/**
* Calculates the structural radius of the conformational ensemble sampled in the trajectory
* as defined by Kuzmanic and Zagrovic, 2010
* (Determination of Ensemble-Average Pairwise Root Mean-Square Deviation from Experimental B-Factors, Biophysical Journal)
* @param t trajectory
* @return structural radius
*/
public static double getStructuralRadius(Trajectory t){
double ret = 0;
int Ns = t.getNumberOfFrames();
for (int i = 0; i < Ns; i++) {
PointList frameI = t.getFrameAsPointList(i);
for (int j = 0; j < Ns; j++) {
PointList frameJ = t.getFrameAsPointList(j);
ret+=Math.pow(Similarity.getRMSD(frameI, frameJ), 2);
}
}
return Math.sqrt(ret/(2*Ns*Ns));
}
// Ensemble averaged RMSD (Brüschweiler, 2002)
/**
* Calculates the ensemble averaged RMSD between two conformational ensembles sampled in two trajectories
* as defined by Brüschweiler, 2002
* (Efficient RMSD measures for the comparison of two molecular ensembles, Proteins: Structure, Function, and Bioinformatics)
* @param t1 first trajectory
* @param t2 second trajectory
* @return ensemble averaged RMSD
*/
public static double getEnsembleAveragedRMSD(Trajectory t1, Trajectory t2){
double ret = 0;
int N = t1.getNumberOfFrames();
int M = t2.getNumberOfFrames();
for (int i = 0; i < N; i++) {
PointList frameI = t1.getFrameAsPointList(i);
for (int j = 0; j < M; j++) {
PointList frameJ = t2.getFrameAsPointList(j);
ret+=Math.pow(Similarity.getRMSD(frameI, frameJ), 2);
}
}
double n = Double.valueOf(N*M);
return Math.sqrt(ret/n);
}
// Contact probability map (Wei et al. 2009 )
/**
* Calculates the (residue) contact probability map for a trajectory
* as defined by Wei et al, 2009
* (Residual Structure in Islet Amyloid Polypeptide Mediates Its Interactions with Soluble Insulin, Biochemistry)
* @param t simulation trajectory
* @param cutoff distance cutoff
* @return contact probability matrix
*/
public static Matrix getContactProbabilityMap(Trajectory t, double cutoff){
int dim = t.getNumberOfResidues();
Matrix ret = new Matrix(dim,dim,0);
for (int k = 0; k < t.getNumberOfFrames(); k++) {
Structure frame = t.getFrameAsStructure(k);
Matrix C = Distances.getContactMatrix(frame, Distances.CLOSESTHEAVY, cutoff);
ret = ret.plus(C);
}
ret = ret.times(1.0/t.getNumberOfFrames());
return ret;
}
// Trajectory of a single atom
/**
* Returns the trajectory of a single atom in the course of the simulation
* @param t simulation trajectory
* @param atomindex index of atom
* @return atomic trajectory as an ArrayList of coordinates
*/
public static ArrayList getTrajectoryOfAtom(Trajectory t, int atomindex){
ArrayList ret = new ArrayList();
for (int i = 0; i < t.getNumberOfFrames(); i++)
ret.add(t.getFrameAsStructure(i).getAtomByIndex(atomindex).getCoordinates());
return ret;
}
}
source/jgromacs/analysis/GNM.java 000644 00000006323 11637052344 0012711 0 ustar /**
*
* Written by Márton Münz and Philip C Biggin
* Copyright (c) University of Oxford, United Kingdom
* Visit http://sbcb.bioch.ox.ac.uk/jgromacs/
*
* This source code file is part of JGromacs v1.0.
*
* JGromacs v1.0 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* JGromacs v1.0. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with JGromacs v1.0. If not, see .
*
*/
package jgromacs.analysis;
import jama.Matrix;
import jama.SingularValueDecomposition;
import java.util.ArrayList;
import jgromacs.data.Structure;
/**
* Objects of this class represent a Gaussian Network Model (GNM) of a protein
*
*/
public class GNM {
private Matrix cM = new Matrix(1,1,0);
private Matrix KM = new Matrix(1,1,0);
private Matrix U = new Matrix(1,1,0);
private Matrix Lambda = new Matrix(1,1,0);
/**
* Constructs a new Gaussian Network Model
* @param s structure to be modelled
* @param cutoff distance cutoff
* @param distanceBetween which atoms are used for calculating the distances (ALPHACARBON: alpha carbon atoms,
* CLOSEST: closest atoms of two residues, CLOSESTHEAVY: closest heavy atoms of two residues)
*/
public GNM(Structure s, double cutoff, int distanceBetween){
cM = Distances.getContactMatrix(s, distanceBetween, cutoff);
KM = calculateKirchhoffMatrix(cM);
SingularValueDecomposition svd = new SingularValueDecomposition(KM);
U = svd.getU();
Lambda = svd.getS();
}
/**
* Returns the contact matrix
* @return contact matrix
*/
public Matrix getContactMatrix(){
return cM;
}
/**
* Returns the Kirchhoff matrix
* @return Kirchhoff matrix
*/
public Matrix getKirchhoffMatrix(){
return KM;
}
/**
* Returns the diagonal matrix of eigenvalues (Lambda)
* @return Lambda matrix
*/
public Matrix getLambdaMatrix(){
return Lambda;
}
/**
* Returns the orthogonal matrix of eigenvectors (U)
* @return U matrix
*/
public Matrix getEigenvectorMatrix(){
return U;
}
/**
* Calculates the mean square fluctuation (MSF) profile
* @return MSF profile
*/
public ArrayList getMSFProfile(){
ArrayList ret = new ArrayList();
int resnum = Lambda.getRowDimension();
for (int i = 0; i < resnum; i++) {
double msf = 0;
for (int q = 0; q < resnum-1; q++)
msf+=Math.pow(U.get(i, q),2)/Lambda.get(q, q);
ret.add(msf);
}
return ret;
}
private static Matrix calculateKirchhoffMatrix(Matrix cM){
Matrix ret = cM.times(-1);
int resnum = ret.getRowDimension();
for (int i = 0; i < resnum; i++) {
double sum = 0;
for (int j = 0; j < resnum; j++)
if (j!=i) sum+=ret.get(i, j);
ret.set(i, i, -sum);
}
return ret;
}
}
source/jgromacs/analysis/package-info.java 000644 00000000211 11575660510 0014603 0 ustar /**
* jgromacs.analysis is a collection of classes providing static methods for various analysis tasks
*/
package jgromacs.analysis; source/jgromacs/analysis/Similarity.java 000644 00000066135 11647540716 0014433 0 ustar /**
*
* Written by Márton Münz and Philip C Biggin
* Copyright (c) University of Oxford, United Kingdom
* Visit http://sbcb.bioch.ox.ac.uk/jgromacs/
*
* This source code file is part of JGromacs v1.0.
*
* JGromacs v1.0 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* JGromacs v1.0. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with JGromacs v1.0. If not, see .
*
*/
package jgromacs.analysis;
import java.util.ArrayList;
import jgromacs.data.FrameIndexSet;
import jgromacs.data.IndexSet;
import jgromacs.data.PointList;
import jgromacs.data.Structure;
import jgromacs.data.Trajectory;
import jama.Matrix;
/**
* Collection of methods for measuring structural similarity
*
*/
public class Similarity {
// Coordinate-based measures
/**
* Calculates RMSD similarity between two point lists
* @param A first point list
* @param B second point list
* @return RMSD
*/
public static double getRMSD(PointList A, PointList B){
PointList superposedA = Superposition.superposeTo(A, B);
return getRMSDnoSuperposition(superposedA, B);
}
/**
* Calculates RMSD similarity between two structures
* @param A first structure
* @param B second structure
* @return RMSD
*/
public static double getRMSD(Structure A, Structure B){
return getRMSD(A.getAllAtomCoordinates(),B.getAllAtomCoordinates());
}
/**
* Calculates RMSD similarity between two groups of atoms
* @param A first structure
* @param indicesA index set of atoms in the first structure
* @param B second structure
* @param indicesB index set of atoms in the second structure
* @return RMSD
*/
public static double getRMSD(Structure A, IndexSet indicesA, Structure B, IndexSet indicesB){
Structure subA = A.getSubStructure(indicesA);
Structure subB = B.getSubStructure(indicesB);
return getRMSD(subA, subB);
}
/**
* Calculates the RMSDi profile between two point lists
* @param A first point list
* @param B second point list
* @return RMSDi profile
*/
public static ArrayList getRMSDiProfile(PointList A, PointList B){
PointList superposedA = Superposition.superposeTo(A, B);
return getRMSDiProfileNoSuperposition(superposedA, B);
}
/**
* Calculates the RMSDi profile between two structures
* @param A first structure
* @param B second structure
* @return RMSDi profile
*/
public static ArrayList getRMSDiProfile(Structure A, Structure B){
return getRMSDiProfile(A.getAllAtomCoordinates(),B.getAllAtomCoordinates());
}
/**
* Calculates the RMSDi profile between two groups of atoms
* @param A first structure
* @param indicesA index set of atoms in the first structure
* @param B second structure
* @param indicesB index set of atoms in the second structure
* @return RMSDi profile
*/
public static ArrayList getRMSDiProfile(Structure A, IndexSet indicesA, Structure B, IndexSet indicesB){
Structure subA = A.getSubStructure(indicesA);
Structure subB = B.getSubStructure(indicesB);
return getRMSDiProfile(subA,subB);
}
/**
* Calculates RMSD similarity between two point lists without doing superposition
* @param A first point list
* @param B second point list
* @return RMSD without superposition
*/
public static double getRMSDnoSuperposition(PointList A, PointList B){
double ret = 0;
for (int i = 0; i < A.getNumberOfPoints(); i++)
ret+= Math.pow(A.getPoint(i).distance(B.getPoint(i)),2);
double n = (double)A.getNumberOfPoints();
return Math.sqrt(ret/n);
}
/**
* Calculates RMSD similarity between two structures without doing superposition
* @param A first structure
* @param B second structure
* @return RMSD without superposition
*/
public static double getRMSDnoSuperposition(Structure A, Structure B){
return getRMSDnoSuperposition(A.getAllAtomCoordinates(),B.getAllAtomCoordinates());
}
/**
* Calculates RMSD similarity between two groups of atoms without superposition
* @param A first structure
* @param indicesA index set of atoms in the first structure
* @param B second structure
* @param indicesB index set of atoms in the second structure
* @return RMSD without superposition
*/
public static double getRMSDnoSuperposition(Structure A, IndexSet indicesA, Structure B, IndexSet indicesB){
Structure subA = A.getSubStructure(indicesA);
Structure subB = B.getSubStructure(indicesB);
return getRMSDnoSuperposition(subA, subB);
}
/**
* Calculates the RMSDi profile between two point lists without superposition
* @param A first point list
* @param B second point list
* @return RMSDi profile without superposition
*/
public static ArrayList getRMSDiProfileNoSuperposition(PointList A, PointList B){
ArrayList ret = new ArrayList();
for (int i = 0; i < A.getNumberOfPoints(); i++)
ret.add(A.getPoint(i).distance(B.getPoint(i)));
return ret;
}
/**
* Calculates the RMSDi profile between two structures without superposition
* @param A first structure
* @param B second structure
* @return RMSDi profile without superposition
*/
public static ArrayList getRMSDiProfileNoSuperposition(Structure A, Structure B){
return getRMSDiProfileNoSuperposition(A.getAllAtomCoordinates(),B.getAllAtomCoordinates());
}
/**
* Calculates the RMSDi profile between two groups of atoms without superposition
* @param A first structure
* @param indicesA index set of atoms in the first structure
* @param B second structure
* @param indicesB index set of atoms in the second structure
* @return RMSDi profile without superposition
*/
public static ArrayList getRMSDiProfileNoSuperposition(Structure A, IndexSet indicesA, Structure B, IndexSet indicesB){
Structure subA = A.getSubStructure(indicesA);
Structure subB = B.getSubStructure(indicesB);
return getRMSDiProfileNoSuperposition(subA, subB);
}
// Distance-based measures
/**
* Calculates dRMSD similarity between two distance matrices
* @param A first distance matrix
* @param B second distance matrix
* @return dRMSD
*/
public static double getDRMSD(Matrix A, Matrix B){
double ret = 0;
int n = A.getRowDimension();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
double dif = A.get(i, j)-B.get(i, j);
ret+=Math.pow(dif, 2);
}
}
return Math.sqrt(ret/(n*n));
}
/**
* Calculates dRMSD similarity between two point lists
* @param A first point list
* @param B second point list
* @return dRMSD
*/
public static double getDRMSD(PointList A, PointList B){
double ret = 0;
Matrix D1 = Distances.getDistanceMatrix(A);
Matrix D2 = Distances.getDistanceMatrix(B);
int n = D1.getRowDimension();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
double dif = D1.get(i, j)-D2.get(i, j);
ret+=Math.pow(dif, 2);
}
}
return Math.sqrt(ret/(n*n));
}
/**
* Calculates dRMSD similarity between two structures
* @param A first structure
* @param B second structure
* @return dRMSD
*/
public static double getDRMSD(Structure A, Structure B){
return getDRMSD(A.getAllAtomCoordinates(),B.getAllAtomCoordinates());
}
/**
* Calculates dRMSD similarity between two groups of atoms
* @param A first structure
* @param indicesA index set of atoms in the first structure
* @param B second structure
* @param indicesB index set of atoms in the second structure
* @return dRMSD
*/
public static double getDRMSD(Structure A, IndexSet indicesA, Structure B, IndexSet indicesB){
Structure subA = A.getSubStructure(indicesA);
Structure subB = B.getSubStructure(indicesB);
return getDRMSD(subA, subB);
}
/**
* Calculates the dRMSDi profile between two distance matrices
* @param A first distance matrix
* @param B second distance matrix
* @return dRMSDi profile
*/
public static ArrayList getDRMSDiProfile(Matrix A, Matrix B){
ArrayList ret = new ArrayList();
int n = A.getRowDimension();
for (int i = 0; i < n; i++) {
double drmsdi = 0;
for (int j = 0; j < n; j++)
drmsdi+=Math.pow(A.get(i, j)-B.get(i, j), 2);
drmsdi = Math.sqrt(drmsdi/n);
ret.add(drmsdi);
}
return ret;
}
/**
* Calculates the dRMSDi profile between two point lists
* @param A first point list
* @param B second point list
* @return dRMSDi profile
*/
public static ArrayList getDRMSDiProfile(PointList A, PointList B){
ArrayList ret = new ArrayList();
Matrix D1 = Distances.getDistanceMatrix(A);
Matrix D2 = Distances.getDistanceMatrix(B);
int n = D1.getRowDimension();
for (int i = 0; i < n; i++) {
double drmsdi = 0;
for (int j = 0; j < n; j++)
drmsdi+=Math.pow(D1.get(i, j)-D2.get(i, j), 2);
drmsdi = Math.sqrt(drmsdi/n);
ret.add(drmsdi);
}
return ret;
}
/**
* Calculates the dRMSDi profile between two structures
* @param A first structure
* @param B second structure
* @return dRMSDi profile
*/
public static ArrayList getDRMSDiProfile(Structure A, Structure B){
return getDRMSDiProfile(A.getAllAtomCoordinates(),B.getAllAtomCoordinates());
}
/**
* Calculates the dRMSDi profile between two groups of atoms
* @param A first structure
* @param indicesA index set of atoms in the first structure
* @param B second structure
* @param indicesB index set of atoms in the second structure
* @return dRMSDi profile
*/
public static ArrayList getDRMSDiProfile(Structure A, IndexSet indicesA, Structure B, IndexSet indicesB){
Structure subA = A.getSubStructure(indicesA);
Structure subB = B.getSubStructure(indicesB);
return getDRMSDiProfile(subA, subB);
}
/**
* Calculates the wdRMSD (weighted dRMSD) similarity of two point lists
* @param A first point list
* @param B second point list
* @param W weight matrix
* @return wdRMSD
*/
public static double getWDRMSD(PointList A, PointList B, Matrix W){
double ret = 0;
double N = 0;
Matrix D1 = Distances.getDistanceMatrix(A);
Matrix D2 = Distances.getDistanceMatrix(B);
int n = D1.getRowDimension();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
double dif = D1.get(i, j)-D2.get(i, j);
ret+=W.get(i, j)*Math.pow(dif, 2);
N+=W.get(i, j);
}
}
return Math.sqrt(ret/N);
}
/**
* Calculates the wdRMSD (weighted dRMSD) similarity of two structures
* @param A first structure
* @param B second structure
* @param W weight matrix
* @return wdRMSD
*/
public static double getWDRMSD(Structure A, Structure B, Matrix W){
return getWDRMSD(A.getAllAtomCoordinates(),B.getAllAtomCoordinates(),W);
}
/**
* Calculates wdRMSD (weighted dRMSD) similarity between two groups of atoms
* @param A first structure
* @param indicesA index set of atoms in the first structure
* @param B second structure
* @param indicesB index set of atoms in the second structure
* @param W weight matrix
* @return wdRMSD
*/
public static double getWDRMSD(Structure A, IndexSet indicesA, Structure B, IndexSet indicesB, Matrix W){
Structure subA = A.getSubStructure(indicesA);
Structure subB = B.getSubStructure(indicesB);
return getWDRMSD(subA, subB, W);
}
/**
* Calculates the wdRMSDi (weighted dRMSDi) profile between two point lists
* @param A first point list
* @param B second point list
* @param W weight matrix
* @return wdRMSDi profile
*/
public static ArrayList getWDRMSDiProfile(PointList A, PointList B, Matrix W){
ArrayList ret = new ArrayList();
Matrix D1 = Distances.getDistanceMatrix(A);
Matrix D2 = Distances.getDistanceMatrix(B);
int n = D1.getRowDimension();
for (int i = 0; i < n; i++) {
double wdrmsdi = 0;
double N = 0;
for (int j = 0; j < n; j++) {
double dif = D1.get(i, j)-D2.get(i, j);
wdrmsdi+=W.get(i, j)*Math.pow(dif, 2);
N+=W.get(i, j);
}
wdrmsdi = Math.sqrt(wdrmsdi/N);
ret.add(wdrmsdi);
}
return ret;
}
/**
* Calculates the wdRMSDi (weighted dRMSDi) profile between two structures
* @param A first structure
* @param B second structure
* @param W weight matrix
* @return wdRMSDi profile
*/
public static ArrayList getWDRMSDiProfile(Structure A, Structure B, Matrix W){
return getWDRMSDiProfile(A.getAllAtomCoordinates(),B.getAllAtomCoordinates(),W);
}
/**
* Calculates the wdRMSDi (weighted dRMSDi) profile between two groups of atoms
* @param A first structure
* @param indicesA index set of atoms in the first structure
* @param B second structure
* @param indicesB index set of atoms in the second structure
* @param W weight matrix
* @return wdRMSDi profile
*/
public static ArrayList getWDRMSDiProfile(Structure A, IndexSet indicesA, Structure B, IndexSet indicesB, Matrix W){
Structure subA = A.getSubStructure(indicesA);
Structure subB = B.getSubStructure(indicesB);
return getWDRMSDiProfile(subA, subB, W);
}
// Similarity matrices
/**
* Calculates the similarity matrix of all frames in a trajectory using the RMSD measure
* @param t trajectory
* @return similarity matrix
*/
public static Matrix getSimilarityMatrixRMSD(Trajectory t){
int dim = t.getNumberOfFrames();
Matrix ret = new Matrix(dim,dim,0);
for (int i = 0; i < dim; i++) {
PointList frameI = t.getFrameAsPointList(i);
for (int j = i+1; j < dim; j++) {
PointList frameJ = t.getFrameAsPointList(j);
double sim = getRMSD(frameI, frameJ);
ret.set(i, j, sim);
ret.set(j, i, sim);
}
}
return ret;
}
/**
* Calculates the similarity matrix of all frames in a trajectory using the RMSD measure
* taking into account only a subset of atoms
* @param t trajectory
* @param indices index set of atoms
* @return similarity matrix
*/
public static Matrix getSimilarityMatrixRMSD(Trajectory t, IndexSet indices){
int dim = t.getNumberOfFrames();
Matrix ret = new Matrix(dim,dim,0);
for (int i = 0; i < dim; i++) {
Structure frameI = t.getFrameAsStructure(i);
for (int j = i+1; j < dim; j++) {
Structure frameJ = t.getFrameAsStructure(j);
double sim = getRMSD(frameI, indices, frameJ, indices);
ret.set(i, j, sim);
ret.set(j, i, sim);
}
}
return ret;
}
/**
* Calculates the similarity matrix of all frames in a trajectory using the dRMSD measure
* @param t trajectory
* @return similarity matrix
*/
public static Matrix getSimilarityMatrixDRMSD(Trajectory t){
int dim = t.getNumberOfFrames();
Matrix ret = new Matrix(dim,dim,0);
for (int i = 0; i < dim; i++) {
PointList frameI = t.getFrameAsPointList(i);
for (int j = i+1; j < dim; j++) {
PointList frameJ = t.getFrameAsPointList(j);
double sim = getDRMSD(frameI, frameJ);
ret.set(i, j, sim);
ret.set(j, i, sim);
}
}
return ret;
}
/**
* Calculates the similarity matrix of all frames in a trajectory using the dRMSD measure
* taking into account only a subset of atoms
* @param t trajectory
* @param indices index set of atoms
* @return similarity matrix
*/
public static Matrix getSimilarityMatrixDRMSD(Trajectory t, IndexSet indices){
int dim = t.getNumberOfFrames();
Matrix ret = new Matrix(dim,dim,0);
for (int i = 0; i < dim; i++) {
Structure frameI = t.getFrameAsStructure(i);
for (int j = i+1; j < dim; j++) {
Structure frameJ = t.getFrameAsStructure(j);
double sim = getDRMSD(frameI, indices, frameJ, indices);
ret.set(i, j, sim);
ret.set(j, i, sim);
}
}
return ret;
}
/**
* Calculates the similarity matrix of all frames in a trajectory using the wdRMSD (weighted dRMSD) measure
* @param t trajectory
* @param W weight matrix
* @return similarity matrix
*/
public static Matrix getSimilarityMatrixWDRMSD(Trajectory t, Matrix W){
int dim = t.getNumberOfFrames();
Matrix ret = new Matrix(dim,dim,0);
for (int i = 0; i < dim; i++) {
PointList frameI = t.getFrameAsPointList(i);
for (int j = i+1; j < dim; j++) {
PointList frameJ = t.getFrameAsPointList(j);
double sim = getWDRMSD(frameI, frameJ, W);
ret.set(i, j, sim);
ret.set(j, i, sim);
}
}
return ret;
}
/**
* Calculates the similarity matrix of all frames in a trajectory using the wdRMSD (weighted dRMSD) measure
* taking into account only a subset of atoms
* @param t trajectory
* @param indices index set of atoms
* @param W weight matrix
* @return similarity matrix
*/
public static Matrix getSimilarityMatrixWDRMSD(Trajectory t, IndexSet indices, Matrix W){
int dim = t.getNumberOfFrames();
Matrix ret = new Matrix(dim,dim,0);
for (int i = 0; i < dim; i++) {
Structure frameI = t.getFrameAsStructure(i);
for (int j = i+1; j < dim; j++) {
Structure frameJ = t.getFrameAsStructure(j);
double sim = getWDRMSD(frameI, indices, frameJ, indices, W);
ret.set(i, j, sim);
ret.set(j, i, sim);
}
}
return ret;
}
// Similarity time series
/**
* Returns the time series of RMSD in a trajectory with regards to a reference point list
* @param t trajectory
* @param R reference point list
* @return time series of RMSD
*/
public static ArrayList getSimilarityTimeSeriesRMSD(Trajectory t, PointList R){
ArrayList ret = new ArrayList();
int dim = t.getNumberOfFrames();
for (int i = 0; i < dim; i++) {
PointList frame = t.getFrameAsPointList(i);
ret.add(getRMSD(frame, R));
}
return ret;
}
/**
* Returns the time series of RMSD in a trajectory with regards to a reference structure
* @param t trajectory
* @param R reference structure
* @return time series of RMSD
*/
public static ArrayList getSimilarityTimeSeriesRMSD(Trajectory t, Structure R){
return getSimilarityTimeSeriesRMSD(t,R.getAllAtomCoordinates());
}
/**
* Returns the time series of RMSD in a trajectory with regards to a reference structure
* taking into account only a subset of atoms
* @param t trajectory
* @param indicesT index set of atoms in the trajectory
* @param R reference structure
* @param indicesR index set of atoms in the reference structure
* @return time series of RMSD
*/
public static ArrayList getSimilarityTimeSeriesRMSD(Trajectory t, IndexSet indicesT, Structure R, IndexSet indicesR){
ArrayList ret = new ArrayList();
int dim = t.getNumberOfFrames();
for (int i = 0; i < dim; i++) {
Structure frame = t.getFrameAsStructure(i);
ret.add(getRMSD(frame, indicesT, R, indicesR));
}
return ret;
}
/**
* Returns the time series of dRMSD in a trajectory with regards to a reference point list
* @param t trajectory
* @param R reference point list
* @return time series of dRMSD
*/
public static ArrayList getSimilarityTimeSeriesDRMSD(Trajectory t, PointList R){
ArrayList ret = new ArrayList();
int dim = t.getNumberOfFrames();
for (int i = 0; i < dim; i++) {
PointList frame = t.getFrameAsPointList(i);
ret.add(getDRMSD(frame, R));
}
return ret;
}
/**
* Returns the time series of dRMSD in a trajectory with regards to a reference structure
* @param t trajectory
* @param R reference structure
* @return time series of dRMSD
*/
public static ArrayList getSimilarityTimeSeriesDRMSD(Trajectory t, Structure R){
return getSimilarityTimeSeriesDRMSD(t,R.getAllAtomCoordinates());
}
/**
* Returns the time series of dRMSD in a trajectory with regards to a reference structure
* taking into account only a subset of atoms
* @param t trajectory
* @param indicesT index set of atoms in the trajectory
* @param R reference structure
* @param indicesR index set of atoms in the reference structure
* @return time series of dRMSD
*/
public static ArrayList getSimilarityTimeSeriesDRMSD(Trajectory t, IndexSet indicesT, Structure R, IndexSet indicesR){
ArrayList ret = new ArrayList();
int dim = t.getNumberOfFrames();
for (int i = 0; i < dim; i++) {
Structure frame = t.getFrameAsStructure(i);
ret.add(getDRMSD(frame, indicesT, R, indicesR));
}
return ret;
}
/**
* Returns the time series of wdRMSD (weighted dRMSD) in a trajectory with regards to a reference point list
* @param t trajectory
* @param R reference point list
* @param W weight matrix
* @return time series of wdRMSD
*/
public static ArrayList getSimilarityTimeSeriesWDRMSD(Trajectory t, PointList R, Matrix W){
ArrayList ret = new ArrayList();
int dim = t.getNumberOfFrames();
for (int i = 0; i < dim; i++) {
PointList frame = t.getFrameAsPointList(i);
ret.add(getWDRMSD(frame, R, W));
}
return ret;
}
/**
* Returns the time series of wdRMSD (weighted dRMSD) in a trajectory with regards to a reference structure
* @param t trajectory
* @param R reference structure
* @param W weight matrix
* @return time series of wdRMSD
*/
public static ArrayList getSimilarityTimeSeriesWDRMSD(Trajectory t, Structure R, Matrix W){
return getSimilarityTimeSeriesWDRMSD(t,R.getAllAtomCoordinates(),W);
}
/**
* Returns the time series of wdRMSD (weighted dRMSD) in a trajectory with regards to a reference structure
* taking into account only a subset of atoms
* @param t trajectory
* @param indicesT index set of atoms in the trajectory
* @param R reference structure
* @param indicesR index set of atoms in the reference structure
* @param W weight matrix
* @return time series of wdRMSD
*/
public static ArrayList getSimilarityTimeSeriesWDRMSD(Trajectory t, IndexSet indicesT, Structure R, IndexSet indicesR, Matrix W){
ArrayList ret = new ArrayList();
int dim = t.getNumberOfFrames();
for (int i = 0; i < dim; i++) {
Structure frame = t.getFrameAsStructure(i);
ret.add(getWDRMSD(frame, indicesT, R, indicesR, W));
}
return ret;
}
// Difference distance matrix
/**
* Calculates the difference distance matrix between two point lists
* @param points1 first point list
* @param points2 second point list
* @return difference distance matrix
*
*/
public static Matrix getDifferenceDistanceMatrix(PointList points1, PointList points2){
Matrix d1 = Distances.getDistanceMatrix(points1);
Matrix d2 = Distances.getDistanceMatrix(points2);
return d1.minus(d2);
}
/**
* Calculates the atomic difference distance matrix between two structures
* @param s1 first structure
* @param s2 second structure
* @return difference distance matrix
*
*/
public static Matrix getDifferenceDistanceMatrix(Structure s1, Structure s2){
Matrix d1 = Distances.getAtomicDistanceMatrix(s1);
Matrix d2 = Distances.getAtomicDistanceMatrix(s2);
return d1.minus(d2);
}
/**
* Calculates the atomic difference distance matrix between two sets of atoms defined by two index sets in two structures
* @param s1 first structure
* @param indices1 first index set
* @param s2 second structure
* @param indices2 second index set
* @return difference distance matrix
*
*/
public static Matrix getDifferenceDistanceMatrix(Structure s1, IndexSet indices1, Structure s2, IndexSet indices2){
Matrix d1 = Distances.getAtomicDistanceMatrix(s1, indices1);
Matrix d2 = Distances.getAtomicDistanceMatrix(s2, indices2);
return d1.minus(d2);
}
// Find similar frames
/**
* Returns the set of frames in a trajectory that are more similar to a reference frame (based on the RMSD similarity measure) than a cutoff value
* @param t trajectory
* @param reference reference frame
* @param cutoff similarity cutoff
* @return frame index set
*/
public static FrameIndexSet findSimilarFramesRMSD(Trajectory t, PointList reference, double cutoff){
FrameIndexSet ret = new FrameIndexSet();
for (int i = 0; i < t.getNumberOfFrames(); i++) {
PointList frame = t.getFrameAsPointList(i);
if (Similarity.getRMSD(frame, reference)<=cutoff) ret.addFrame(i);
}
ret.setName("Similar[RMSD:"+cutoff+"]"+"(to:Noname)");
return ret;
}
/**
* Returns the list of frames in a trajectory that are more similar to a reference frame (based on the dRMSD similarity measure) than a cutoff value
* @param t trajectory
* @param reference reference frame
* @param cutoff similarity cutoff
* @return frame list
*/
public static FrameIndexSet findSimilarFramesDRMSD(Trajectory t, PointList reference, double cutoff){
FrameIndexSet ret = new FrameIndexSet();
for (int i = 0; i < t.getNumberOfFrames(); i++) {
PointList frame = t.getFrameAsPointList(i);
if (Similarity.getDRMSD(frame, reference)<=cutoff) ret.addFrame(i);
}
ret.setName("Similar[dRMSD:"+cutoff+"]"+"(to:Noname)");
return ret;
}
/**
* Returns the list of frames in a trajectory that are more similar to a reference distance matrix (based on the dRMSD similarity measure) than a cutoff value
* @param t trajectory
* @param reference reference distance matrix
* @param cutoff similarity cutoff
* @return frame list
*/
public static FrameIndexSet findSimilarFramesDRMSD(Trajectory t, Matrix reference, double cutoff){
FrameIndexSet ret = new FrameIndexSet();
for (int i = 0; i < t.getNumberOfFrames(); i++) {
PointList frame = t.getFrameAsPointList(i);
if (Similarity.getDRMSD(Distances.getDistanceMatrix(frame), reference)<=cutoff) ret.addFrame(i);
}
ret.setName("Similar[dRMSD:"+cutoff+"]"+"(to:Noname)");
return ret;
}
// Medoids
/**
* Calculates the medoid frame of a trajectory using the RMSD measure
* @param t trajectory
* @return medoid frame
*/
public static PointList getMedoidRMSD(Trajectory t){
Matrix S = getSimilarityMatrixRMSD(t);
int dim = S.getRowDimension();
int best = 0;
double min = 99999;
for (int i = 0; i < dim; i++) {
double sum = 0;
for (int j = 0; j < dim; j++) sum+=S.get(i, j);
if (sum