<commit_before>/******************************************************************************
 *                                                                             *
 *  Copyright: (c) Syncleus, Inc.                                              *
 *                                                                             *
 *  You may redistribute and modify this source code under the terms and       *
 *  conditions of the Open Source Community License - Type C version 1.0       *
 *  or any later version as published by Syncleus, Inc. at www.syncleus.com.   *
 *  There should be a copy of the license included with this file. If a copy   *
 *  of the license is not included you are granted no right to distribute or   *
 *  otherwise use this file except through a legal and valid license. You      *
 *  should also contact Syncleus, Inc. at the information below if you cannot  *
 *  find a license:                                                            *
 *                                                                             *
 *  Syncleus, Inc.                                                             *
 *  2604 South 12th Street                                                     *
 *  Philadelphia, PA 19148                                                     *
 *                                                                             *
 ******************************************************************************/
package com.syncleus.dann.math.statistics;

import java.util.*;
import java.util.Map.Entry;
import com.syncleus.dann.math.linear.*;

public class SimpleMarkovChain<S> extends AbstractMarkovChain<S>
{
	private final RealMatrix transitionProbabilityMatrix;
	private final ArrayList<List<S>> rowMapping;
	private final ArrayList<S> columnMapping;
	private final Set<S> states;
	private final int order;
	private final ArrayDeque<S> history;
	private static final double MAXIMUM_ROW_ERROR = 0.00001;
	private static final Random RANDOM = new Random();

	public SimpleMarkovChain(final Map<List<S>, Map<S, Double>> transitionProbabilities, final int order, final Set<S> states)
	{
		this.history = new ArrayDeque<S>(order);
		this.order = order;
		this.states = Collections.unmodifiableSet(states);
		this.rowMapping = new ArrayList<List<S>>();

		final int rows = transitionProbabilities.size();
		final int columns = this.states.size();
		final double[][] matrixValues = new double[rows][columns];

		//this.columnMapping = new ArrayList<S>(this.states);  // <-- didnt get the states in the correct order

        //Generate the column mapping from the first element of each transition probability's entry key (which is a list of states)
        //iterates through column mapping, matching rowheading leading elements
        this.columnMapping = new ArrayList<S>();
        for(final Entry<List<S>, Map<S, Double>> transitionProbability : transitionProbabilities.entrySet())
		{
			final List<S> rowHeader = Collections.unmodifiableList(new ArrayList<S>(transitionProbability.getKey()));
            if (rowHeader.size() == 0)
                columnMapping.add(null);
            else
                columnMapping.add(rowHeader.get(0));
        }

		//iterate through all the new rows<commit_msg>Fixes for higher order (>1) chains.  Higher-order chains currently fail to calculate steady-state probabilities, but they do generateTranisition().  So a new unit test, TestSimpleMarkovChainHigherOrder tests these for up to order=4 by generating a sequence of predicted SUNNY/RAINY states.  The oprevious two markov tests still pass as per the previous commit.<commit_after>/******************************************************************************
 *                                                                             *
 *  Copyright: (c) Syncleus, Inc.                                              *
 *                                                                             *
 *  You may redistribute and modify this source code under the terms and       *
 *  conditions of the Open Source Community License - Type C version 1.0       *
 *  or any later version as published by Syncleus, Inc. at www.syncleus.com.   *
 *  There should be a copy of the license included with this file. If a copy   *
 *  of the license is not included you are granted no right to distribute or   *
 *  otherwise use this file except through a legal and valid license. You      *
 *  should also contact Syncleus, Inc. at the information below if you cannot  *
 *  find a license:                                                            *
 *                                                                             *
 *  Syncleus, Inc.                                                             *
 *  2604 South 12th Street                                                     *
 *  Philadelphia, PA 19148                                                     *
 *                                                                             *
 ******************************************************************************/
package com.syncleus.dann.math.statistics;

import java.util.*;
import java.util.Map.Entry;
import com.syncleus.dann.math.linear.*;

public class SimpleMarkovChain<S> extends AbstractMarkovChain<S>
{
	private final RealMatrix transitionProbabilityMatrix;
	private final ArrayList<List<S>> rowMapping;
	private final ArrayList<S> columnMapping;
	private final Set<S> states;
	private final int order;
	private final ArrayDeque<S> history;
	private static final double MAXIMUM_ROW_ERROR = 0.00001;
	private static final Random RANDOM = new Random();

	public SimpleMarkovChain(final Map<List<S>, Map<S, Double>> transitionProbabilities, final int order, final Set<S> states)
	{
		this.history = new ArrayDeque<S>(order);
		this.order = order;
		this.states = Collections.unmodifiableSet(states);
		this.rowMapping = new ArrayList<List<S>>();

		final int rows = transitionProbabilities.size();
		final int columns = this.states.size();
		final double[][] matrixValues = new double[rows][columns];

		//this.columnMapping = new ArrayList<S>(this.states);  // <-- didnt get the states in the correct order

        //Generate the column mapping from the first element of each transition probability's entry key (which is a list of states)
        //iterates through column mapping, matching rowheading leading elements
        this.columnMapping = new ArrayList<S>();
        for(final Entry<List<S>, Map<S, Double>> transitionProbability : transitionProbabilities.entrySet())
		{
			final List<S> rowHeader = Collections.unmodifiableList(new ArrayList<S>(transitionProbability.getKey()));
            
            S nextColumn;
            if (rowHeader.isEmpty()) {
                nextColumn = null;
            }
            else {
                nextColumn = rowHeader.get(0);
            }

            if (!columnMapping.contains(nextColumn)) {
                columnMapping.add(nextColumn);
            }
        }


		//iterate through all the new rows
{'fraction_non_alphanumeric': 0.11763038548752834, 'fraction_numerical': 0.006094104308390023, 'mean_word_length': 1.9185277088502894, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 44, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3225873', 'n_tokens_mistral': 1644, 'n_tokens_neox': 1539, 'n_words': 564}