package org.seqcode.motifs; import org.seqcode.data.motifdb.WeightMatrix; import org.seqcode.ml.clustering.PairwiseElementMetric; /** * compares two weight matrices and returns the euclidian distance between them * normalized over the length of the query matrix */ public class WMNormalizedDistanceComparator implements WMComparator, PairwiseElementMetric<WeightMatrix> { public double compare(WeightMatrix query, WeightMatrix target) { if (target.matrix.length < query.matrix.length) { return Double.MAX_VALUE; } double minscore = Double.MAX_VALUE; for (int offset = 0; offset <= target.matrix.length - query.matrix.length; offset++) { double score = 0; for (int i = 0; i < query.matrix.length; i++) { score += Math.sqrt(Math.pow(query.matrix[i]['A'] - target.matrix[offset+i]['A'],2) + Math.pow(query.matrix[i]['C'] - target.matrix[offset+i]['C'],2) + Math.pow(query.matrix[i]['G'] - target.matrix[offset+i]['G'],2) + Math.pow(query.matrix[i]['T'] - target.matrix[offset+i]['T'],2)); } if (score < minscore) { minscore = score; } score = 0; for (int i = 0; i < query.matrix.length; i++) { score += Math.sqrt(Math.pow(query.matrix[query.matrix.length - i -1]['T'] - target.matrix[offset+i]['A'],2) + Math.pow(query.matrix[query.matrix.length - i -1]['G'] - target.matrix[offset+i]['C'],2) + Math.pow(query.matrix[query.matrix.length - i -1]['C'] - target.matrix[offset+i]['G'],2) + Math.pow(query.matrix[query.matrix.length - i -1]['A'] - target.matrix[offset+i]['T'],2)); } if (score < minscore) { minscore = score; } } return minscore / query.length(); } public double evaluate(WeightMatrix query, WeightMatrix target) { if (query.length() > target.length()) { return compare(target,query); } else { return compare(query,target); } } }