/* * Copyright 2003-2010 Tufts University Licensed under the * Educational Community License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may * obtain a copy of the License at * * http://www.osedu.org/licenses/ECL-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an "AS IS" * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing * permissions and limitations under the License. */ package edu.tufts.vue.compare; import java.util.*; import tufts.vue.*; /** * @author akumar03 * @author Scott Fraize re-write 2012 */ public class WeightAggregate extends ConnectivityMatrix { private static final org.apache.log4j.Logger Log = org.apache.log4j.Logger.getLogger(WeightAggregate.class); private final int count; public static WeightAggregate create(List<ConnectivityMatrix> matrices) { final IndexedCountingSet preComputed = new IndexedCountingSet(); for (ConnectivityMatrix matrix : matrices) preComputed.addAll(matrix.keys); // We pre-compute the index so the matrix aggregate will know how big // of a matrix will be required to hold it all. return new WeightAggregate(preComputed, matrices); } protected WeightAggregate(IndexedCountingSet preComputed, List<ConnectivityMatrix> matrices) { super(preComputed); this.count = matrices.size(); for (ConnectivityMatrix input : matrices) mergeInConnectionValues(input); } /** * This will search the input matrix for all non-zero connection values and add them to the * connection value for the same two keys in this aggregate. This will only work if the keys * from the input matrix have already been merged to this aggregate, and the matrix for this * aggregate has been sized to handle all of the input keys. */ private void mergeInConnectionValues(final ConnectivityMatrix input) { Log.info("mergeIn " + input); final int inSize = input.size(); for (int index1 = 0; index1 < inSize; index1++) { for (int index2 = 0; index2 < inSize; index2++) { final int connection = input.cx[index1][index2]; if (connection != 0) { final Object key1 = input.keys.get(index1); final Object key2 = input.keys.get(index2); this.cx[this.keys.indexOf(key1)] [this.keys.indexOf(key2)] += connection; // Log.debug("merged " + connection + " for " + key1 + "," + key2); } } } } public ConnectivityMatrix getAggregate(){ return this; } /** @return the number of nodes with the given merge-key (e.g. label) in the aggregate */ public int getNodeCount(Object key) { try { return super.keys.count(key); } catch (NullPointerException e) { Log.warn("getNodeCount: key not present: " + tufts.Util.tags(key)); return 0; } } /** this does not return exactly the % of maps a node is found on: a node many times * on a single map will increase it's weight, yes? todo: do I have that right? * See mergeInConnectionValues... */ public double getPercentFound(LWComponent c) { final int nodeCount = getNodeCount(Util.getMergeProperty(c)); if (nodeCount <= 0) { Log.warn("not found w/key: " + c); return 0.0; } return (100.0 * nodeCount) / (double) this.count; } /** @return the number of matricies summed into this aggregate */ public int getCount() { return this.count; } }