/***************************************************************************************************
*             C# sample for the usage of class TopoART_C (simple classification task)              *
****************************************************************************************************
*                           Created by Marko Tscherepanow, 22 December 2016                        *
***************************************************************************************************/

// Compile and run from the console: dotnet run --project TopoART-C_sample1.csproj

using System;
using LibTopoART;

namespace LibTopoART_samples
{
	/// <summary>
	/// Simple classification sample. [C#]
	/// <para>
	/// This sample demonstrates training and several possibilities for prediction at the example of
	/// a simple classification task.
	/// </para>
	/// </summary>
	class TopoART_C_sample1
	{
		private static void Main()
		{
			// Training data
			decimal[][] trainingSamples = [ [ 0.1m, 0.1m ], [ 0.15m, 0.2m ], [ 0.21m, 0.11m ], [ 0.9m, 0.1m ], [ 0.85m, 0.12m ] ];
			long[] trainingSampleClassIDs = [ 1, 1, 1, 2, 2 ];

			// Test data
			decimal[][] testSamples = [ [ 0.09m, 0.11m ], [ 0.91m, 0.13m ], [ 0.9m, 0.75m ] ];

			// Create TopoART-C network using rho_a = 0.90 and default values for the remaining parameters
			var tac = new TopoART_C(2, 2, 0.9m);

			// Disable topology learning
			tac.SkipEdgeLearning = true;

			// Training
			for(long i = 0; i < trainingSamples.LongLength; ++i)
				tac.Learn(trainingSamples[i], trainingSampleClassIDs[i]);

			// Prediction with nu = 5 (higher values cannot change the results in this sample, independent of rho_a)
			var classID1 = tac.Predict(testSamples[0], 5);	// belongs to class 1
			if(classID1 == 1)
				Console.WriteLine("Correctly classified the first test sample");
			var classID2 = tac.Predict(testSamples[1], 5);	// belongs to class 2
			if(classID2 == 2)
				Console.WriteLine("Correctly classified the second test sample");

			// The third test sample belongs neither to class 1 nor to class 2. However, it is closer to class 2 and
			// differs from it only in the second input dimension. This is confirmed by the following predictions.

			// Extended prediction with nu = 5 and an empty mask vector
			var pred3 = tac.Predict(testSamples[2], null, 5);	
			Console.WriteLine("Predicted class ID {0} for the third test sample (all dimensions), but the confidence of {1} signifies some uncertainty",
				pred3.classID, pred3.confidence);

			// Extended prediction with nu = 5 and a mask vector inhibiting the second input dimension
			bool[] mask = [ false, true ];
			var pred4 = tac.Predict(testSamples[2], mask, 5);
			Console.WriteLine("Predicted class ID {0} for the third test sample (only first dimension) with the confidence of {1} signifying complete certainty",
				pred4.classID, pred4.confidence);
		}
	}
}