// Path: src/main/java/com/tiemens/secretshare/exceptions/SecretShareException.java
// public class SecretShareException
//     extends RuntimeException
// {
//     // ==================================================
//     // class static data
//     // ==================================================
// 
//     private static final long serialVersionUID = 2193317873773384997L;
// 
//     // ==================================================
//     // class static methods
//     // ==================================================
// 
// 
// 
//     // ==================================================
//     // instance data
//     // ==================================================
// 
//     // ==================================================
//     // factories
//     // ==================================================
// 
//     // ==================================================
//     // constructors
//     // ==================================================
// 
// 
//     /** Constructs a new runtime exception with the specified detail message.
//      * The cause is not initialized, and may subsequently be initialized by a
//      * call to {@link #initCause}.
//      *
//      * @param   message   the detail message. The detail message is saved for
//      *          later retrieval by the {@link #getMessage()} method.
//      */
//     public SecretShareException(final String message)
//     {
//         super(message);
//     }
// 
//     /**
//      * Constructs a new runtime exception with the specified detail message and
//      * cause.  <p>Note that the detail message associated with
//      * <code>cause</code> is <i>not</i> automatically incorporated in
//      * this runtime exception's detail message.
//      *
//      * @param  message the detail message (which is saved for later retrieval
//      *         by the {@link #getMessage()} method).
//      * @param  cause the cause (which is saved for later retrieval by the
//      *         {@link #getCause()} method).  (A <code>null</code> value is
//      *         permitted, and indicates that the cause is nonexistent or
//      *         unknown.)
//      */
//     public SecretShareException(final String message,
//                                 final Throwable cause)
//     {
//         super(message, cause);
//     }
// 
//     // ==================================================
//     // public methods
//     // ==================================================
// 
//     // ==================================================
//     // non public methods
//     // ==================================================
// }


import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.tiemens.secretshare.exceptions.SecretShareException;
/*******************************************************************************
 * Copyright (c) 2009, 2014 Tim Tiemens.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License v2.1
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
 *
 * 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 Lesser General Public License for more details.
 *
 *
 * Contributors:
 *     Tim Tiemens - initial API and implementation
 *******************************************************************************/
package com.tiemens.secretshare.math.matrix;




public class NumberSimplex<E extends Number>
{

    // ==================================================
    // class static data
    // ==================================================

    // ==================================================
    // class static methods
    // ==================================================

    // ==================================================
    // instance data
    // ==================================================

    /** Abstract method to create a matrix */
    private final NumberMatrix<E> matrix;
    /** index of the "B" column - i.e. the index of the constants */
    private final int constantsInThisColumnIndex; // 0-based index

    // computed values
    private NumberOrVariable<E>[] mTop;
    private NumberOrVariable<E>[] mSide;
    private E[][] mArrayhide;
    private Map<NumberOrVariable<E>, E> mAnswers;

    // ==================================================
    // factories
    // ==================================================

    // ==================================================
    // constructors
    // ==================================================


    public NumberSimplex(NumberMatrix<E> inMatrix, int inConstantsIndex)
    {
        matrix = inMatrix;
        constantsInThisColumnIndex = inConstantsIndex;
        //System.out.println("SIMPLEX cons matrix.h=" + matrix.getHeight() + " matrix.w=" + matrix.getWidth() +
        //                   " m.array.length=" +
        //                   matrix.getArray().length + " m.array[0].length=" + matrix.getArray()[0].length);

    }


    // ==================================================
    // public methods
    // ==================================================

    // .initForSolve(), then .solve(), then .getAnswer()

    public void initForSolve(PrintStream out)
    {
        final int width = matrix.getWidth();
        final int height = matrix.getHeight();

        mTop = fillInTopVariables(width - 1);
        mSide = fillInConstants(height);
        //System.out.println("INIT-SOLVE matrix.h=" + matrix.getHeight() +
        //        " matrix.w=" + matrix.getWidth() + " m.array.length=" +
        //        matrix.getArray().length + " m.array[0].length=" + matrix.getArray()[0].length);
        mArrayhide = fillInArray(matrix.getArray(), constantsInThisColumnIndex);

        nullPrintln(out, "INIT-SOLVE, TOP.length = " + mTop.length + " matrix.height=" + height + " matrix.w=" + width);
        printTopArraySide(out);

    }

