All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.citec.tcs.alignment.PathList Maven / Gradle / Ivy

/* 
 * TCS Alignment Toolbox
 * 
 * Copyright (C) 2013-2015
 * Benjamin Paaßen, Georg Zentgraf
 * AG Theoretical Computer Science
 * Centre of Excellence Cognitive Interaction Technology (CITEC)
 * University of Bielefeld
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program 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 Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see .
 */
package de.citec.tcs.alignment;

import de.citec.tcs.alignment.comparators.DerivableComparator;
import de.citec.tcs.alignment.sequence.Sequence;
import de.citec.tcs.alignment.sequence.Value;
import java.util.ArrayList;

/**
 * This is a list-based datastructure accumulating multiple AlignmentPaths. It
 * is also able to calculate the average derivative of all given paths.
 *
 * @author Benjamin Paassen - [email protected]
 */
public class PathList extends ArrayList implements AlignmentDerivativeAlgorithm {

	public PathList() {
		super();
	}

	/**
	 * {@inheritDoc }
	 */
	@Override
	public  Y calculateParameterDerivative(
			DerivableComparator comp, String keyword) {
		return comp.transformToResult(calculateRawParameterDerivative(comp, keyword));
	}

	/**
	 * {@inheritDoc }
	 */
	@Override
	public  double[] calculateRawParameterDerivative(
			DerivableComparator comp, String keyword) {

		final int P = comp.getNumberOfParameters();
		final double[] derivatives = new double[P];

		if (this.isEmpty()) {
			return derivatives;
		}
		/*
		 * now we let each path calculate its derivative and calculate the
		 * average.
		 */
		for (final AlignmentPath path : this) {
			final double[] pathDerivatives = path.calculateRawParameterDerivative(comp, keyword);
			for (int p = 0; p < P; p++) {
				derivatives[p] += pathDerivatives[p];
			}
		}
		for (int p = 0; p < P; p++) {
			derivatives[p] /= (double) this.size();
		}

		return derivatives;
	}

	/**
	 * {@inheritDoc }
	 */
	@Override
	public double[] calculateWeightDerivative() {
		if (this.isEmpty()) {
			throw new UnsupportedOperationException(
					"Weight derivative without any paths is not defined.");
		}


		/*
		 * now we let each path calculate its weight derivative and take the
		 * average.
		 */
		final int K = get(0).getSpecificaton().size();
		final double[] derivative = new double[K];
		for (final AlignmentPath path : this) {
			final double[] pathDerivative = path.calculateWeightDerivative();
			for (int k = 0; k < K; k++) {
				derivative[k] += pathDerivative[k];
			}
		}
		for (int k = 0; k < K; k++) {
			derivative[k] /= (double) this.size();
		}
		return derivative;
	}

	/**
	 * This transforms the PathList to a matrix, mostly for visualization
	 * purposes. The matrix is equivalent the dynamic programming algorithm of
	 * the StrictAlgorithm that created this PathMap. However, only those
	 * entries are non-zero that are relevant for at least one path in this map.
	 * The value of the output matrix is defined as the average over
	 * all path toMatrix outputs.
	 *
	 * @return the dynamic programming matrix of the algorithm that created this
	 *         PathList with non-zero entries at positions that are relevant for at
	 *         least
	 *         one path.
	 */
	public double[][] toMatrix() {

		final int m = get(0).getLeft().getNodes().size();
		final int n = get(0).getRight().getNodes().size();

		final double[][] out = new double[m + 1][n + 1];
		for (final AlignmentPath path : this) {
			int i = 0;
			int j = 0;
			double oldScore = 0;
			for (final Operation op : path.getOperations()) {
				switch (op.getType()) {
					case DELETION:
					case SKIPDELETION:
					case DELETIONREPLACEMENT:
						i++;
						break;
					case INSERTION:
					case SKIPINSERTION:
					case INSERTIONREPLACEMENT:
						j++;
						break;
					case REPLACEMENT:
						i++;
						j++;
						break;
					default:
						throw new UnsupportedOperationException("Unsupported operation: " + op.getType());
				}
				out[i][j] += oldScore + op.getWeightedLocalCost();
				oldScore = out[i][j];
			}
		}

		for (int i = 0; i < m; i++) {

			for (int j = 0; j < m; j++) {
				if (out[i][j] > 0) {
					out[i][j] /= (double) this.size();
				}
			}
		}
		return out;
	}

	/**
	 * Returns the average distance of all stored paths.
	 *
	 * @return the average distance of all stored paths.
	 */
	@Override
	public double getDistance() {
		if (this.isEmpty()) {
			throw new UnsupportedOperationException(
					"Average distance without any paths is not defined.");
		}
		double sum = 0;
		for (final AlignmentPath p : this) {
			sum += p.getDistance();
		}
		return sum / (double) this.size();
	}

	/**
	 * {@inheritDoc }
	 */
	@Override
	public Sequence getLeft() {
		if (this.isEmpty()) {
			throw new UnsupportedOperationException("This PathList is empty.");
		}
		Sequence left = null;
		for (final AlignmentPath p : this) {
			if (left == null) {
				left = p.getLeft();
			} else {
				if (left != p.getLeft()) {
					throw new UnsupportedOperationException("The AlignmentPaths in this list have no consistent left sequence.");
				}
			}
		}
		return left;
	}

	/**
	 * {@inheritDoc }
	 */
	@Override
	public Sequence getRight() {
		if (this.isEmpty()) {
			throw new UnsupportedOperationException("This PathList is empty.");
		}
		Sequence right = null;
		for (final AlignmentPath p : this) {
			if (right == null) {
				right = p.getRight();
			} else {
				if (right != p.getRight()) {
					throw new UnsupportedOperationException("The AlignmentPaths in this list have no consistent right sequence.");
				}
			}
		}
		return right;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy