Click here to Skip to main content
15,891,423 members
Articles / Multimedia / GDI+

C# Application to Create and Recognize Mouse Gestures (.NET)

Rate me:
Please Sign up or sign in to vote.
4.82/5 (39 votes)
17 Mar 2008CPOL5 min read 221.8K   8.1K   144  
This program can create and recognize mouse gestures.
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Reflection;
using System.Common;

namespace NeuralNetworks
{
	public class Layer
	{
		public event OnOutputsComputed OutputsComputed;
		public event OnIOActivityProgress IOProgress;

		private int m_TotNeurons;
		private int m_NeuronsSynapses;
		private double[] m_Output;
		private IActivationFunction m_Function;
		private Neuron[] m_Neurons;

		public int NeuronsSynapses { get { return m_NeuronsSynapses; } }
		public double[] Output { get { return m_Output; } }
		public IActivationFunction Function { get { return m_Function; } }
		public int Neurons { get { return m_Neurons != null ? m_Neurons.Length : 0; } }
		public Neuron this[int index] { get { return m_Neurons[index]; } }

		public Layer(string full_path)
		{
			try
			{
				XmlTextReader reader = new XmlTextReader(full_path);
				Deserialize(reader);
				reader.Close();
			}
			catch (Exception exc)
			{
				Console.WriteLine("Exception caught while creating neural net layer data.\n\tSource: " + exc.Source + "\n\tMessage: " + exc.Message);
			}
		}

		public Layer(XmlReader reader)
		{
			Deserialize(reader);
		}

		public Layer(int neurons_synapses, int neurons, double[] biases, IActivationFunction function)
		{
			Initialize(neurons_synapses, neurons, biases, function);
		}

		private void Initialize(Neuron[] neurons, IActivationFunction function)
		{
			if (neurons == null)
				throw new ArgumentException("Neurons cannot be null", "neurons");
			else if (function == null)
				throw new ArgumentException("Function cannot be null", "function");

			m_TotNeurons = neurons.Length;
			m_NeuronsSynapses = neurons[0].Synapses;
			m_Function = function;
			m_Neurons = neurons;

			m_Output = new double[neurons.Length];
		}

		private void Initialize(int neurons_synapses, int neurons, double[] biases, IActivationFunction function)
		{
			if (neurons_synapses < 1)
				throw new ArgumentException("Neurons synapses must be a strictly positive value", "neurons_synapses");
			else if (neurons<1)
				throw new ArgumentException("There must be at least 1 neuron", "neurons");
			else if (neurons != biases.Length)
				throw new ArgumentException("Biases must be as much as layer neurons", "biases");
			else if (function == null)
				throw new ArgumentException("Function cannot be null", "function");

			m_TotNeurons = neurons;
			m_NeuronsSynapses = neurons_synapses;
			m_Function = function;
			m_Neurons = new Neuron[neurons];

			for (int i = 0; i < neurons; i++)
				m_Neurons[i] = new Neuron(neurons_synapses, biases[i], function);

			m_Output = new double[neurons];
		}

		public double[] Compute(double[] input)
		{
			for (int i = 0; i < m_Neurons.Length; i++)
				m_Output[i] = m_Neurons[i].Compute(input);

			if (OutputsComputed != null)
				OutputsComputed(input, m_Output);

			return m_Output;
		}

		public override string ToString()
		{
			string s = "{\n";
			if (m_Neurons != null)
			{
				for (int i = 0; i < m_Neurons.Length; i++)
					s += "\tNeuron " + i.ToString() + ": " + m_Neurons[i].ToString() + "\n";
			}
			else
				s += "\tNULL\n";
			s += "} (" + m_Function.ToString() + ")";
			return s;
		}

		public override bool Equals(object obj)
		{
			if (obj == this)
				return true;
			else
			{
				Layer l = obj as Layer;

				if (l == null)
					return false;
				else
				{
					if (l.m_Neurons.Length != m_Neurons.Length)
						return false;
					else
					{
						for (int i = 0; i < m_Neurons.Length; i++)
						{
							if (!m_Neurons[i].Equals(l.m_Neurons[i]))
								return false;
						}
						return true;
					}
				}
			}
		}

		public override int GetHashCode()
		{
			int hash = 0;

			for (int i = 0; i < m_Neurons.Length; i++)
				hash += m_Neurons[i].GetHashCode();

			return hash;
		}

		public void Serialize(XmlWriter writer)
		{
			writer.WriteStartElement("layer");

			writer.WriteStartElement("function");
			writer.WriteAttributeString("type", m_Function.GetType().ToString());
			m_Function.SerializeParameters(writer);
			writer.WriteEndElement();
			
			if (IOProgress != null)
				IOProgress("Layer function saved...");

			writer.WriteStartElement("neurons");
			writer.WriteAttributeString("inputs", m_NeuronsSynapses.ToString());
			writer.WriteAttributeString("count", m_Neurons.Length.ToString());

			for (int i = 0; i < m_Neurons.Length; i++)
			{
				m_Neurons[i].Serialize(writer, false);

				if (IOProgress != null)
					IOProgress("Layer neuron " + (i + 1).ToString() + "/" + m_Neurons.Length.ToString() + " saved...");
			}
			writer.WriteEndElement();

			writer.WriteEndElement();
		}

		public void Deserialize(XmlReader reader)
		{
			try
			{
				//int inputs = 0;
				Neuron[] neurons = null;
				IActivationFunction function = null;

				while (reader.Read())
				{
					switch (reader.NodeType)
					{
						case XmlNodeType.Element:
							{
								if (reader.Name == "function")
								{
									Type f_type = Type.GetType(reader["type"]);
									ConstructorInfo[] constructors = f_type.GetConstructors();
									function = (IActivationFunction)constructors[0].Invoke(null);
									function.DeserializeParameters(reader);

									if (IOProgress != null)
										IOProgress("Layer function loaded...");
								}
								else if (reader.Name == "neurons")
								{
									//inputs = int.Parse(reader["inputs"]);
									neurons = new Neuron[int.Parse(reader["count"])];

									for (int i = 0; i < neurons.Length; i++)
									{
										neurons[i] = new Neuron(reader, function);

										if (IOProgress != null)
											IOProgress("Layer neuron " + i.ToString() + "/" + m_Neurons.Length.ToString() + " loaded...");
									}
								}
								break;
							}
						case XmlNodeType.EndElement:
							{
								if (reader.Name == "layer")
								{
									Initialize(neurons, function);
									return;
								}
								break;
							}
					}
				}
			}
			catch (Exception exc)
			{
				Console.WriteLine("Exception caught while deserializing neural net data.\n\tSource: " + exc.Source + "\n\tMessage: " + exc.Message);
				Initialize(1, 1, new double[1] { 0 }, new ActivationFunctions.LinearFunction());
			}
		}

		public bool Save(string full_path)
		{
			try
			{
				XmlTextWriter writer = new XmlTextWriter(full_path, Encoding.UTF8);
				writer.Formatting = Formatting.Indented;
				writer.WriteStartDocument();
				Serialize(writer);
				writer.WriteEndDocument();
				writer.Close();
				return true;
			}
			catch (Exception exc)
			{
				Console.WriteLine("Exception caught while saving neural net layer data.\n\tSource: " + exc.Source + "\n\tMessage: " + exc.Message);
				return false;
			}
		}

		public bool Load(string full_path)
		{
			try
			{
				XmlTextReader reader = new XmlTextReader(full_path);
				Deserialize(reader);
				reader.Close();
				return true;
			}
			catch (Exception exc)
			{
				Console.WriteLine("Exception caught while loading neural net layer data.\n\tSource: " + exc.Source + "\n\tMessage: " + exc.Message);
				return false;
			}
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Apex s.r.l.
Italy Italy
I got my Computer Science (Engineering) Master's Degree at the Siena University (Italy), but I'm from Rieti (a small town next to Rome).
My hobbies are RPG, MMORGP, programming and 3D graphics.
At the moment I'm employed at Apex s.r.l. (Modena, Italy) as a senior software developer, working for a WPF/WCF project in Rome.

Comments and Discussions