/* * File: OverconstrainedMatrixVectorMultiplier.java * Authors: Jeremy D. Wendt * Company: Sandia National Laboratories * Project: Cognitive Foundry * * Copyright 2016, Sandia Corporation. * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive * license for use of this work by or on behalf of the U.S. Government. * Export of this program may require a license from the United States * Government. See CopyrightHistory.txt for complete details. */ package gov.sandia.cognition.learning.algorithm.minimization.matrix; import gov.sandia.cognition.annotation.PublicationReference; import gov.sandia.cognition.annotation.PublicationType; import gov.sandia.cognition.math.matrix.Matrix; import gov.sandia.cognition.math.matrix.Vector; /** * Implements an overconstrainted matrix-vector multiplication. * * @author Jeremy D. Wendt * @since 4.0.0 */ @PublicationReference(author = "Jonathan Richard Shewchuk", title = "An Introduction to the Conjugate Gradient Method Without the Agonizing Pain", type = PublicationType.WebPage, year = 1994, url = "http://www.cs.cmu.edu/~quake-papers/painless-conjugate-gradient.pdf‎") public class OverconstrainedMatrixVectorMultiplier extends MatrixVectorMultiplier { private OverconstrainedMatrixVectorMultiplier() { super(null); throw new UnsupportedOperationException("Null constructor not supported"); } /** * Clones the input matrix to prevent any later edits to the input from * changing the results of iterative multiplications. * * @param m The matrix to multiply with */ OverconstrainedMatrixVectorMultiplier(Matrix m) { super(m); if (m.getNumRows() < m.getNumColumns()) { throw new IllegalArgumentException("Unable to minimize an " + "underconstrained problem"); } } /** * Returns m times input. * * @param input The vector to multiply by m. * @return m times input. */ @Override public Vector evaluate(Vector input) { return transposeMult(super.evaluate(input)); } /** * Return A^(T) * input. * * @param input The vector to multiply by the transpose of A * @return A^(T) * input */ public Vector transposeMult(Vector input) { // NOTE: This computes A^(T)x by the following: // return (x^(T)A)^(T) // But as we don't have to transpose vectors in this code, it requires // no real transposes at all. return input.times(m); } @Override public boolean equals(Object o) { if (!(o instanceof OverconstrainedMatrixVectorMultiplier)) { return false; } // Other than the type, I don't add anything here return super.equals(o); } @Override public int hashCode() { int hash = 1; return hash * 17 + super.hashCode(); } }