gt: 		lastValues = evalValues();
context: 
  
  
  
  
  
  
  //$$strtCprt
  /**
  * Simple Algebra 
  * 
  * Copyright (C) 2014 Thornton Green
  * 
  * This program is free software; you can redistribute it and/or modify it under the terms of the GNU 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 General Public License for more details.
  * You should have received a copy of the GNU General Public License along with this program; if not, 
  * see <http://www.gnu.org/licenses>.
  * Additional permission under GNU GPL version 3 section 7
  *
  */
  //$$endCprt
  
  
  
  
  
  
  package simplealgebra.algo;
  
  import java.math.BigInteger;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.Map.Entry;
  
  import simplealgebra.BadCreationException;
  import simplealgebra.CloneThreadCache;
  import simplealgebra.Elem;
  import simplealgebra.ElemFactory;
  import simplealgebra.NotInvertibleException;
  import simplealgebra.NumDimensions;
  import simplealgebra.SquareMatrixElem;
  import simplealgebra.algo.DescentAlgorithmMultiElem.DescentInverseFailedException;
  import simplealgebra.et.EinsteinTensorElem;
  import simplealgebra.ga.GeometricAlgebraMultivectorElem;
  import simplealgebra.ga.GeometricAlgebraMultivectorElemFactory;
  import simplealgebra.ga.GeometricAlgebraOrd;
  import simplealgebra.symbolic.MultiplicativeDistributionRequiredException;
  import simplealgebra.symbolic.SCacheKey;
  import simplealgebra.symbolic.SymbolicElem;
  import simplealgebra.symbolic.SymbolicElemFactory;
  import simplealgebra.symbolic.SymbolicZero;
  
  
  /**
   * Evaluator for multivariate Newton-Raphson, using the formula <math display="inline">
   * <mrow>
   *  <msub>
   *          <mi>J</mi>
   *        <mi>F</mi>
   *  </msub>
   *  <mfenced open="(" close=")" separators=",">
   *    <mrow>
   *      <msub>
   *              <mi>x</mi>
   *            <mi>n</mi>
   *      </msub>
   *    </mrow>
   *  </mfenced>
   *  <mfenced open="(" close=")" separators=",">
   *    <mrow>
   *      <msub>
   *              <mi>x</mi>
   *          <mrow>
   *            <mi>n</mi>
   *            <mo>+</mo>
   *            <mn>1</mn>
   *          </mrow>
   *      </msub>
   *      <mo>-</mo>
   *      <msub>
   *              <mi>x</mi>
   *            <mi>n</mi>
   *      </msub>
   *    </mrow>
   *  </mfenced>
   *  <mo>=</mo>
   *  <mo>-</mo>
   *  <mi>F</mi>
   *  <mfenced open="(" close=")" separators=",">
   *    <mrow>
   *      <msub>
   *              <mi>x</mi>
   *            <mi>n</mi>
   *      </msub>
   *    </mrow>
   *  </mfenced>
   * </mrow>
   * </math>
   *
   * Includes a simple backtracking method.
   * 
   * <P>See http://en.wikipedia.org/wiki/Newton's_method
   * 
   * This documentation should be viewed using Firefox version 33.1.1 or above.
   * 
   * @author thorngreen
   *
   * @param <U> The number of dimensions.
   * @param <R> The enclosed type for the evaluation.
   * @param <S> The factory for the enclosed type for the evaluation.
   */
  public class NewtonRaphsonMultiElemSimpleBacktrackCacheFinal<U extends NumDimensions, R extends Elem<R,?>, S extends ElemFactory<R,S>>
  	extends DescentAlgorithmMultiElem<U,R,S> {
  	
  	/**
  	 * The functions over which to evaluate Netwon-Raphson.
  	 */
  	protected Iterable<HashSet<BigInteger>> functionsKeys;
  	
  	/**
  	 * The last iteration values calculated.
  	 */
  	protected GeometricAlgebraMultivectorElem<U,GeometricAlgebraOrd<U>,R,S> lastValues = null;
  	
  	/**
  	 * The implicit space over which to evaluate the functions.
  	 */
  	protected HashMap<? extends Elem<?,?>,? extends Elem<?,?>> implicitSpace = null;
  	
  	/**
  	 * The evaluations of the functions for use in the Newton-Raphson method.
  	 */
  	protected GeometricAlgebraMultivectorElem<U,GeometricAlgebraOrd<U>,SymbolicElem<R,S>,SymbolicElemFactory<R,S>> evals;
  	
  	/**
  	 * The evaluation of the Jacobian for use in the Newton-Raphson method.
  	 */
  	protected SquareMatrixElem<U,SymbolicElem<R,S>,SymbolicElemFactory<R,S>> partialEvalJacobian;
  	
  	/**
  	 * The number of dimensions over which to evaluate Newton-Raphson.
  	 */
  	protected U dim;
  	
  	/**
  	 * The factory for the enclosed type.
  	 */
  	protected SymbolicElemFactory<R,S> sfac;
  	
  	/**
  	 * Input parameters for the algorithm.
  	 */
  	protected DescentAlgorithmMultiElemInputParamCallbacks<U,R,S> param;
  	
  	/**
  	 * Indicates that the iterations stopped because they could no longer proceed.
  	 */
  	protected boolean iterationsStopped = false;
  	
  	
  	/**
  	 * Constructs the evaluator.
  	 * 
  	 * @param _param The input parameters for the evaluator.
  	 * @param cache Cache to be used for symbolic evals if useCachedEval() returns true.
  	 * @throws NotInvertibleException
  	 * @throws MultiplicativeDistributionRequiredException
  	 */
  	public NewtonRaphsonMultiElemSimpleBacktrackCacheFinal( 
  			final DescentAlgorithmMultiElemInputParam<U,R,S> _param,
  			final HashMap<SCacheKey<SymbolicElem<R, S>, SymbolicElemFactory<R, S>>, SymbolicElem<R, S>> cache )
  					throws NotInvertibleException, MultiplicativeDistributionRequiredException
  	{
  		functionsKeys = _param.getFunctions().getKeySet();
  		dim = _param.getDim();
  		sfac = _param.getSfac();
  		param = _param.getCallbacks();
  		final SimplificationType useSimplification = param.useSimplification();
  		final boolean useCachedEval = param.useCachedEval();
  		evals = new GeometricAlgebraMultivectorElem<U,GeometricAlgebraOrd<U>,SymbolicElem<R,S>,SymbolicElemFactory<R,S>>( 
  				_param.getSfac() , _param.getDim() , new GeometricAlgebraOrd<U>() );
  		for( final Entry<HashSet<BigInteger>, SymbolicElem<SymbolicElem<R, S>, SymbolicElemFactory<R, S>>> ii : _param.getFunctions().getEntrySet() )
  		{
  			final HashSet<BigInteger> key = ii.getKey();
  			SymbolicElem<R,S> evalF = useCachedEval ? 
  					ii.getValue().evalCached( _param.getImplicitSpaceFirstLevel() , cache ) :
  					ii.getValue().eval( _param.getImplicitSpaceFirstLevel() );
  			evalF = handleSimplification( evalF , useSimplification );
  			evals.setVal( key , evalF );
  		}
  		partialEvalJacobian = new SquareMatrixElem<U,SymbolicElem<R,S>,SymbolicElemFactory<R,S>>(
  				_param.getSfac() , _param.getDim() );
  		BigInteger bcnt = BigInteger.ZERO;
  		for( final ArrayList<? extends Elem<?,?>> withRespectTo : _param.getWithRespectTos() )
  		{
  			final BigInteger key = bcnt;
  			bcnt = bcnt.add( BigInteger.ONE );
  			for( final HashSet<BigInteger> key2A : functionsKeys )
  			{
  				final BigInteger key2 = key2A.iterator().next();
  				final SymbolicElem<SymbolicElem<R,S>,SymbolicElemFactory<R,S>> fun = _param.getFunctions().get( key2A );
  				SymbolicElem<R,S> evalP = useCachedEval ?
  						fun.evalPartialDerivativeCached( withRespectTo , _param.getImplicitSpaceFirstLevel() , cache) :
  						fun.evalPartialDerivative( withRespectTo , _param.getImplicitSpaceFirstLevel() );
  				evalP = handleSimplification( evalP , useSimplification );
  				if( !( evalP instanceof SymbolicZero<?,?> ) ) // Allow the matrix to be sparse in instances where the derivative is zero.
  				{
  					partialEvalJacobian.setVal( key2 , key , evalP );
  				}
  			}
  		}
  	}
  	
  	
  	/**
  	 * Runs Newton-Raphson.
  	 * 
  	 * @param implicitSpaceInitialGuess The implicit space for the initial guess.
  	 * @return An iterated result.
  	 * @throws NotInvertibleException
  	 * @throws MultiplicativeDistributionRequiredException
  	 */
  	public GeometricAlgebraMultivectorElem<U,GeometricAlgebraOrd<U>,R,S> eval( HashMap<? extends Elem<?,?>,? extends Elem<?,?>> implicitSpaceInitialGuess ) throws NotInvertibleException, MultiplicativeDistributionRequiredException
  	{	
  		iterationsStopped = false;
  		implicitSpace = implicitSpaceInitialGuess;
  