    public void solve(PrintStream out)
    {
        final int height = mArrayhide.length;
        final int width = mArrayhide[0].length;
        if (height != width)
        {
// Path: src/main/java/com/tiemens/secretshare/exceptions/SecretShareException.java
// public class SecretShareException
//     extends RuntimeException
// {
//     // ==================================================
//     // class static data
//     // ==================================================
// 
//     private static final long serialVersionUID = 2193317873773384997L;
// 
//     // ==================================================
//     // class static methods
//     // ==================================================
// 
// 
// 
//     // ==================================================
//     // instance data
//     // ==================================================
// 
//     // ==================================================
//     // factories
//     // ==================================================
// 
//     // ==================================================
//     // constructors
//     // ==================================================
// 
// 
//     /** Constructs a new runtime exception with the specified detail message.
//      * The cause is not initialized, and may subsequently be initialized by a
//      * call to {@link #initCause}.
//      *
//      * @param   message   the detail message. The detail message is saved for
//      *          later retrieval by the {@link #getMessage()} method.
//      */
//     public SecretShareException(final String message)
//     {
//         super(message);
//     }
// 
//     /**
//      * Constructs a new runtime exception with the specified detail message and
//      * cause.  <p>Note that the detail message associated with
//      * <code>cause</code> is <i>not</i> automatically incorporated in
//      * this runtime exception's detail message.
//      *
//      * @param  message the detail message (which is saved for later retrieval
//      *         by the {@link #getMessage()} method).
//      * @param  cause the cause (which is saved for later retrieval by the
//      *         {@link #getCause()} method).  (A <code>null</code> value is
//      *         permitted, and indicates that the cause is nonexistent or
//      *         unknown.)
//      */
//     public SecretShareException(final String message,
//                                 final Throwable cause)
//     {
//         super(message, cause);
//     }
// 
//     // ==================================================
//     // public methods
//     // ==================================================
// 
//     // ==================================================
//     // non public methods
//     // ==================================================
// }


// Path: src/main/java/com/tiemens/secretshare/math/matrix/NumberSimplex.java
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.tiemens.secretshare.exceptions.SecretShareException;

/*******************************************************************************
 * Copyright (c) 2009, 2014 Tim Tiemens.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License v2.1
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
 *
 * 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 Lesser General Public License for more details.
 *
 *
 * Contributors:
 *     Tim Tiemens - initial API and implementation
 *******************************************************************************/
package com.tiemens.secretshare.math.matrix;




public class NumberSimplex<E extends Number>
{

    // ==================================================
    // class static data
    // ==================================================

    // ==================================================
    // class static methods
    // ==================================================

    // ==================================================
    // instance data
    // ==================================================

    /** Abstract method to create a matrix */
    private final NumberMatrix<E> matrix;
    /** index of the "B" column - i.e. the index of the constants */
    private final int constantsInThisColumnIndex; // 0-based index

    // computed values
    private NumberOrVariable<E>[] mTop;
    private NumberOrVariable<E>[] mSide;
    private E[][] mArrayhide;
    private Map<NumberOrVariable<E>, E> mAnswers;

    // ==================================================
    // factories
    // ==================================================

    // ==================================================
    // constructors
    // ==================================================


    public NumberSimplex(NumberMatrix<E> inMatrix, int inConstantsIndex)
    {
        matrix = inMatrix;
        constantsInThisColumnIndex = inConstantsIndex;
        //System.out.println("SIMPLEX cons matrix.h=" + matrix.getHeight() + " matrix.w=" + matrix.getWidth() +
        //                   " m.array.length=" +
        //                   matrix.getArray().length + " m.array[0].length=" + matrix.getArray()[0].length);

    }


    // ==================================================
    // public methods
    // ==================================================

    // .initForSolve(), then .solve(), then .getAnswer()

    public void initForSolve(PrintStream out)
    {
        final int width = matrix.getWidth();
        final int height = matrix.getHeight();

        mTop = fillInTopVariables(width - 1);
        mSide = fillInConstants(height);
        //System.out.println("INIT-SOLVE matrix.h=" + matrix.getHeight() +
        //        " matrix.w=" + matrix.getWidth() + " m.array.length=" +
        //        matrix.getArray().length + " m.array[0].length=" + matrix.getArray()[0].length);
        mArrayhide = fillInArray(matrix.getArray(), constantsInThisColumnIndex);

        nullPrintln(out, "INIT-SOLVE, TOP.length = " + mTop.length + " matrix.height=" + height + " matrix.w=" + width);
        printTopArraySide(out);

    }

    public void solve(PrintStream out)
    {
        final int height = mArrayhide.length;
        final int width = mArrayhide[0].length;
        if (height != width)
        {
            throw new SecretShareException("h=" + height + " w=" + width + " must match");