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

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

/* 
 * TCS Alignment Toolbox Version 3
 * 
 * Copyright (C) 2016
 * Benjamin Paaßen
 * 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.Comparator;
import de.citec.tcs.alignment.comparators.DerivableComparator;
import de.citec.tcs.alignment.comparators.Gradient;
import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
import lombok.NonNull;

/**
 * This class models an Alignment as it is given out by a strict alignment.
 * Such an alignment is defined as a sequence of alignment operations transforming the
 * left input Sequence to the right one.
 *
 * By listing those operations AlignmentPaths are able to calculate the strict
 * derivative of the AlignmentAlgorithm.
 *
 * @author Benjamin Paassen - [email protected]
 * @param  the class of the elements in the left input sequence.
 * @param  the class of the elements in the right input sequence.
 */
public class Alignment extends ArrayList> implements DerivableAlignmentDistance {

	/**
	 * The Comparator that was used to compute this Alignment.
	 *
	 */
	@Getter
	@NonNull
	private final Comparator comparator;
	@NonNull
	private final List left;
	@NonNull
	private final List right;
	private final double distance;

	public Alignment(@NonNull List> operations, @NonNull Comparator comparator,
			@NonNull List left, @NonNull List right, double distance) {
		super(operations);
		this.comparator = comparator;
		this.left = left;
		this.right = right;
		this.distance = distance;
	}

	public Alignment(@NonNull Comparator comparator,
			@NonNull List left, @NonNull List right, double distance) {
		this(new ArrayList>(), comparator, left, right, distance);
	}

	/**
	 * A copy constructor.
	 *
	 * @param copy the Alignment that shall be copied.
	 */
	public Alignment(Alignment copy) {
		super();
		this.left = copy.left;
		this.right = copy.right;
		this.comparator = copy.comparator;
		this.distance = copy.distance;
		for (final Operation op : copy) {
			this.add(new Operation<>(op));
		}
	}

	@Override
	public List getLeft() {
		return left;
	}

	@Override
	public List getRight() {
		return right;
	}

	@Override
	public double getDistance() {
		return distance;
	}

	/**
	 * This transforms the Alignment to a matrix, mostly for visualization
	 * purposes. The matrix is equivalent the dynamic programming algorithm of
	 * the StrictAlgorithm that created this path. However, only those entries
	 * are non-zero that are relevant for this path.
	 *
	 * @return the dynamic programming matrix of the algorithm that created this
	 * path with non-zero entries at positions that are relevant for this path.
	 */
	public double[][] toMatrix() {
		final double[][] out = new double[left.size() + 1][right.size() + 1];
		int i = 0;
		int j = 0;
		double oldScore = 0;
		for (final Operation op : this) {
			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.getDistance();
			oldScore = out[i][j];
		}
		return out;
	}

	@Override
	public double[] computeGradient(DerivableComparator comp) {
		final int P = comp.getNumberOfParameters();
		final double[] gradient = new double[P];
		for (final Operation op : this) {
			final Gradient grad = comp.computeGradient(op.getType(), op.getLeft(), op.getRight());
			while (grad.notEmpty()) {
				gradient[grad.currentParameterIndex()] += grad.currentValue();
				grad.next();
			}
		}
		return gradient;
	}

	@Override
	public String toString() {
		final StringBuilder builder = new StringBuilder();
		builder.append("Distance = ");
		builder.append(distance);
		builder.append("\n");
		for (final Operation op : this) {
			builder.append(op.toString());
			builder.append("\n");
		}
		return builder.toString();
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy