using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;
using CategoryTheory;
using BaseTypes.Interfaces;
using SerializationInterface;
using DiagramUI;
using DiagramUI.Interfaces;
using FormulaEditor;
using DataPerformer.Interfaces;
using DataPerformer;
using OrdinaryDifferentialEquations;
using ControlSystemsWrapper;
namespace ControlSystems.Data
{
/// <summary>
/// Rational Transform Control System based on external data
/// </summary>
[Serializable()]
public class RationalTransformControlSystemData : RationalTransformControlSystemFunctionWrapper, IMeasure,
DataPerformer.Interfaces.IDifferentialEquationSolver, IDataConsumer,
IPostSetArrow, IStarted, IDynamical, IAlias, IReplaceMeasurements,
ISetFeedback
{
#region Fields
/// <summary>
/// Change input event
/// </summary>
private event Action onChangeInput = () => { };
string measureString = "";
string aliasString = "";
const Double a = 0;
double[] derivations;
IDifferentialEquationsSystem system;
IMeasurements measurements;
IMeasure[] measures;
IMeasure inp;
bool isUpdated = false;
IAliasName alias = null;
bool isSerialized = true;
Action reset;
List<string> mes = new List<string>();
Action SetFeedback = delegate()
{
};
#endregion
#region Ctor
/// <summary>
/// Default constructor
/// </summary>
public RationalTransformControlSystemData()
{
system = this;
isSerialized = false;
reset = delegate()
{
};
}
/// <summary>
/// Deserialization constructor
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
protected RationalTransformControlSystemData(SerializationInfo info, StreamingContext conext)
: base(info, conext)
{
system = this;
measureString = Serialization.Deserialize<string>("Measure", info);
reset = delegate()
{
};
try
{
aliasString = Serialization.Deserialize<string>("Alias", info);
}
catch (Exception ex)
{
ex.ShowError(10);
}
}
#endregion
#region ISerializable Members
/// <summary>
/// ISerializable interface implementation
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
Serialization.Serialize<string>("Measure", info, measureString);
Serialization.Serialize<string>("Alias", info, aliasString);
}
#endregion
#region IAlias Members
IList<string> IAlias.AliasNames
{
get
{
return new List<string>(variables.Keys);
}
}
object IAlias.this[string name]
{
get
{
return variables[name];
}
set
{
variables[name] = (double)value;
Initialize();
}
}
object IAlias.GetType(string name)
{
return BaseTypes.FixedTypes.Double;
}
#endregion
#region IMeasure Members
Func<object> IMeasure.Parameter
{
get { return GetValue; }
}
string IMeasure.Name
{
get { return "Output"; }
}
object IMeasure.Type
{
get { return a; }
}
#endregion
#region IDifferentialEquationSolver Members
void DataPerformer.Interfaces.IDifferentialEquationSolver.CalculateDerivations()
{
action = (double)inp.Parameter();
system.Calculate(0, derivations);
SetFeedback();
}
void DataPerformer.Interfaces.IDifferentialEquationSolver.CopyVariablesToSolver(int offset, double[] variables)
{
Array.Copy(variables, offset, state, 0, state.Length);
}
int VariablesCount
{
get
{
return state.Length;
}
}
#endregion
#region IMeasurements Members
int IMeasurements.Count
{
get { return measures.Length; }
}
IMeasure IMeasurements.this[int n]
{
get { return measures[n]; }
}
void IMeasurements.UpdateMeasurements()
{
if (isUpdated)
{
return;
}
try
{
UpdateChildrenData();
isUpdated = true;
}
catch (Exception e)
{
e.ShowError(10);
this.Throw(e);
}
}
bool IMeasurements.IsUpdated
{
get
{
return isUpdated;
}
set
{
isUpdated = value;
}
}
#endregion
#region IDataConsumer Members
void IDataConsumer.Add(IMeasurements measurements)
{
if (this.measurements != null)
{
this.Throw(new Exception("Mesurements already exists"));
}
this.measurements = measurements;
}
void IDataConsumer.Remove(IMeasurements measurements)
{
this.measurements = null;
}
public void UpdateChildrenData()
{
try
{
if (measurements != null)
{
measurements.UpdateMeasurements();
}
}
catch (Exception e)
{
e.ShowError(10);
this.Throw(e);
}
}
int IDataConsumer.Count
{
get { return 1; }
}
IMeasurements IDataConsumer.this[int n]
{
get { return measurements; }
}
void IDataConsumer.Reset()
{
this.FullReset();
}
event Action IDataConsumer.OnChangeInput
{
add { onChangeInput += value; }
remove { onChangeInput -= value; }
}
#endregion
#region IStarted Members
void IStarted.Start(double time)
{
for (int i = 0; i < state.Length; i++)
{
state[i] = 0;
}
reset = ResetDistr;
}
#endregion
#region IDynamical Members
double IDynamical.Time
{
set { reset(); }
}
#endregion
#region IReplaceMeasurements Members
void IReplaceMeasurements.Replace(IMeasurements oldMeasurements, IMeasure oldMeasure, IMeasurements newMeasurements, IMeasure newMeasure)
{
string s = this.GetMeasurementName(newMeasurements);
measureString = s + "." + newMeasure.Name;
inp = newMeasure;
}
#endregion
#region ISetFeedback Members
void ISetFeedback.AddFeedback(IMeasure measure, IAlias alias, string name)
{
string an = this.GetRelativeName(alias as IAssociatedObject);
aliasString = an + "." + name;
Alias = aliasString;
}
#endregion
#region IStateDoubleVariables Members
List<string> IStateDoubleVariables.Variables
{
get
{
return mes;
}
}
double[] IStateDoubleVariables.Vector
{
get
{
return state;
}
set
{
state = value;
}
}
void IStateDoubleVariables.Set(double[] input, int offset, int length)
{
Array.Copy(input, offset, state, 0, length);
}
#endregion
#region IPostSetArrow Members
public void PostSetArrow()
{
derivations = new double[state.Length];
Input = measureString;
measures = Measure.CreateMeasures(state, derivations, this, inp, out mes);
Alias = aliasString;
}
#endregion
#region Members
/// <summary>
/// Input measurements
/// </summary>
public ICollection<string> InputMeasurements
{
get
{
return this.GetAllMeasuresType(a);
}
}
/// <summary>
/// Input
/// </summary>
public string Input
{
get
{
return measureString;
}
set
{
if (value.Length == 0)
{
measureString = "";
inp = DataPerformer.StaticExtensionDataPerformerBase.Factory.TimeProvider.TimeMeasure;
return;
}
inp = this.FindMeasure(value, false);
measureString = value;
}
}
/// <summary>
/// Alias
/// </summary>
public string Alias
{
get
{
return aliasString;
}
set
{
alias = this.FindAliasName(value, true);
aliasString = value;
if (alias == null)
{
SetFeedback = delegate()
{
};
}
else
{
SetFeedback = delegate()
{
alias.Value = state[0];
};
}
}
}
/// <summary>
/// Creates system
/// </summary>
/// <param name="formula">Formula</param>
public override void CreateSystem(string formula)
{
base.CreateSystem(formula);
if (isSerialized)
{
isSerialized = false;
return;
}
PostSetArrow();
}
object GetValue()
{
return Output;
}
void ResetDistr()
{
UpdateChildrenData();
foreach (IMeasure m in measures)
{
if (m is IDerivation)
{
IDerivation der = m as IDerivation;
IMeasure md = der.Derivation;
if (md is IDistribution)
{
IDistribution distr = md as IDistribution;
distr.Reset();
}
}
}
reset = delegate()
{
};
}
#endregion
#region Classes & Delegates
class Measure : IMeasure, IDerivation
{
int i;
const Double a = 0;
double[] state;
string name;
IMeasure derivation;
internal static IMeasure[] CreateMeasures(double[] state, double[] der,
RationalTransformControlSystemData transform, IMeasure measure, out List<string> mes)
{
mes = new List<string>();
List<IMeasure> l = new List<IMeasure>();
new Measure(state, der, 0, "x", l, measure, mes);
l.Add(transform);
return l.ToArray();
}
private Measure(double[] state, double[] der, int i, string name, List<IMeasure> l,
IMeasure measure, List<string> mes)
{
this.state = state;
this.name = name;
mes.Add(name);
this.i = i;
l.Add(this);
if (i < state.Length - 1)
{
derivation = new Measure(state, der, i + 1, "D" + name, l, measure, mes);
}
else
{
derivation = LastDer.Create(der, "D" + name, measure);
}
}
private object GetValue()
{
return state[i];
}
#region IMeasure Members
Func<object> IMeasure.Parameter
{
get { return GetValue; }
}
string IMeasure.Name
{
get { return name; }
}
object IMeasure.Type
{
get { return a; }
}
#endregion
#region IDerivation Members
IMeasure IDerivation.Derivation
{
get { return derivation; }
}
#endregion
class LastDer : IMeasure
{
double[] der;
string name;
const Double a = 0;
int n;
protected LastDer(double[] der, string name)
{
this.der = der;
this.name = name;
n = der.Length - 1;
}
#region IMeasure Members
Func<object> IMeasure.Parameter
{
get { return getValue; }
}
string IMeasure.Name
{
get { return name; }
}
object IMeasure.Type
{
get { return a; }
}
#endregion
static internal LastDer Create(double[] der, string name, IMeasure m)
{
if (m is IDistribution)
{
IDistribution d = m as IDistribution;
return new LastDerDistr(der, name, d);
}
return new LastDer(der, name);
}
private object getValue()
{
return der[n];
}
}
class LastDerDistr : LastDer, IDistribution
{
IDistribution distr;
internal LastDerDistr(double[] der, string name, IDistribution d)
: base(der, name)
{
distr = d;
}
#region IDistribution Members
void IDistribution.Reset()
{
distr.Reset();
}
double IDistribution.Integral
{
get { return distr.Integral; }
}
#endregion
}
}
#endregion
}
}