// Path: src/datastructs/DataSequence.java
// public class DataSequence implements Serializable {
// 
// 	private static final long serialVersionUID = 1L;
// 	public List<DataStep> steps = new ArrayList<>();
// 	
// 	public DataSequence() {
// 		
// 	}
// 	
// 	public DataSequence(List<DataStep> steps) {
// 		this.steps = steps;
// 	}
// 	
// 	@Override
// 	public String toString() {
// 		String result = "";
// 		result += "========================================================\n";
// 		for (DataStep step : steps) {
// 			result += step.toString() + "\n";
// 		}
// 		result += "========================================================\n";
// 		return result;
// 	}
// }
// 
// Path: src/datastructs/DataSet.java
// public abstract class DataSet implements Serializable {
// 	public int inputDimension;
// 	public int outputDimension;
// 	public Loss lossTraining;
// 	public Loss lossReporting;
// 	public List<DataSequence> training;
// 	public List<DataSequence> validation;
// 	public List<DataSequence> testing;
// 	public abstract void DisplayReport(Model model, Random rng) throws Exception;
// 	public abstract Nonlinearity getModelOutputUnitToUse();
// }
// 
// Path: src/datastructs/DataStep.java
// public class DataStep implements Serializable {
// 
// 	private static final long serialVersionUID = 1L;
// 	public Matrix input = null;
// 	public Matrix targetOutput = null;
// 	
// 	public DataStep() {
// 		
// 	}
// 	
// 	public DataStep(double[] input, double[] targetOutput) {
// 		this.input = new Matrix(input);
// 		if (targetOutput != null) {
// 			this.targetOutput = new Matrix(targetOutput);
// 		}
// 	}
// 	
// 	@Override
// 	public String toString() {
// 		String result = "";
// 		for (int i = 0; i < input.w.length; i++) {
// 			result += String.format("%.5f", input.w[i]) + "\t";
// 		}
// 		result += "\t->\t";
// 		if (targetOutput != null) {
// 			for (int i = 0; i < targetOutput.w.length; i++) {
// 				result += String.format("%.5f", targetOutput.w[i]) + "\t";
// 			}
// 		}
// 		else {
// 			result += "___\t";
// 		}
// 		return result;
// 	}
// }
// 
// Path: src/loss/LossMultiDimensionalBinary.java
// public class LossMultiDimensionalBinary implements Loss {
// 
// 	/**
// 	 * 
// 	 */
// 	private static final long serialVersionUID = 1L;
// 
// 	@Override
// 	public void backward(Matrix actualOutput, Matrix targetOutput) throws Exception {
// 		throw new Exception("not implemented");
// 	}
// 	
// 	@Override
// 	public double measure(Matrix actualOutput, Matrix targetOutput) throws Exception {
// 		if (actualOutput.w.length != targetOutput.w.length) {
// 			throw new Exception("mismatch");
// 		}
// 		
// 		for (int i = 0; i < targetOutput.w.length; i++) {
// 			if (targetOutput.w[i] >= 0.5 && actualOutput.w[i] < 0.5) {
// 				return 1;
// 			}
// 			if (targetOutput.w[i] < 0.5 && actualOutput.w[i] >= 0.5) {
// 				return 1;
// 			}
// 		}
// 		return 0;
// 	}
// 
// }
// 
// Path: src/loss/LossSumOfSquares.java
// public class LossSumOfSquares implements Loss {
// 
// 	/**
// 	 * 
// 	 */
// 	private static final long serialVersionUID = 1L;
// 
// 	@Override
// 	public void backward(Matrix actualOutput, Matrix targetOutput) throws Exception {
// 		for (int i = 0; i < targetOutput.w.length; i++) {
// 			double errDelta = actualOutput.w[i] - targetOutput.w[i];
// 			actualOutput.dw[i] += errDelta;
// 		}
// 	}
// 	
// 	@Override
// 	public double measure(Matrix actualOutput, Matrix targetOutput) throws Exception {
// 		double sum = 0;
// 		for (int i = 0; i < targetOutput.w.length; i++) {
// 			double errDelta = actualOutput.w[i] - targetOutput.w[i];
// 			sum += 0.5 * errDelta * errDelta;
// 		}
// 		return sum;
// 	}
// }
// 
// Path: src/model/Model.java
// public interface Model extends Serializable {
// 	Matrix forward(Matrix input, Graph g) throws Exception;
// 	void resetState();
// 	List<Matrix> getParameters();
// }
// 
// Path: src/model/SigmoidUnit.java
// public class SigmoidUnit implements Nonlinearity {
// 
// 	private static final long serialVersionUID = 1L;
// 
// 	@Override
// 	public double forward(double x) {
// 		return 1 / (1 + Math.exp(-x));
// 	}
// 
// 	@Override
// 	public double backward(double x) {
// 		double act = forward(x);
// 		return act * (1 - act);
// 	}
// }


import java.util.*;
import datastructs.DataSequence;
import datastructs.DataSet;
import datastructs.DataStep;
import loss.LossMultiDimensionalBinary;
import loss.LossSumOfSquares;
import model.Model;
import model.Nonlinearity;
import model.SigmoidUnit;
package datasets;



public class EmbeddedReberGrammar extends DataSet {
	
	static public class State {
		public State(Transition[] transitions) {
			this.transitions = transitions;
		}
		public Transition[] transitions;
	}
	
	static public class Transition {
		public Transition(int next_state_id, int token) {
			this.next_state_id = next_state_id;
			this.token = token;
		}
		public int next_state_id;
		public int token;
	}
	
	public EmbeddedReberGrammar(Random r) throws Exception {
		int total_sequences = 1000;
		inputDimension = 7;
		outputDimension = 7;
// Path: src/datastructs/DataSequence.java
// public class DataSequence implements Serializable {
// 
// 	private static final long serialVersionUID = 1L;
// 	public List<DataStep> steps = new ArrayList<>();
// 	
// 	public DataSequence() {
// 		
// 	}
// 	
// 	public DataSequence(List<DataStep> steps) {
// 		this.steps = steps;
// 	}
// 	
// 	@Override
// 	public String toString() {
// 		String result = "";
// 		result += "========================================================\n";
// 		for (DataStep step : steps) {
// 			result += step.toString() + "\n";
// 		}
// 		result += "========================================================\n";
// 		return result;
// 	}
// }
// 
// Path: src/datastructs/DataSet.java
// public abstract class DataSet implements Serializable {
// 	public int inputDimension;
// 	public int outputDimension;
// 	public Loss lossTraining;
// 	public Loss lossReporting;
// 	public List<DataSequence> training;
// 	public List<DataSequence> validation;
// 	public List<DataSequence> testing;
// 	public abstract void DisplayReport(Model model, Random rng) throws Exception;
// 	public abstract Nonlinearity getModelOutputUnitToUse();
// }
// 
// Path: src/datastructs/DataStep.java
// public class DataStep implements Serializable {
// 
// 	private static final long serialVersionUID = 1L;
// 	public Matrix input = null;
// 	public Matrix targetOutput = null;
// 	
// 	public DataStep() {
// 		
// 	}
// 	
// 	public DataStep(double[] input, double[] targetOutput) {
// 		this.input = new Matrix(input);
// 		if (targetOutput != null) {
// 			this.targetOutput = new Matrix(targetOutput);
// 		}
// 	}
// 	
// 	@Override
// 	public String toString() {
// 		String result = "";
// 		for (int i = 0; i < input.w.length; i++) {
// 			result += String.format("%.5f", input.w[i]) + "\t";
// 		}
// 		result += "\t->\t";
// 		if (targetOutput != null) {
// 			for (int i = 0; i < targetOutput.w.length; i++) {
// 				result += String.format("%.5f", targetOutput.w[i]) + "\t";
// 			}
// 		}
// 		else {
// 			result += "___\t";
// 		}
// 		return result;
// 	}
// }
// 
// Path: src/loss/LossMultiDimensionalBinary.java
// public class LossMultiDimensionalBinary implements Loss {
// 
// 	/**
// 	 * 
// 	 */
// 	private static final long serialVersionUID = 1L;
// 
// 	@Override
// 	public void backward(Matrix actualOutput, Matrix targetOutput) throws Exception {
// 		throw new Exception("not implemented");
// 	}
// 	
// 	@Override
// 	public double measure(Matrix actualOutput, Matrix targetOutput) throws Exception {
// 		if (actualOutput.w.length != targetOutput.w.length) {
// 			throw new Exception("mismatch");
// 		}
// 		
// 		for (int i = 0; i < targetOutput.w.length; i++) {
// 			if (targetOutput.w[i] >= 0.5 && actualOutput.w[i] < 0.5) {
// 				return 1;
// 			}
// 			if (targetOutput.w[i] < 0.5 && actualOutput.w[i] >= 0.5) {
// 				return 1;
// 			}
// 		}
// 		return 0;
// 	}
// 
// }
// 
// Path: src/loss/LossSumOfSquares.java
// public class LossSumOfSquares implements Loss {
// 
// 	/**
// 	 * 
// 	 */
// 	private static final long serialVersionUID = 1L;
// 
// 	@Override
// 	public void backward(Matrix actualOutput, Matrix targetOutput) throws Exception {
// 		for (int i = 0; i < targetOutput.w.length; i++) {
// 			double errDelta = actualOutput.w[i] - targetOutput.w[i];
// 			actualOutput.dw[i] += errDelta;
// 		}
// 	}
// 	
// 	@Override
// 	public double measure(Matrix actualOutput, Matrix targetOutput) throws Exception {
// 		double sum = 0;
// 		for (int i = 0; i < targetOutput.w.length; i++) {
// 			double errDelta = actualOutput.w[i] - targetOutput.w[i];
// 			sum += 0.5 * errDelta * errDelta;
// 		}
// 		return sum;
// 	}
// }
// 
// Path: src/model/Model.java
// public interface Model extends Serializable {
// 	Matrix forward(Matrix input, Graph g) throws Exception;
// 	void resetState();
// 	List<Matrix> getParameters();
// }
// 
// Path: src/model/SigmoidUnit.java
// public class SigmoidUnit implements Nonlinearity {
// 
// 	private static final long serialVersionUID = 1L;
// 
// 	@Override
// 	public double forward(double x) {
// 		return 1 / (1 + Math.exp(-x));
// 	}
// 
// 	@Override
// 	public double backward(double x) {
// 		double act = forward(x);
// 		return act * (1 - act);
// 	}
// }


// Path: src/datasets/EmbeddedReberGrammar.java
import java.util.*;
import datastructs.DataSequence;
import datastructs.DataSet;
import datastructs.DataStep;
import loss.LossMultiDimensionalBinary;
import loss.LossSumOfSquares;
import model.Model;
import model.Nonlinearity;
import model.SigmoidUnit;

package datasets;



public class EmbeddedReberGrammar extends DataSet {
	
	static public class State {
		public State(Transition[] transitions) {
			this.transitions = transitions;
		}
		public Transition[] transitions;
	}
	
	static public class Transition {
		public Transition(int next_state_id, int token) {
			this.next_state_id = next_state_id;
			this.token = token;
		}
		public int next_state_id;
		public int token;
	}
	
	public EmbeddedReberGrammar(Random r) throws Exception {
		int total_sequences = 1000;
		inputDimension = 7;
		outputDimension = 7;
		lossTraining = new LossSumOfSquares();