using System;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using CategoryTheory;
using DiagramUI;
using FormulaEditor;
using GeneralLinearMethod;
using AnalyticPolynom;
namespace DataPerformer
{
/// <summary>
/// Formula transformer of mesurements. It is measurements consumer
/// </summary>
[Serializable()]
public class FormulaDataConsumer : DataConsumer, IMeasurements, ISerializable,
IPostSetArrow, IAlias
{
/// <summary>
/// Output measurement
/// </summary>
private IMeasure measure;
/// <summary>
/// Output value
/// </summary>
private double result;
/// <summary>
/// String representation of formula
/// </summary>
private string formulaString = "";
/// <summary>
/// The object's formula
/// </summary>
private MathFormula formula;
/// <summary>
/// Tree of the formula
/// </summary>
private ObjectFormulaTree tree;
/// <summary>
/// The formula argument
/// </summary>
private ElementaryObjectArgument arg;
/// <summary>
/// Input parameter
/// </summary>
private DynamicalParameter par;
/// <summary>
/// The formula arguments
/// </summary>
private ArrayList arguments;
/// <summary>
/// Derivation of output parameter
/// </summary>
private double derivation;
/// <summary>
/// Partial derivations
/// </summary>
private Hashtable derivations = new Hashtable();
/// <summary>
/// Table of parameters
/// </summary>
private Hashtable parameters = new Hashtable();
/// <summary>
/// Constructor
/// </summary>
public FormulaDataConsumer() : base(11)
{
init();
arguments = new ArrayList();
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
public FormulaDataConsumer(SerializationInfo info, StreamingContext context) :
base(11)
{
formulaString = (string)info.GetValue("Formula", typeof(string));
if (formulaString.Length > 0)
{
Formula = formulaString;
}
arguments = (ArrayList)info.GetValue("Arguments", typeof(ArrayList));
parameters = (Hashtable)info.GetValue("Parameters", typeof(Hashtable));
init();
}
/// <summary>
/// ISerializable interface implementation
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
new public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Formula", formulaString);
info.AddValue("Arguments", arguments);
info.AddValue("Parameters", parameters);
}
/// <summary>
/// Creates correspond xml
/// </summary>
/// <param name="doc">document to create element</param>
/// <returns>The created element</returns>
/*new public XmlElement CreateXml(XmlDocument doc)
{
XmlElement el = doc.CreateElement("FormulaDataConsumer");
XmlAttribute attr = doc.CreateAttribute("Formula");
attr.Value = Formula;
el.Attributes.Append(attr);
foreach (string s in arguments)
{
XmlElement ea = doc.CreateElement("FormulaArgument");
XmlAttribute attrArg = doc.CreateAttribute("Argument");
attrArg.Value = s;
ea.Attributes.Append(attrArg);
el.AppendChild(ea);
}
return el;
}*/
/// <summary>
/// The count of measurements
/// </summary>
int IMeasurements.Count
{
get
{
return 1;
}
}
/// <summary>
/// Access to n - th measurement
/// </summary>
IMeasure IMeasurements.this[int n]
{
get
{
return measure;
}
}
/// <summary>
/// Updates measurements data
/// </summary>
public void UpdateMeasurements()
{
if (IsUpdated)
{
return;
}
try
{
if (par == null)
{
throw new Exception(DynamicalParameter.UndefinedParameters);
}
UpdateChildrenData();
par.Set(arg);
result = (double)tree.Result;
derivation = 0;
string str = arg.Variables;
foreach (char c in str)
{
string s = c + "";
if (parameters.ContainsKey(s))
{
continue;
}
IMeasure m = par[c];
if (!(m is IDerivation))
{
derivation = 0;
break;
}
IDerivation p = m as IDerivation;
ObjectFormulaTree t = derivations[c] as ObjectFormulaTree;
derivation += (double)t.Result * p.Derivation;
}
isUpdated = true;
}
catch (Exception e)
{
PureDesktop.ThrowException(this, e);
}
}
/// <summary>
/// The header control of measurements
/// </summary>
/*public Control HeaderControl
{
get
{
return new FormulaControl(this);
}
}*/
/// <summary>
/// Accepts parameters
/// </summary>
/// <param name="s">String of parameters</param>
public void AcceptParameters(string s)
{
parameters.Clear();
par = null;
arg = new ElementaryObjectArgument();
arg.Add(tree);
string str = arg.Variables;
foreach (char c in s)
{
if (str.IndexOf(c) < 0)
{
throw new Exception("Illegal formula parameter");
}
}
foreach (char c in s)
{
double a = 0;
parameters["" + c] = a;
arg[c] = a;
}
}
/// <summary>
/// The operation that performs after arrows setting
/// </summary>
public void PostSetArrow()
{
if (tree == null)
{
return;
}
DynamicalParameter parameter = new DynamicalParameter();
foreach (IMeasurements measurements in measurementsData)
{
/*IAssociatedObject cont = measurements as IAssociatedObject;
INamedComponent comp = cont.Object as INamedComponent;*/
string name = DataConsumer.GetName(this, measurements);//comp.Name;
for (int i = 0; i < measurements.Count; i++)
{
IMeasure measure = measurements[i];
string p = name + "." + measure.Name;
foreach (string s in arguments)
{
if (s.Substring(4).Equals(p))
{
char c = s[0];
parameter.Add(c, measure);
}
}
}
}
foreach (string s in arguments)
{
if (s.Substring(4).Equals("Time"))
{
parameter.Add(s[0], DataConsumer.TimeMeasure);
}
}
Parameter = parameter;
foreach (string s in AliasNames)
{
arg[s[0]] = this[s];
}
}
/// <summary>
/// The name of measurements source
/// </summary>
public string SourceName
{
get
{
INamedComponent comp = obj as INamedComponent;
return comp.Name;
}
}
/// <summary>
/// String representation of formula
/// </summary>
public string Formula
{
get
{
return formulaString;
}
set
{
formula = MathFormula.FromString(MathSymbolFactory.Sizes, value);
formulaString = value;
MathFormula f = formula.FullTransform;
tree = new ObjectFormulaTree(f, ElementaryFunctionsCreator.Object);
arg = new ElementaryObjectArgument();
arg.Add(tree);
string var = arg.Variables;
derivations.Clear();
parameters.Clear();
foreach (char c in var)
{
ObjectFormulaTree t = DerivationPerformer.Derivation(tree, c + "");
arg.Add(t);
t = ElementarySimplifier.Simplify(t);
derivations[c] = t;
}
}
}
/// <summary>
/// The formula arguments
/// </summary>
public ArrayList Arguments
{
get
{
return arguments;
}
set
{
string str = Variables;
bool b = false;
foreach (char c in str)
{
foreach (string s in value)
{
if (s[0] == c)
{
goto m;
}
}
throw new Exception(VariablesShortage);
m:
b = b;
}
arguments = value;
}
}
/// <summary>
/// Input dynamical parameter
/// </summary>
public DynamicalParameter Parameter
{
set
{
arg = new ElementaryObjectArgument();
arg.Add(tree);
par = value;
}
}
/// <summary>
/// Formula variables
/// </summary>
public string Variables
{
get
{
string s = "";
ElementaryObjectArgument arg = new ElementaryObjectArgument();
string str = arg.Variables;
foreach (char c in str)
{
if (!parameters.ContainsKey("" + c))
{
s += c;
}
}
return s;
}
}
/// <summary>
/// Names of aliases
/// </summary>
public List<string> AliasNames
{
get
{
List<string> s = new List<string>();
foreach (string str in parameters.Keys)
{
s.Add(str);
}
return s;
}
}
/// <summary>
/// Access to alias object
/// </summary>
public object this[string alias]
{
get
{
return parameters[alias];
}
set
{
char c = alias[0];
double a = (double)value;
arg[c] = a;
parameters[alias] = a;
}
}
/// <summary>
/// Gets alias type
/// </summary>
/// <param name="n"></param>
/// <returns></returns>
public object GetType(int n)
{
Double a = 0;
return a;
}
/// <summary>
/// Calculates formula result
/// </summary>
/// <returns>The formula result</returns>
private object calculate()
{
return result;
}
/// <summary>
/// Calculates derivation
/// </summary>
/// <returns>The derivation</returns>
private object getDerivation()
{
return derivation;
}
/// <summary>
/// Initialization
/// </summary>
private void init()
{
measure = new MeasureDerivation(tree.ReturnType, new MeasureParameter(calculate), new MeasureParameter(getDerivation), "result");
}
}
/// <summary>
/// Solver of ordinary differential equations systev
/// </summary>
[Serializable()]
public class DifferentialEquationSolver : DataConsumer, IDifferentialEquationSolver, ISerializable,
IPostSetArrow, IStarted, IAlias, ICheckCorrectness
{
#region Fields
/// <summary>
/// arguments of right parts
/// </summary>
private ElementaryObjectArgument arg;
/// <summary>
/// Input dynamical parameter
/// </summary>
private DynamicalParameter par;
/// <summary>
/// Table of variables of equations. Table contains initial values and derivations of variables
/// </summary>
private Hashtable variables = new Hashtable();
/// <summary>
/// Table representation of input parameters
/// </summary>
private Hashtable parameters = new Hashtable();
/// <summary>
/// Output parameters
/// </summary>
private ArrayList output;
/// <summary>
/// The time
/// </summary>
private double time;
/// <summary>
/// Current time
/// </summary>
private double timeOld;
/// <summary>
/// List of right parts arguments
/// </summary>
private ArrayList arguments = new ArrayList();
/// <summary>
/// Table representation of variables
/// </summary>
private Hashtable vars = new Hashtable();
/// <summary>
/// Table representation of parameters
/// </summary>
private Hashtable pars = new Hashtable();
/// <summary>
/// Table of aliases
/// </summary>
private Hashtable aliases = new Hashtable();
/// <summary>
/// Table of aliases names
/// </summary>
private Hashtable aliasNames = new Hashtable();
/// <summary>
/// Table of external aliases
/// </summary>
private Hashtable externalAliases = new Hashtable();
/// <summary>
/// The "is serialized" flag
/// </summary>
private bool isSerialized = false;
#endregion
#region Constructors
/// <summary>
/// Consructor
/// </summary>
public DifferentialEquationSolver() : base(30)
{
init();
vars = new Hashtable();
pars = new Hashtable();
aliases = new Hashtable();
arguments = new ArrayList();
}
/// <summary>
/// Consructor
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
public DifferentialEquationSolver(SerializationInfo info, StreamingContext context) :
base(30)
{
init();
try
{
isSerialized = true;
vars = (Hashtable)info.GetValue("Vars", typeof(Hashtable));
pars = (Hashtable)info.GetValue("Pars", typeof(Hashtable));
aliases = (Hashtable)info.GetValue("Aliases", typeof(Hashtable));
arguments = (ArrayList)info.GetValue("Arguments", typeof(ArrayList));
aliasNames = (Hashtable)info.GetValue("AliasNames", typeof(Hashtable));
comments = (ArrayList)info.GetValue("Comments", typeof(ArrayList));
}
catch (Exception)
{
}
}
#endregion
/// <summary>
/// ISerializable interface implementation
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
new public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Vars", vars);
info.AddValue("Pars", pars);
info.AddValue("Aliases", aliases);
info.AddValue("Arguments", arguments);
info.AddValue("AliasNames", aliasNames);
info.AddValue("Comments", comments);
}
/// <summary>
/// Creates correspond xml
/// </summary>
/// <param name="doc">document to create element</param>
/// <returns>The created element</returns>
/* new public XmlElement CreateXml(XmlDocument doc)
{
XmlElement el = doc.CreateElement("DifferentialEquationSolver");
return el;
}*/
/// <summary>
/// Keys of variables
/// </summary>
public ICollection Keys
{
get
{
return variables.Keys;
}
}
/// <summary>
/// Access to variable
/// </summary>
public string this[char c]
{
get
{
object[] o = variables[c] as object[];
return o[0] as string;
}
}
/// <summary>
/// Sets values of variables
/// </summary>
/// <param name="b">Begin index</param>
/// <param name="x">Array of variables</param>
public void SetVariables(int b, double[] x)
{
int i = b;
foreach (object[] o in variables.Values)
{
o[3] = x[i];
++i;
}
}
/// <summary>
/// Comments
/// </summary>
public ArrayList Comments
{
get
{
return comments;
}
set
{
comments = value;
}
}
/// <summary>
/// The count of measurements
/// </summary>
int IMeasurements.Count
{
get
{
if (output == null)
{
return 0;
}
return output.Count;
}
}
/// <summary>
/// Access to n - th measurement
/// </summary>
IMeasure IMeasurements.this[int n]
{
get
{
return output[n] as IMeasure;
}
}
/// <summary>
/// Updates measurements data
/// </summary>
public void UpdateMeasurements()
{
if (IsUpdated)
{
return;
}
try
{
UpdateChildrenData();
isUpdated = true;
}
catch (Exception e)
{
PureDesktop.ThrowException(this, e);
}
}
/// <summary>
/// The time
/// </summary>
new public double Time
{
set
{
time = value;
}
}
/// <summary>
/// The operation that performs after arrows setting
/// </summary>
public void PostSetArrow()
{
postDeserialize();
postSetAlias();
}
/// <summary>
/// Checks its correctenss
/// </summary>
public void CheckCorrectness()
{
try
{
//PostSetArrow();
}
catch (Exception e)
{
PureDesktop.ThrowException(this, e);
}
}
/// <summary>
/// Accepts measurements
/// </summary>
private void acceptMeasurements()
{
DynamicalParameter parameter = new DynamicalParameter();
parameters.Clear();
foreach (IMeasurements measurements in measurementsData)
{
/*IAssociatedObject cont = measurements as IAssociatedObject;
INamedComponent nc = cont.Object as INamedComponent;*/
string name = DataConsumer.GetName(this, measurements);//nc.Name;
for (int i = 0; i < measurements.Count; i++)
{
IMeasure measure = measurements[i];
string p = name + "." + measure.Name;
foreach (char c in pars.Keys)
{
if (!pars.ContainsKey(c))
{
continue;
}
if (pars[c] == null)
{
continue;
}
string s = pars[c] as string;
if (s.Equals(p))
{
parameter.Add(c, measure);
parameters[c] = measure;
}
}
}
}
foreach (string s in arguments)
{
if (s.Substring(s.Length - 4).Equals("Time"))
{
parameter.Add(s[0], DataConsumer.TimeMeasure);
parameters[s[0]] = DataConsumer.TimeMeasure;
}
}
foreach (char c in pars.Keys)
{
if (!parameters.ContainsKey(c))
{
if (pars[c] != null)
{
PureDesktop.ThrowException(this, new Exception(PureDesktop.GetResourceString(VectorFormulaConsumer.ExternalParameter_) +
c + PureDesktop.GetResourceString(VectorFormulaConsumer._IsNotDefined)));
}
}
}
Parameter = parameter;
}
/// <summary>
/// The name of measurements source
/// </summary>
public string SourceName
{
get
{
INamedComponent comp = obj as INamedComponent;
return comp.Name;
}
}
/// <summary>
/// Arguments of equations
/// </summary>
public ArrayList Arguments
{
get
{
return arguments;
}
set
{
bool b = false;
string str = InputParameters;
string sc = ConstantNames;
foreach (char c in str)
{
if (aliases.ContainsKey(c + ""))
{
continue;
}
foreach (string s in value)
{
if (s[0] == c)
{
goto m;
}
}
throw new Exception(DataConsumer.VariablesShortage);
m:
b = !b;
}
arguments = value;
pars.Clear();
foreach (string s in arguments)
{
pars[s[0]] = s.Substring(4);
}
}
}
/// <summary>
/// Input dynamical parameter
/// </summary>
public DynamicalParameter Parameter
{
set
{
par = value;
}
}
/// <summary>
/// Starts this object
/// </summary>
new public void Start()
{
try
{
timeOld = time;
foreach (object[] o in variables.Values)
{
o[3] = o[4];
}
//calculateDerivations();
}
catch (Exception e)
{
PureDesktop.ThrowException(this, e);
}
}
/// <summary>
/// Calculates initial value of variable
/// </summary>
/// <param name="c">The variable key</param>
/// <returns>Initial value of variable</returns>
public double GetInitialValue(char c)
{
object[] o = variables[c] as object[];
return (double)o[4];
}
/// <summary>
/// Adds variable
/// </summary>
/// <param name="c">The variable key</param>
public void AddVariable(char c)
{
double a = 0;
variables[c] = new object[]{"", null, null, a, a, a};
vars[c] = new object[]{"", a};
}
/// <summary>
/// Sets right part formula to variable
/// </summary>
/// <param name="c">The variable key</param>
/// <param name="formula">The string representation of formula</param>
public void SetVariable(char c, string formula)
{
object[] o = variables[c] as object[];
o[0] = formula;
object[] ob = vars[c] as object[];
ob[0] = formula;
}
/// <summary>
/// Sets initial value of variable
/// </summary>
/// <param name="c">The variable key</param>
/// <param name="a">Initial value of variable</param>
public void SetValue(char c, double a)
{
object[] o = variables[c] as object[];
o[4] = a;
object[] ob = vars[c] as object[];
ob[1] = a;
}
/// <summary>
/// All variabeles in formulas
/// </summary>
public string AllVariables
{
get
{
string s = "";
foreach (object[] o in variables.Values)
{
string st = o[0] as string;
MathFormula f = MathFormula.FromString(MathSymbolFactory.Sizes, st);
string str = ElementaryObjectDetector.GetVariables(f);
foreach (char c in str)
{
if (s.IndexOf(c) < 0)
{
s += c;
}
}
}
return s;
}
}
/// <summary>
/// Preparation
/// </summary>
public void Prepare()
{
//parameters.Clear();
output = new ArrayList();
string str = "";
aliases.Clear();
Double a = 0;
string var = AllVariables;
Hashtable table = new Hashtable();
foreach (char c in var)
{
table[c] = a;
}
foreach (char c in pars.Keys)
{
IMeasure m = parameters[c] as IMeasure;
table[c] = m.Type;
}
IFormulaObjectCreator creator = new FormulaArrayObjectCreator(
new ElementaryObjectsCreator(table));
foreach (object[] o in variables.Values)
{
string st = o[0] as string;
MathFormula f = MathFormula.FromString(MathSymbolFactory.Sizes, st);
o[1] = f;
ObjectFormulaTree t = new ObjectFormulaTree(f.FullTransform, creator);
o[2] = t;
string s = ElementaryObjectDetector.GetVariables(f);
foreach (char c in s)
{
if (str.IndexOf(c) < 0)
{
if (!aliases.ContainsKey("" + c))
{
str += c;
if (variables.ContainsKey(c))
{
parameters.Remove(c);
pars.Remove(c);
}
}
}
}
}
foreach (char c in variables.Keys)
{
Variable v = new Variable(this, c);
IMeasure m = new MeasureDerivation(a, new MeasureParameter(v.calculate),
new MeasureParameter(v.derivation), c + "");
output.Add(m);
if (str.IndexOf(c) < 0)
{
str += c;
}
}
foreach (string s in aliases.Keys)
{
str += s;
}
arg = new ElementaryObjectArgument();
foreach (object[] o in variables.Values)
{
ObjectFormulaTree tree = o[2] as ObjectFormulaTree;
arg.Add(tree);
}
foreach (string s in aliases.Keys)
{
arg[s[0]] = aliases[s];
}
}
/// <summary>
/// Clears parameters
/// </summary>
public void ClearParameters()
{
parameters.Clear();
pars.Clear();
}
/// <summary>
/// String of parameters
/// </summary>
public string Parameters
{
get
{
string s = "";
foreach (char c in parameters.Keys)
{
s += c;
}
return s;
}
}
/// <summary>
/// String of input parameters
/// </summary>
public string InputParameters
{
get
{
string s = "";
string all = AllVariables;
foreach (char c in all)
{
if (aliases.ContainsKey("" + c) | variables.ContainsKey(c))
{
continue;
}
s += c;
}
return s;
}
}
/// <summary>
/// String of input parameters
/// </summary>
public string AllParameters
{
get
{
string s = "";
string all = AllVariables;
foreach (char c in all)
{
if (variables.ContainsKey(c))
{
continue;
}
s += c;
}
return s;
}
}
/// <summary>
/// Clears aliases
/// </summary>
public void ResetAliases()
{
aliases.Clear();
foreach (char c in vars.Keys)
{
AddAlias("" + c);
}
}
/// <summary>
/// Adds alias
/// </summary>
/// <param name="alias">The alias to add</param>
public void AddAlias(string alias)
{
double a = 0;
aliases[alias] = a;
}
/// <summary>
/// Sets input parameter
/// </summary>
/// <param name="c">The parameter key</param>
/// <param name="m">The parameter measurement</param>
public void SetParameter(char c, IMeasure m)
{
parameters[c] = m;
pars[c] = m.Name;
}
/// <summary>
/// String of constants names
/// </summary>
public string ConstantNames
{
get
{
string str = "";
List<string> l = AliasNames;
foreach (string s in l)
{
if (!vars.ContainsKey(s[0]))
{
str += s;
}
}
return str;
}
}
/// <summary>
/// Names of aliases
/// </summary>
public List<string> AliasNames
{
get
{
List<string> s = new List<string>();
foreach (string str in aliases.Keys)
{
s.Add(str);
}
return s;
}
}
/// <summary>
/// Access to alias object
/// </summary>
public object this[string alias]
{
get
{
return aliases[alias];
}
set
{
char c = alias[0];
double a = (double)value;
arg[c] = a;
aliases[alias] = a;
if (variables.ContainsKey(c))
{
SetValue(c, a);
}
}
}
public object GetType(int n)
{
Double a = 0;
return a;
}
/// <summary>
/// Clears set of variables
/// </summary>
public void ClearVariables()
{
variables.Clear();
vars.Clear();
}
/// <summary>
/// Gets derivaton of variable
/// </summary>
/// <param name="c">The variable key</param>
/// <returns>The derivation</returns>
double getDerivation(char c)
{
object[] o = variables[c] as object[];
return (double)o[5];
}
/// <summary>
/// Performs operations after deserialization
/// </summary>
private void postDeserialize()
{
output = new ArrayList();
foreach (char c in vars.Keys)
{
object[] o = vars[c] as object[];
double d = 0;
variables[c] = new object[]{o[0], null, null, o[1], o[1], d};
}
string str = "";
foreach (object[] o in variables.Values)
{
string st = o[0] as string;
MathFormula f = MathFormula.FromString(MathSymbolFactory.Sizes, st);
o[1] = f;
string s = ElementaryObjectDetector.GetVariables(f);
}
Double a = 0;
foreach (char c in variables.Keys)
{
Variable v = new Variable(this, c);
IMeasure m = new MeasureDerivation(a, new MeasureParameter(v.calculate),
new MeasureParameter(v.derivation), c + "");
output.Add(m);
if (str.IndexOf(c) < 0)
{
str += c;
}
}
foreach (string s in aliases.Keys)
{
str += s;
}
if (!isSerialized)
{
pars.Clear();
isSerialized = false;
foreach (string ps in arguments)
{
pars[ps[0]] = ps.Substring(4);
}
}
acceptMeasurements();
Hashtable table = new Hashtable();
foreach (char c in str)
{
table[c] = a;
}
foreach (char c in pars.Keys)
{
if (pars.ContainsKey(c))
{
if (pars[c] != null)
{
IMeasure m = parameters[c] as IMeasure;
table[c] = m.Type;
}
}
}
IFormulaObjectCreator creator = new FormulaArrayObjectCreator(
new ElementaryObjectsCreator(table));
foreach (object[] o in variables.Values)
{
string st = o[0] as string;
MathFormula f = MathFormula.FromString(MathSymbolFactory.Sizes, st);
o[1] = f;
ObjectFormulaTree t = new ObjectFormulaTree(f.FullTransform, creator);
o[2] = t;
}
arg = new ElementaryObjectArgument();
foreach (object[] o in variables.Values)
{
ObjectFormulaTree tree = o[2] as ObjectFormulaTree;
arg.Add(tree);
}
foreach (string s in aliases.Keys)
{
arg[s[0]] = (double)aliases[s];
}
}
/// <summary>
/// Initialization
/// </summary>
private void init()
{
}
/// <summary>
/// Gets value of variable
/// </summary>
/// <param name="c">The variable keu</param>
/// <returns>The value of variable</returns>
private double getValue(char c)
{
object[] o = variables[c] as object[];
return (double)o[3];
}
/// <summary>
/// Calculates derivations
/// </summary>
public void CalculateDerivations()
{
try
{
foreach (char c in externalAliases.Keys)
{
object[] o = externalAliases[c] as object[];
IAlias al = o[0] as IAlias;
string s = o[1] as string;
object[] ob = variables[c] as object[];
al[s] = ob[3];
}
UpdateChildrenData();
foreach (char c in parameters.Keys)
{
IMeasure m = parameters[c] as IMeasure;
if (m == null)
{
throw new Exception(DynamicalParameter.UndefinedParameters);
}
arg[c] = m.Parameter();
}
foreach (char c in variables.Keys)
{
object[] o = variables[c] as object[];
arg[c] = o[3];
}
foreach (char c in variables.Keys)
{
object[] o = variables[c] as object[];
ObjectFormulaTree t = o[2] as ObjectFormulaTree;
o[5] = t.Result;
}
}
catch (Exception e)
{
PureDesktop.ThrowException(this, e);
}
}
public Hashtable ExternalAliases
{
get
{
return aliasNames;
}
set
{
aliasNames = value;
postSetAlias();
}
}
public override List<string> AllAliases
{
get
{
List<string> a = new List<string>();
DataConsumer.GetAliases(this, a);
return a;
}
}
private void postSetAlias()
{
externalAliases.Clear();
if (aliasNames == null)
{
return;
}
foreach (char c in aliasNames.Keys)
{
string s = aliasNames[c] as string;
externalAliases[c] = DataConsumer.FindAlias(this, s);
}
}
/// <summary>
/// Auxiliary class for providing output measurements of differential equations solver
/// </summary>
public class Variable
{
/// <summary>
/// The solver
/// </summary>
DifferentialEquationSolver solver;
/// <summary>
/// Index of the variable
/// </summary>
char indx;
/// <summary>
/// Constructor
/// </summary>
/// <param name="solver">The solver</param>
/// <param name="indx">Index of the variable</param>
public Variable(DifferentialEquationSolver solver, char indx)
{
this.solver = solver;
this.indx = indx;
}
/// <summary>
/// Calculates value of measurement
/// </summary>
/// <returns>Value of measurement</returns>
public object calculate()
{
return solver.getValue(indx);
}
/// <summary>
/// Calculates time derivation of measurement
/// </summary>
/// <returns>Time derivation</returns>
public object derivation()
{
return solver.getDerivation(indx);
}
}
}
/// <summary>
/// The state machine
/// </summary>
[Serializable()]
public class StateMachine : DataConsumer, ISerializable,
IPostSetArrow, IStarted, IMeasurements
{
/// <summary>
/// Table of input parameters
/// </summary>
private Hashtable parameters = new Hashtable();
/// <summary>
/// Parameters
/// </summary>
private Hashtable pars;
/// <summary>
/// State transition table
/// </summary>
private int[,] table;
/// <summary>
/// Current state
/// </summary>
private int state;
/// <summary>
/// Initial state
/// </summary>
private int initialState;
/// <summary>
/// Table of parameters
/// </summary>
private Hashtable doubleParameters = new Hashtable();
/// <summary>
/// Output measurement
/// </summary>
private IMeasure measure;
/// <summary>
/// Constructor
/// </summary>
public StateMachine() : base(33)
{
pars = new Hashtable();
init();
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
public StateMachine(SerializationInfo info, StreamingContext context) :
base(33)
{
table = (int[,])info.GetValue("Table", typeof(int[,]));
pars = (Hashtable)info.GetValue("Parameters", typeof(Hashtable));
initialState = (int)info.GetValue("Initial", typeof(int));
init();
}
/// <summary>
/// ISerializable interface implementation
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
new public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Table", table);
info.AddValue("Parameters", pars);
info.AddValue("Initial", initialState);
}
/// <summary>
/// Access to table
/// </summary>
public int this[int i, int j]
{
get
{
return table[i, j];
}
}
/// <summary>
/// The state
/// </summary>
public int State
{
get
{
return state;
}
set
{
state = value;
}
}
/// <summary>
/// The initial state
/// </summary>
public int InitialState
{
set
{
initialState = value;
}
get
{
return initialState;
}
}
/// <summary>
/// Gets state table dimension
/// </summary>
/// <param name="i">Numer of dimension</param>
/// <returns></returns>
public int GetLength(int i)
{
if (table == null)
{
return 0;
}
return table.GetLength(i);
}
/// <summary>
/// The machine state transition table
/// </summary>
public int[,] Table
{
set
{
for (int i = 0; i < value.GetLength(0); i++)
{
for (int j = 0; j < value.GetLength(1); j++)
{
if (value[i, j] >= value.GetLength(0))
{
throw new Exception("State machine out of range");
}
}
}
doubleParameters.Clear();
parameters.Clear();
pars.Clear();
table = value;
}
}
/// <summary>
/// The n th measurement
/// </summary>
new public IMeasure this[int n]
{
get
{
return parameters[n] as IMeasure;
}
}
/// <summary>
/// The count of measurements
/// </summary>
int IMeasurements.Count
{
get
{
return 1;
}
}
/// <summary>
/// Access to n - th measurement
/// </summary>
IMeasure IMeasurements.this[int n]
{
get
{
return measure;
}
}
/// <summary>
/// The keys of input parameters
/// </summary>
public ICollection Keys
{
get
{
return parameters.Keys;
}
}
/// <summary>
/// Creates correspond xml
/// </summary>
/// <param name="doc">document to create element</param>
/// <returns>The created element</returns>
/*new public XmlElement CreateXml(XmlDocument doc)
{
XmlElement el = doc.CreateElement("DifferentialEquationSolver");
return el;
}*/
/// <summary>
/// Updates measurements data
/// </summary>
public void UpdateMeasurements()
{
if (IsUpdated)
{
return;
}
try
{
UpdateChildrenData();
foreach (int i in Keys)
{
double x = (double)doubleParameters[i];
IMeasure m = this[i];
double y = (double)m.Parameter();
if ((y > 0) & (x <= 0))
{
state = table[state, i];
}
doubleParameters[i] = y;
}
isUpdated = true;
}
catch (Exception e)
{
PureDesktop.ThrowException(this, e);
}
}
/// <summary>
/// The operation that performs after arrows setting
/// </summary>
public void PostSetArrow()
{
postDeserialize();
parameters.Clear();
foreach (IMeasurements measurements in measurementsData)
{
/*IAssociatedObject cont = measurements as IAssociatedObject;
INamedComponent c = cont.Object as INamedComponent;*/
string name = DataConsumer.GetName(this, measurements);//c.Name;
for (int i = 0; i < measurements.Count; i++)
{
IMeasure measure = measurements[i];
string p = name + "." + measure.Name;
foreach (int j in pars.Keys)
{
string s = pars[j] as string;
if (s.Equals(p))
{
parameters[j] = measure;
}
}
}
}
}
/// <summary>
/// The name of measurements source
/// </summary>
public string SourceName
{
get
{
INamedComponent comp = obj as INamedComponent;
return comp.Name;
}
}
/// <summary>
/// Starts this object
/// </summary>
new public void Start()
{
try
{
foreach (int i in Keys)
{
double a = -1;
doubleParameters[i] = a;
}
state = initialState;
}
catch (Exception e)
{
PureDesktop.ThrowException(this, e);
}
}
/// <summary>
/// Sets i - th input parameter
/// </summary>
/// <param name="i">The parameter number</param>
/// <param name="name">The parameter name</param>
/// <param name="m">The input measurement</param>
public void SetParameter(int i, string name, IMeasure m)
{
parameters[i] = m;
pars[i] = name + "." + m.Name;
}
/// <summary>
/// Clears parameters
/// </summary>
public void ClearParameters()
{
parameters.Clear();
pars.Clear();
doubleParameters.Clear();
}
/// <summary>
/// Gets name of i - th parameter
/// </summary>
/// <param name="i">The parameter number</param>
/// <returns>The name of i - th parameter</returns>
public string GetParameter(int i)
{
return pars[i] as string;
}
/// <summary>
/// Operation after deserialization
/// </summary>
private void postDeserialize()
{
doubleParameters.Clear();
parameters.Clear();
}
/// <summary>
/// Gets state
/// </summary>
/// <returns></returns>
private object getState()
{
return state;
}
/// <summary>
/// Initialization
/// </summary>
private void init()
{
Int32 a = 0;
measure = new Measure(a, new MeasureParameter(getState), "State");
}
}
[Serializable()]
public class Nulling : ICategoryObject, IMeasurements, ISerializable,
IStarted
{
private double zero = 0;
private double x;
private double der;
private bool switched = false;
private IMeasure measure;
private FormulaDataConsumer consumer;
private StateMachine machine;
private int state = 0;
//private NamedComponent component;
protected object obj;
/// <summary>
/// Update flag
/// </summary>
private bool isUpdated;
public Nulling()
{
init();
}
public Nulling(SerializationInfo info, StreamingContext context)
{
state = (int)info.GetValue("State", typeof(int));
init();
}
/// <summary>
/// ISerializable interface implementation
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("State", state);
}
/// <summary>
/// Creates correspond xml
/// </summary>
/// <param name="doc">document to create element</param>
/// <returns>The created element</returns>
/*public XmlElement CreateXml(XmlDocument doc)
{
XmlElement el = doc.CreateElement("Nulling");
return el;
}*/
/// <summary>
/// Associated object
/// </summary>
public object Object
{
get
{
return obj;
}
set
{
obj = value;
}
}
/// <summary>
/// Starts this object
/// </summary>
public void Start()
{
try
{
zero = 0;
switched = false;
if (consumer == null)
{
throw new Exception("Nulling has no consumer");
}
if (machine == null)
{
throw new Exception("Nulling has no machine");
}
}
catch (Exception e)
{
PureDesktop.ThrowException(this, e);
}
}
public int State
{
set
{
state = value;
}
get
{
return state;
}
}
/// <summary>
/// Updates measurements data
/// </summary>
public void UpdateMeasurements()
{
if (IsUpdated)
{
return;
}
try
{
consumer.UpdateMeasurements();
IMeasurements m = consumer;
IMeasure measure = m[0];
x = (double)measure.Parameter();
der = 0;
if (measure is IDerivation)
{
IDerivation d = measure as IDerivation;
der = d.Derivation;
}
machine.UpdateMeasurements();
int s = machine.State;
if (switched)
{
if (s != state)
{
switched = false;
}
}
else
{
if (s == state)
{
zero = x;
switched = true;
}
}
isUpdated = true;
}
catch (Exception e)
{
PureDesktop.ThrowException(this, e);
}
}
public void RemoveArrow(NullingArrow arrow)
{
object o = arrow.Target;
if (o == machine)
{
machine = null;
return;
}
if (o == consumer)
{
consumer = null;
}
}
/// <summary>
/// The name of measurements source
/// </summary>
public string SourceName
{
get
{
INamedComponent comp = obj as INamedComponent;
return comp.Name;
}
}
/// <summary>
/// The category of this object
/// </summary>
public ICategory Category
{
get
{
return null;
}
}
/// <summary>
/// The identical arrow of this object
/// </summary>
public ICategoryArrow Id
{
get
{
return null;
}
}
/// <summary>
/// The n th measurement
/// </summary>
public IMeasure this[int n]
{
get
{
return measure;
}
}
/// <summary>
/// The count of measurements
/// </summary>
public int Count
{
get
{
return 1;
}
}
public void SetMachine(StateMachine machine)
{
if (this.machine != null)
{
throw new Exception("Machine already exists");
}
this.machine = machine;
}
public void SetConsumer(FormulaDataConsumer consumer)
{
if (this.consumer != null)
{
throw new Exception("Consumer already exists");
}
this.consumer = consumer;
}
public int States
{
get
{
if (machine == null)
{
return 0;
}
return machine.GetLength(0);
}
}
public StateMachine Machine
{
get
{
return machine;
}
}
public FormulaDataConsumer Consumer
{
get
{
return consumer;
}
}
private object getValue()
{
return x - zero;
}
private object getDerivation()
{
return der;
}
private void init()
{
Double a = 0;
measure = new MeasureDerivation(a, new MeasureParameter(getValue),
new MeasureParameter(getDerivation), "Nulling");
}
/// <summary>
/// Shows, wreather the object is updated
/// </summary>
public bool IsUpdated
{
get
{
return isUpdated;
}
set
{
isUpdated = value;
}
}
}
[Serializable()]
public class NullingArrow : ICategoryArrow, IRemovableObject, ISerializable
{
public Nulling source;
/// <summary>
/// The target of this arrow
/// </summary>
public ICategoryObject target;
/// <summary>
/// Linked object
/// </summary>
protected object obj;
int a = 0;
public NullingArrow()
{
}
public NullingArrow(SerializationInfo info, StreamingContext context)
{
a = (int)info.GetValue("A", typeof(int));
}
/// <summary>
/// ISerializable interface implementation
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("A", a);
}
/// <summary>
/// The source of this arrow
/// </summary>
public ICategoryObject Source
{
get
{
return source;
}
set
{
if (!(value is Nulling))
{
CategoryException.ThrowIllegalSourceException();
}
source = value as Nulling;
}
}
/// <summary>
/// The target of this arrow
/// </summary>
public ICategoryObject Target
{
get
{
return target;
}
set
{
if (value is StateMachine)
{
StateMachine machine = value as StateMachine;
source.SetMachine(machine);
return;
}
if (value is FormulaDataConsumer)
{
FormulaDataConsumer consumer = value as FormulaDataConsumer;
source.SetConsumer(consumer);
return;
}
CategoryException.ThrowIllegalTargetException();
}
}
public bool IsMonomorphism
{
get
{
return false;
}
}
public bool IsEpimorphism
{
get
{
return false;
}
}
public bool IsIsomorphism
{
get
{
return false;
}
}
/// <summary>
/// Composes this arrow "f" with next arrow "g"
/// </summary>
/// <param name="category"> The category of arrow</param>
/// <param name="next"> The next arrow "g" </param>
/// <returns>Composition "fg" </returns>
public ICategoryArrow Compose(ICategory category, ICategoryArrow next)
{
return null;
}
/// <summary>
/// Associated object
/// </summary>
public object Object
{
get
{
return obj;
}
set
{
obj = value;
}
}
/// <summary>
/// The post remove operation
/// </summary>
public void RemoveObject()
{
source.RemoveArrow(this);
}
}
/// <summary>
/// Multidimensional dynamical parameter
/// </summary>
public class DynamicalParameter
{
/// <summary>
/// Strig of parameters labels
/// </summary>
private string labels = "";
/// <summary>
/// List of parameters
/// </summary>
private ArrayList parameters = new ArrayList();
/// <summary>
/// Error message of undefined parameter
/// </summary>
public static readonly string UndefinedParameter = "Undefined parameter";
/// <summary>
/// Error message of undefined parameters
/// </summary>
public static readonly string UndefinedParameters = "Undefined parameters";
/// <summary>
/// Constructor
/// </summary>
public DynamicalParameter()
{
}
/// <summary>
/// Adds measurement
/// </summary>
/// <param name="c">Measurement label</param>
/// <param name="m">Measurement</param>
public void Add(char c, IMeasure m)
{
if (labels.IndexOf(c) >= 0)
{
throw new Exception("Double parameter '" + c + "'");
}
labels += c;
parameters.Add(m);
}
/// <summary>
/// Checks whether formula argument contains all parameters
/// </summary>
/// <param name="arg"></param>
/*public void Check(FormulaArgument arg)
{
arg.Check(labels);
}*/
/// <summary>
/// Gets measurement
/// </summary>
public IMeasure this[char c]
{
get
{
int n = labels.IndexOf(c);
if (n < 0)
{
throw new Exception(UndefinedParameter);
}
return parameters[n] as IMeasure;
}
}
/// <summary>
/// Sets formula argument
/// </summary>
/// <param name="arg"></param>
public void Set(ElementaryObjectArgument arg)
{
foreach(char c in labels)
{
arg[c] = this[c].Parameter();
}
}
/// <summary>
/// String of parameter variables
/// </summary>
public string Variables
{
get
{
return labels;
}
}
}
/// <summary>
/// Base class of data consumers
/// </summary>
[Serializable()]
public class DataConsumer : IDataConsumer, ICategoryObject,
ISerializable
{
/// <summary>
/// Desktop
/// </summary>
static private IDesktop desktop;
/// <summary>
/// Type of variable
/// </summary>
static private Double a = 0;
/// <summary>
/// Time
/// </summary>
//static private double time;
/// <summary>
/// Step
/// </summary>
static private int stepNumber;
/// <summary>
/// Desktop
/// </summary>
public static IDesktop Desktop
{
get
{
return desktop;
}
set
{
desktop = value;
}
}
static IMeasure timeMeasure = new MeasureDerivation(a, new MeasureParameter(GetTime), new MeasureParameter(Unity), "Time");
static public List<string> GetAllMeasurements(IDataConsumer consumer, object type)
{
List<string> list = new List<string>();
for (int i = 0; i < consumer.Count; i++)
{
IMeasurements m = consumer[i];
IAssociatedObject ao = m as IAssociatedObject;
IAssociatedObject th = consumer as IAssociatedObject;
string on = PureDesktop.GetRelativeName(th, ao) + ".";
for (int j = 0; j < m.Count; j++)
{
IMeasure mea = m[j];
string s = on + mea.Name;
if (type == null)
{
list.Add(s);
continue;
}
if (mea.Type.Equals(type))
{
list.Add(s);
}
}
}
return list;
}
/// <summary>
/// Gets measures type
/// </summary>
/// <param name="consumer">Consumer</param>
/// <returns>Dictionary of types</returns>
public static Dictionary<string, object> GetAllMeasuresType(IDataConsumer consumer)
{
Dictionary<string, object> dictionary = new Dictionary<string, object>();
for (int i = 0; i < consumer.Count; i++)
{
IMeasurements m = consumer[i];
IAssociatedObject ao = m as IAssociatedObject;
IAssociatedObject th = consumer as IAssociatedObject;
string on = PureDesktop.GetRelativeName(th, ao) + ".";
for (int j = 0; j < m.Count; j++)
{
IMeasure mea = m[j];
string s = on + mea.Name;
dictionary[s] = mea.Type;
}
}
return dictionary;
}
/// <summary>
/// The unity
/// </summary>
/// <returns>Unity</returns>
static private object Unity()
{
return (double)1;
}
/// <summary>
/// Measurement of time
/// </summary>
static public IMeasure TimeMeasure
{
get
{
return timeMeasure;
}
}
/// <summary>
/// Number of step
/// </summary>
static public int StepNumber
{
get
{
return stepNumber;
}
set
{
stepNumber = value;
}
}
/// <summary>
/// Gets time
/// </summary>
/// <returns>The time</returns>
static private object GetTime()
{
return DataPerformerStrategy.Object.Time;
}
/// <summary>
/// The time
/// </summary>
/* public static double Time
{
set
{
IDesktop desktop = Desktop;
ICollection components = DataPerformerStrategy.Object.Components;
time = value;
foreach (INamedComponent comp in components)
{
IDynamical dynamical = null;
if (comp is IObjectLabel)
{
IObjectLabel label = comp as IObjectLabel;
ICategoryObject obj = label.Object;
if (!(obj is IDynamical))
{
continue;
}
dynamical = obj as IDynamical;
}
else if (comp is IArrowLabel)
{
IArrowLabel label = comp as IArrowLabel;
ICategoryArrow arr = label.Arrow;
if (!(arr is IDynamical))
{
continue;
}
dynamical = arr as IDynamical;
}
dynamical.Time = value;
}
DataPerformerStrategy.Object.UpdateAll(desktop);
DataConsumer.ResetUpdatedMeasurements(desktop);
}
get
{
return time;
}
}
*/
/// <summary>
/// Error message of variables shortage
/// </summary>
public static readonly string VariablesShortage = "Shortage of variables";
/// <summary>
/// Arrows to data providers
/// </summary>
protected List<IMeasurements> measurementsData;
/// <summary>
/// Type of consumer
/// </summary>
protected int type;
/// <summary>
/// Object factory
/// </summary>
//protected ElectromagneticUIFactory factory;
/// <summary>
/// Linked desktop component
/// </summary>
//protected NamedComponent control;
/// <summary>
/// Linked object
/// </summary>
protected object obj;
/// <summary>
/// Update flag
/// </summary>
protected bool isUpdated;
/// <summary>
/// Comments
/// </summary>
protected ArrayList comments = new ArrayList();
/// <summary>
/// Controls of graph
/// </summary>
private ArrayList graphControls = new ArrayList();
/// <summary>
/// Start
/// </summary>
private double start = 0;
/// <summary>
/// Step
/// </summary>
private double step = 1;
/// <summary>
/// Number of steps
/// </summary>
private int steps = 2;
/// <summary>
/// Constructor
/// </summary>
/// <param name="type">Type of consumer</param>
public DataConsumer(int type)
{
this.type = type;
initialize();
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
public DataConsumer(SerializationInfo info, StreamingContext context)
{
type = (int)info.GetValue("Type", typeof(int));
try
{
graphControls = (ArrayList)info.GetValue("GraphConrtols", typeof(ArrayList));
start = (double)info.GetValue("Start", typeof(double));
step = (double)info.GetValue("Step", typeof(double));
steps = (int)info.GetValue("Steps", typeof(int));
}
catch (Exception)
{
}
initialize();
}
/// <summary>
/// ISerializable interface implementation
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Type", type);
info.AddValue("GraphConrtols", graphControls);
info.AddValue("Start", start);
info.AddValue("Step", step);
info.AddValue("Steps", steps);
}
/// <summary>
/// Creates correspond xml
/// </summary>
/// <param name="doc">document to create element</param>
/// <returns>The created element</returns>
/*public XmlElement CreateXml(XmlDocument doc)
{
XmlElement el = doc.CreateElement("DataConsumer");
XmlAttribute attr = doc.CreateAttribute("Type");
attr.Value = type + "";
el.Attributes.Append(attr);
if (ConsumerType == (int)ElectromagneticUI.ButtonKinds.GraphConsumer)
{
Form form = control.LabelForm;
if (form != null)
{
IXmlElementCreator xml = form as IXmlElementCreator;
XmlElement plotter = xml.CreateXml(doc);
el.AppendChild(plotter);
}
}
return el;
}*/
/// <summary>
/// Gets all aliases of consumer and all its children
/// </summary>
/// <param name="consumer">The consumer</param>
/// <param name="list">List of aliases</param>
public static void GetAliases(IDataConsumer consumer, List<string> list)
{
getAliases(consumer, consumer, list);
}
/// <summary>
/// Gets list children measurements of data consumer
/// </summary>
/// <param name="consumer">The consumer</param>
/// <param name="measurements">Children measurements</param>
public static void GetMeasurements(IDataConsumer consumer, ArrayList measurements)
{
if (consumer is IMeasurements)
{
if (!measurements.Contains(consumer))
{
measurements.Add(consumer);
}
}
for (int i = 0; i < consumer.Count; i++)
{
object o = consumer[i];
if (o is IDataConsumer)
{
IDataConsumer c = o as IDataConsumer;
GetMeasurements(c, measurements);
}
else
{
if (!(measurements.Contains(o)))
{
measurements.Add(o);
}
}
}
}
/// <summary>
/// Resets updated measurements
/// </summary>
/// <param name="desktop">The desktop</param>
public static void ResetUpdatedMeasurements(IDesktop desktop)
{
ICollection comp = DataPerformerStrategy.Object.Components;
foreach (object o in comp)
{
if (!(o is IObjectLabel))
{
continue;
}
IObjectLabel l = o as IObjectLabel;
object ob = l.Object;
if (!(ob is IMeasurements))
{
continue;
}
IMeasurements m = ob as IMeasurements;
m.IsUpdated = false;
}
}
public static ArrayList GetDataConsumers(IDesktop desktop)
{
ArrayList list = new ArrayList();
ICollection comp = desktop.AllComponents;
foreach (object o in comp)
{
if (!(o is IObjectLabel))
{
continue;
}
IObjectLabel l = o as IObjectLabel;
object ob = l.Object;
if (!(ob is IDataConsumer))
{
continue;
}
list.Add(ob);
}
return list;
}
/// <summary>
/// Aliases of this object and all its children
/// </summary>
public virtual List<string> AllAliases
{
get
{
List<string> a = new List<string>();
DataConsumer.GetAliases(this, a);
return a;
}
}
/// <summary>
/// Finds alias object
/// </summary>
/// <param name="c">Data consumer</param>
/// <param name="alias">Full alias</param>
/// <returns>Pair object[]{object, alias}</returns>
public static object[] FindAlias(IDataConsumer consumer, string alias)
{
return findAlias(consumer, consumer, alias);
}
/// <summary>
/// Gets relative name
/// </summary>
/// <param name="o">Base object</param>
/// <param name="mea">Measurements</param>
/// <returns>The name</returns>
public static string GetName(IAssociatedObject o, IMeasurements mea)
{
IAssociatedObject ao = mea as IAssociatedObject;
return PureDesktop.GetRelativeName(o, ao);
}
/// <summary>
/// Controls of graph
/// </summary>
public ArrayList GraphControls
{
get
{
return graphControls;
}
set
{
graphControls = value;
}
}
/// <summary>
/// Adds target arrow
/// </summary>
/// <param name="arrow">Arrow to add</param>
public void Add(IMeasurements arrow)
{
measurementsData.Add(arrow);
}
/// <summary>
/// Removes target arrow
/// </summary>
/// <param name="arrow">Arrow to remove</param>
public void Remove(IMeasurements arrow)
{
measurementsData.Remove(arrow);
}
/// <summary>
/// Updates chidren measurements
/// </summary>
public void UpdateChildrenData()
{
try
{
foreach (IMeasurements m in measurementsData)
{
m.UpdateMeasurements();
}
}
catch (Exception e)
{
PureDesktop.ThrowException(this, e);
}
}
/// <summary>
/// Resets measurements
/// </summary>
public void Reset()
{
Reset(this);
}
/// <summary>
/// Resets data consumer
/// </summary>
/// <param name="consumer">The consumer</param>
public static void Reset(IDataConsumer consumer)
{
if (consumer is IMeasurements)
{
IMeasurements mea = consumer as IMeasurements;
mea.IsUpdated = false;
}
for (int i = 0; i < consumer.Count; i++)
{
IMeasurements m = consumer[i] as IMeasurements;
m.IsUpdated = false;
if (m is IDataConsumer)
{
IDataConsumer c = m as IDataConsumer;
c.Reset();
}
}
}
/// <summary>
/// Count of providers
/// </summary>
public int Count
{
get
{
return measurementsData.Count;
}
}
/// <summary>
/// Arrow of n th provider
/// </summary>
public IMeasurements this[int n]
{
get
{
return measurementsData[n];
}
}
/// <summary>
/// Gets aliases of this object and all its childen
/// </summary>
/// <param name="list"></param>
// public void GetAliases(ArrayList list)
// {
// }
/// <summary>
/// The category of this object
/// </summary>
public ICategory Category
{
get
{
return null;
}
}
/// <summary>
/// The identical arrow of this object
/// </summary>
public ICategoryArrow Id
{
get
{
return null;
}
}
/// <summary>
/// Type of consumer
/// </summary>
public int ConsumerType
{
get
{
return type;
}
}
/// <summary>
/// The UI factory of domain
/// </summary>
/* public IUIFactory Facrory
{
get
{
return factory;
}
set
{
factory = value as ElectromagneticUIFactory;
}
}*/
/// <summary>
/// Associated object
/// </summary>
public object Object
{
get
{
return obj;
}
set
{
obj = value;
}
}
/// <summary>
/// Shows, wreather the object is updated
/// </summary>
public bool IsUpdated
{
get
{
return isUpdated;
}
set
{
isUpdated = value;
}
}
/// <summary>
/// Start
/// </summary>
public double Start
{
get
{
return start;
}
set
{
start = value;
}
}
/// <summary>
/// Step
/// </summary>
public double Step
{
get
{
return step;
}
set
{
step = value;
}
}
/// <summary>
/// Number of steps
/// </summary>
public int Steps
{
get
{
return steps;
}
set
{
steps = value;
}
}
public static XmlDocument GetArraysXmlDocument(IDataConsumer consumer)
{
ArrayList meas = new ArrayList();
int[] r = null;
int n = consumer.Count;
for (int i = 0; i < n; i++)
{
IMeasurements mea = consumer[i];
int k = mea.Count;
for (int j = 0; j < k; j++)
{
IMeasure m = mea[j];
object type = m.Type;
if (!(type is ArrayReturnType))
{
continue;
}
ArrayReturnType art = type as ArrayReturnType;
int[] rr = art.Dimension;
if (rr.Length > 1)
{
continue;
}
if (r == null)
{
r = rr;
}
if (r[0] != rr[0])
{
continue;
}
meas.Add(m);
}
}
if (r == null)
{
return null;
}
XmlDocument doc = new XmlDocument();
doc.LoadXml("<?xml version=\"1.0\"?><ExperimentalData><Root></Root></ExperimentalData>");
XmlElement root = doc.GetElementsByTagName("Root")[0] as XmlElement;
XmlAttribute att = doc.CreateAttribute("uid");
att.Value = Guid.NewGuid() + "";
root.Attributes.Append(att);
att = doc.CreateAttribute("time");
att.Value = DateTime.Now + "";
root.Attributes.Append(att);
XmlElement descr = doc.CreateElement("ParametersDescription");
root.AppendChild(descr);
for (int i = 0; i < meas.Count; i++)
{
IMeasure m = meas[i] as IMeasure;
XmlElement e = doc.CreateElement("ParameterDescription");
descr.AppendChild(e);
att = doc.CreateAttribute("id");
att.Value = i + "";
e.Attributes.Append(att);
att = doc.CreateAttribute("name");
att.Value = m.Name;
e.Attributes.Append(att);
}
XmlElement results = doc.CreateElement("Results");
root.AppendChild(results);
for (int i = 0; i < r[0]; i++)
{
XmlElement result = doc.CreateElement("Result");
results.AppendChild(result);
for (int j = 0; j < meas.Count; j++)
{
IMeasure mea = meas[j] as IMeasure;
XmlElement par = doc.CreateElement("Parameter");
result.AppendChild(par);
att = doc.CreateAttribute("id");
att.Value = j + "";
par.Attributes.Append(att);
att = doc.CreateAttribute("value");
object[] o = mea.Parameter() as object[];
att.Value = o[i] + "";
par.Attributes.Append(att);
}
}
return doc;
}
private static void getAliases(IDataConsumer baseObject, IDataConsumer consumer, List<string> list)
{
IAssociatedObject ao = consumer as IAssociatedObject;
PureObjectLabel.GetObjectAliases(ao, consumer, list);
for (int i = 0; i < consumer.Count; i++)
{
object o = consumer[i];
if (o is IDataConsumer)
{
IDataConsumer c = o as IDataConsumer;
getAliases(consumer, c, list);
}
else
{
PureObjectLabel.GetObjectAliases(ao, o, list);
}
}
}
/// <summary>
/// Finds alias object
/// </summary>
/// <param name="c">Data consumer</param>
/// <param name="alias">Full alias</param>
/// <returns>Pair objec[]{object, alias}</returns>
public static object[] findAlias(IDataConsumer baseObject, IDataConsumer consumer, string alias)
{
IAssociatedObject ao = baseObject as IAssociatedObject;
INamedComponent nc = PureObjectLabel.PrefixComponent(ao, consumer, alias);
if ((nc != null) & (consumer is IAlias))
{
return new object[]{consumer, PureObjectLabel.Suffix(alias)};
}
for (int i = 0; i < consumer.Count; i++)
{
object o = consumer[i];
if (o is IDataConsumer)
{
IDataConsumer c = o as IDataConsumer;
object[] r = findAlias(baseObject, c, alias);
if (r != null)
{
return r;
}
}
else
{
INamedComponent comp = PureObjectLabel.PrefixComponent(ao, o, alias);
if ((comp != null) & (o is IAlias))
{
return new object[]{o, PureObjectLabel.Suffix(alias)};
}
}
}
return null;
}
/// <summary>
/// Gets name of measure
/// </summary>
/// <param name="consumer">Data consumer</param>
/// <param name="measure">Measure</param>
/// <returns>The name</returns>
public static string GetName(IDataConsumer consumer, IMeasure measure)
{
IAssociatedObject ass = consumer as IAssociatedObject;
INamedComponent comp = ass.Object as INamedComponent;
IDesktop d = comp.Desktop;
for (int i = 0; i < consumer.Count; i++)
{
IMeasurements mea = consumer[i];
for (int j = 0; j < mea.Count; j++)
{
IMeasure m = mea[j];
if (m == measure)
{
IAssociatedObject ao = mea as IAssociatedObject;
INamedComponent nc = ao.Object as INamedComponent;
string name = PureObjectLabel.GetName(nc, d);
return name + "." + m.Name;
}
}
}
return null;
}
/// <summary>
/// Finds measure
/// </summary>
/// <param name="consumer">Data consumer</param>
/// <param name="measure">Measure name</param>
/// <returns>The measure</returns>
public static IMeasure FindMeasure(IDataConsumer consumer, string measure)
{
int n = measure.LastIndexOf(".");
string p = measure.Substring(0, n);
string s = measure.Substring(n + 1);
IAssociatedObject ass = consumer as IAssociatedObject;
INamedComponent comp = ass.Object as INamedComponent;
IDesktop d = comp.Desktop;
for (int i = 0; i < consumer.Count; i++)
{
IMeasurements mea = consumer[i];
IAssociatedObject ao = mea as IAssociatedObject;
INamedComponent nc = ao.Object as INamedComponent;
string name = PureObjectLabel.GetName(nc, d);
if (!name.Equals(p))
{
continue;
}
for (int j = 0; j < mea.Count; j++)
{
IMeasure m = mea[j];
if (s.Equals(m.Name))
{
return m;
}
}
}
return null;
}
/// <summary>
/// Initialization
/// </summary>
private void initialize()
{
measurementsData = new List<IMeasurements>();
}
}
[Serializable()]
public class FourierSeriesLink : ICategoryArrow, ISerializable,
IRemovableObject
{
/// <summary>
/// The source of this arrow
/// </summary>
private FourierSeries source;
/// <summary>
/// The target of this arrow
/// </summary>
private Series target;
/// <summary>
/// Auxiliary field
/// </summary>
private int a = 0;
/// <summary>
/// Linked object
/// </summary>
protected object obj;
/// <summary>
/// Constuctor
/// </summary>
public FourierSeriesLink()
{
}
/// <summary>
/// Deserializetion contructor
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
public FourierSeriesLink(SerializationInfo info, StreamingContext context)
{
a = (int)info.GetValue("A", typeof(int));
}
/// <summary>
/// ISerializable interface implementation
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("A", a);
}
/// <summary>
/// Creates correspond xml
/// </summary>
/// <param name="doc">document to create element</param>
/// <returns>The created element</returns>
/*public XmlElement CreateXml(XmlDocument doc)
{
XmlElement el = doc.CreateElement("FourierSeriesLink");
return el;
}*/
/// <summary>
/// The source of this arrow
/// </summary>
public ICategoryObject Source
{
set
{
if (!(value is FourierSeries))
{
CategoryException.ThrowIllegalSourceException();
}
source = value as FourierSeries;
}
get
{
return source as ICategoryObject;
}
}
/// <summary>
/// The target of this arrow
/// </summary>
public ICategoryObject Target
{
get
{
return target as ICategoryObject;
}
set
{
if (!(value is Series))
{
CategoryException.ThrowIllegalTargetException();
}
target = value as Series;
source.AddSeries(target);
}
}
public bool IsMonomorphism
{
get
{
return false;
}
}
public bool IsEpimorphism
{
get
{
return false;
}
}
public bool IsIsomorphism
{
get
{
return false;
}
}
/// <summary>
/// Composes this arrow "f" with next arrow "g"
/// </summary>
/// <param name="category"> The category of arrow</param>
/// <param name="next"> The next arrow "g" </param>
/// <returns>Composition "fg" </returns>
public ICategoryArrow Compose(ICategory category, ICategoryArrow next)
{
return null;
}
/// <summary>
/// Associated object
/// </summary>
public object Object
{
get
{
return obj;
}
set
{
obj = value;
}
}
/// <summary>
/// The post remove operation
/// </summary>
public void RemoveObject()
{
source.RemoveSeries(target);
}
}
[Serializable()]
public class SwitchLink : ICategoryArrow, ISerializable, IRemovableObject
{
private FormulaDataConsumer target;
private ISwitched source;
//private bool isUpdatable = false;
/// <summary>
/// Linked object
/// </summary>
protected object obj;
int a;
public SwitchLink()
{
a = 0;
}
public SwitchLink(SerializationInfo info, StreamingContext context)
{
a = (int)info.GetValue("A", typeof(int));
}
/// <summary>
/// ISerializable interface implementation
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("A", a);
}
/// <summary>
/// Creates correspond xml
/// </summary>
/// <param name="doc">document to create element</param>
/// <returns>The created element</returns>
/*public XmlElement CreateXml(XmlDocument doc)
{
XmlElement el = doc.CreateElement("SwitchLink");
return el;
}*/
/// <summary>
/// Composes this arrow "f" with next arrow "g"
/// </summary>
/// <param name="category"> The category of arrow</param>
/// <param name="next"> The next arrow "g" </param>
/// <returns>Composition "fg" </returns>
public ICategoryArrow Compose(ICategory category, ICategoryArrow next)
{
return null;
}
/// <summary>
/// The category of this object
/// </summary>
public ICategory Category
{
get
{
return null;
}
}
/// <summary>
/// Associated object
/// </summary>
public object Object
{
get
{
return obj;
}
set
{
obj = value;
}
}
/// <summary>
/// The post remove operation
/// </summary>
public void RemoveObject()
{
source.RemoveSwitch(this);
}
/// <summary>
/// The source of this arrow
/// </summary>
public ICategoryObject Source
{
get
{
return source as ICategoryObject;
}
set
{
if (!(value is ISwitched))
{
CategoryException.ThrowIllegalSourceException();
}
source = value as ISwitched;
}
}
/// <summary>
/// The target of this arrow
/// </summary>
public ICategoryObject Target
{
get
{
return target;
}
set
{
if (source == null)
{
throw new Exception("Source object is missing");
}
if (source == value)
{
throw new Exception("Target of switch link should not concide with source");
}
if (!(value is FormulaDataConsumer))
{
CategoryException.ThrowIllegalTargetException();
}
target = value as FormulaDataConsumer;
source.AddSwitch(this);
}
}
public bool IsMonomorphism
{
get
{
return false;
}
}
public bool IsEpimorphism
{
get
{
return false;
}
}
public bool IsIsomorphism
{
get
{
return false;
}
}
}
[Serializable()]
public class UnaryLink : ICategoryArrow, ISerializable,
IRemovableObject
{
private VectorFormulaConsumer source;
private IObjectOperation target;
/// <summary>
/// Linked object
/// </summary>
protected object obj;
int a;
public UnaryLink()
{
a = 0;
}
public UnaryLink(SerializationInfo info, StreamingContext context)
{
a = (int)info.GetValue("A", typeof(int));
}
/// <summary>
/// ISerializable interface implementation
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("A", a);
}
/// <summary>
/// Creates correspond xml
/// </summary>
/// <param name="doc">document to create element</param>
/// <returns>The created element</returns>
/*public XmlElement CreateXml(XmlDocument doc)
{
XmlElement el = doc.CreateElement("SeriesLink");
return el;
}*/
/// <summary>
/// Composes this arrow "f" with next arrow "g"
/// </summary>
/// <param name="category"> The category of arrow</param>
/// <param name="next"> The next arrow "g" </param>
/// <returns>Composition "fg" </returns>
public ICategoryArrow Compose(ICategory category, ICategoryArrow next)
{
return null;
}
/// <summary>
/// The category of this object
/// </summary>
public ICategory Category
{
get
{
return null;
}
}
/// <summary>
/// Associated object
/// </summary>
public object Object
{
get
{
return obj;
}
set
{
obj = value;
}
}
/// <summary>
/// The post remove operation
/// </summary>
public void RemoveObject()
{
source.RemoveOperation(target);
}
/// <summary>
/// The source of this arrow
/// </summary>
public ICategoryObject Source
{
get
{
return source;
}
set
{
if (!(value is VectorFormulaConsumer))
{
CategoryException.ThrowIllegalSourceException();
}
source = value as VectorFormulaConsumer;
}
}
/// <summary>
/// The target of this arrow
/// </summary>
public ICategoryObject Target
{
get
{
return target as ICategoryObject;
}
set
{
if (!(value is IObjectOperation))
{
CategoryException.ThrowIllegalTargetException();
}
target = value as IObjectOperation;
source.AddOperation(target);
}
}
public bool IsMonomorphism
{
get
{
return false;
}
}
public bool IsEpimorphism
{
get
{
return false;
}
}
public bool IsIsomorphism
{
get
{
return false;
}
}
}
[Serializable()]
public class FormulaRegressionLink : ICategoryArrow, ISerializable,
IRemovableObject
{
/// <summary>
/// The source
/// </summary>
private FormulaRegression source;
/// <summary>
/// The target
/// </summary>
private ICategoryObject target;
/// <summary>
/// Linked object
/// </summary>
protected object obj;
int a;
public FormulaRegressionLink()
{
a = 0;
}
public FormulaRegressionLink(SerializationInfo info, StreamingContext context)
{
a = (int)info.GetValue("A", typeof(int));
}
/// <summary>
/// ISerializable interface implementation
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("A", a);
}
/// <summary>
/// Creates correspond xml
/// </summary>
/// <param name="doc">document to create element</param>
/// <returns>The created element</returns>
/*public XmlElement CreateXml(XmlDocument doc)
{
XmlElement el = doc.CreateElement("FormulaRegressionLink");
return el;
}*/
/// <summary>
/// Composes this arrow "f" with next arrow "g"
/// </summary>
/// <param name="category"> The category of arrow</param>
/// <param name="next"> The next arrow "g" </param>
/// <returns>Composition "fg" </returns>
public ICategoryArrow Compose(ICategory category, ICategoryArrow next)
{
return null;
}
/// <summary>
/// The category of this object
/// </summary>
public ICategory Category
{
get
{
return null;
}
}
/// <summary>
/// Associated object
/// </summary>
public object Object
{
get
{
return obj;
}
set
{
obj = value;
}
}
/// <summary>
/// The source of this arrow
/// </summary>
public ICategoryObject Source
{
get
{
return source;
}
set
{
if (!(value is FormulaRegression))
{
CategoryException.ThrowIllegalSourceException();
}
source = value as FormulaRegression;
}
}
/// <summary>
/// The target of this arrow
/// </summary>
public ICategoryObject Target
{
get
{
return target;
}
set
{
if (source == null)
{
throw new Exception("Source object is missing");
}
if (source == value)
{
throw new Exception("Target of switch link should not concide with source");
}
if (value is IArgumentSelection)
{
source.AddSelection(value as IArgumentSelection);
target = value;
return;
}
if (value is VectorFormulaConsumer)
{
source.Formula = value as VectorFormulaConsumer;
target = value;
return;
}
CategoryException.ThrowIllegalTargetException();
}
}
public bool IsMonomorphism
{
get
{
return false;
}
}
public bool IsEpimorphism
{
get
{
return false;
}
}
public bool IsIsomorphism
{
get
{
return false;
}
}
/// <summary>
/// The post remove operation
/// </summary>
public void RemoveObject()
{
if (target is IArgumentSelection)
{
IArgumentSelection s = target as IArgumentSelection;
source.RemoveSelection(s);
}
}
}
/// <summary>
/// Selection with arguments
/// </summary>
public class ArgumentMultiSelection : IArgumentSelection
{
private ArrayList selections = new ArrayList();
private ArrayList etalons = new ArrayList();
//private int pointsCount;
private int dim = 0;
private string name = "";
/// <summary>
/// Count of points
/// </summary>
public int PointsCount
{
get
{
return first.PointsCount;
}
}
/// <summary>
/// Free variables
/// </summary>
public string[] Variables
{
get
{
return first.Variables;
}
}
/// <summary>
/// Dimension of output vector
/// </summary>
public int VectorDimension
{
get
{
return dim;
}
}
/// <summary>
/// Gets value of variable
/// </summary>
public double this[int i, string str]
{
get
{
return first[i, str];
}
}
/// <summary>
/// Adds seletion
/// </summary>
/// <param name="sel">Selection to add</param>
public void AddSelection(IArgumentSelection sel)
{
if (selections.Count == 0)
{
selections.Add(sel);
etalons.Add(sel);
dim += sel.VectorDimension;
return;
}
string[] variables = first.Variables;
string[] var = sel.Variables;
if (var.Length != variables.Length)
{
throw new Exception("Illegal number of variables");
}
foreach (string s in var)
{
foreach (string s1 in variables)
{
if (s.Equals(s1))
{
goto m1;
}
}
throw new Exception("Illegal variables");
m1: continue;
}
dim += sel.VectorDimension;
etalons.Add(sel);
selections.Add(sel.SynchronizedSelection(selections[0] as IArgumentSelection));
}
/// <summary>
/// Removes selection
/// </summary>
/// <param name="sel">Selection to remove</param>
public void RemoveSelection(IArgumentSelection sel)
{
int n = etalons.IndexOf(sel);
if (n >= 0)
{
etalons.RemoveAt(n);
selections.RemoveAt(n);
dim -= sel.VectorDimension;
}
}
/// <summary>
/// Component of i - th selection
/// </summary>
/// <param name="i">Selection number</param>
/// <returns>The component</returns>
public IObjectLabel GetComponent(int i)
{
ICategoryObject o = etalons[i] as ICategoryObject;
return o.Object as IObjectLabel;
}
/// <summary>
/// Dimension of data
/// </summary>
public int DataDimension
{
get
{
return PointsCount * VectorDimension;
}
}
/// <summary>
/// Access to n - th element
/// </summary>
public double? this[int n]
{
get
{
int m = n / dim;
int k = n - dim * m;
IArgumentSelection s = selections[k] as IArgumentSelection;
return s[m];
}
}
/// <summary>
/// Weight of n - th element
/// </summary>
/// <param name="n">Element number</param>
/// <returns>The weight</returns>
public double GetWeight(int n)
{
return 1;
}
/// <summary>
/// Aprior weight of n - th element
/// </summary>
/// <param name="n">Element number</param>
/// <returns>The weight</returns>
public double GetApriorWeight(int n)
{
return 0;
}
/// <summary>
/// Tolerance of it - th element
/// </summary>
/// <param name="n">Element number</param>
/// <returns>Tolerance</returns>
public int GetTolerance(int n)
{
return 0;
}
/// <summary>
/// Sets tolerance of n - th element
/// </summary>
/// <param name="n">Element number</param>
/// <param name="tolerance">Tolerance to set</param>
public void SetTolerance(int n, int tolerance)
{
}
/// <summary>
/// The "is fixed amount" sign
/// </summary>
public bool HasFixedAmount
{
get
{
foreach (IStructuredSelection s in selections)
{
if (!s.HasFixedAmount)
{
return false;
}
}
return true;
}
}
/// <summary>
/// Selection name
/// </summary>
public string Name
{
get
{
return name;
}
}
/// <summary>
/// Calculates synchronized selection
/// </summary>
/// <param name="selection">The etalon selection</param>
/// <returns>Synchronized selection</returns>
public IArgumentSelection SynchronizedSelection(IArgumentSelection selection)
{
ArgumentMultiSelection sel = new ArgumentMultiSelection();
for (int i = 0; i < selections.Count; i++)
{
IArgumentSelection s = selections[i] as IArgumentSelection;
sel.AddSelection(s.SynchronizedSelection(selection));
}
return sel;
}
/// <summary>
/// Gets i - th selection
/// </summary>
/// <param name="i">The selection nubmer</param>
/// <returns>Choosen selection</returns>
public IArgumentSelection GetSelection(int i)
{
return selections[i] as IArgumentSelection;
}
/// <summary>
/// Count of selections
/// </summary>
public int SelectionCount
{
get
{
return selections.Count;
}
}
/// <summary>
/// First selection
/// </summary>
private IArgumentSelection first
{
get
{
if (selections.Count == 0)
{
return null;
}
return selections[0] as IArgumentSelection;
}
}
}
/// <summary>
/// Switched object
/// </summary>
public interface ISwitched
{
/// <summary>
/// Adds switch link
/// </summary>
/// <param name="link">Link to add</param>
void AddSwitch(SwitchLink link);
/// <summary>
/// Removes switch link
/// </summary>
/// <param name="link">Link to remove</param>
void RemoveSwitch(SwitchLink link);
}
/// <summary>
/// ArrayCalculatorAccociated with formulas
/// </summary>
public class FormulaArrayCalculator
{
/// <summary>
/// Number of calculator
/// </summary>
static private int staticNumber = 0;
/// <summary>
/// Global calculator
/// </summary>
//static public GlobalArrayCalculator GlobalCalculator = new GlobalArrayCalculator(Calculate);
/// <summary>
/// Calculators
/// </summary>
static private Hashtable calculators = new Hashtable();
/// <summary>
/// Number of calculator
/// </summary>
private int number;
/// <summary>
/// Arguments
/// </summary>
private string[] arguments;
/// <summary>
/// Signal dimension
/// </summary>
private int dim;
/// <summary>
/// Formula consumer
/// </summary>
private VectorFormulaConsumer formulas;
/// <summary>
/// Diagram calculator
/// </summary>
private ArrayCalculator calculator;
/// <summary>
/// Constructor
/// </summary>
/// <param name="formulas">Formula consumer</param>
public FormulaArrayCalculator(VectorFormulaConsumer formulas)
{
this.formulas = formulas;
IMeasurements m = formulas;
List<string> al = formulas.AliasNames;
List<string> a = new List<string>();
for (int i = 0; i < al.Count; i++)
{
a.Add(al[i]);
}
a.Sort();
arguments = new string[al.Count];
for (int i = 0; i < a.Count; i++)
{
arguments[i] = a[i] as string;
}
dim = formulas.Count;
calculator = new ArrayCalculator(calculate);
number = staticNumber;
//AddCalculator(calculator);
}
/// <summary>
/// Calculator
/// </summary>
/*public ArrayCalculator Calculator
{
get
{
return calculator;
}
}*/
/// <summary>
/// Destructor
/// </summary>
/*
~FormulaArrayCalculator()
{
calculators[number] = null;
}*/
/// <summary>
/// Calculates parameters of i - th calculator
/// </summary>
/// <param name="i">Calculator number</param>
/// <param name="x">Input</param>
/// <param name="data">Output</param>
/* public static void Calculate(int i, int n, int m, double[] x, double [] data)
{
ArrayCalculator calc = calculators[i] as ArrayCalculator;
calc(n, m, x, data);
}*/
/// <summary>
/// Adds calculator
/// </summary>
/// <param name="calculator">Calculator to add</param>
/*public static int AddCalculator(ArrayCalculator calculator)
{
calculators[staticNumber] = calculator;
if (staticNumber == 0)
{
ArrayCalculatorWrapper.SetGlobalCalculator(GlobalCalculator);
}
staticNumber++;
return staticNumber - 1;
}*/
/// <summary>
/// Output dimension
/// </summary>
public int Dim
{
get
{
return dim;
}
}
/// <summary>
/// Formula calculator
/// </summary>
public ArrayCalculator Calculator
{
get
{
return calculator;
}
}
/// <summary>
/// Number of calculator
/// </summary>
public int Number
{
get
{
return number;
}
}
/// <summary>
/// Arguments of calculator
/// </summary>
public string[] Arguments
{
get
{
return arguments;
}
}
/// <summary>
/// Calculation
/// </summary>
/// <param name="x">Input</param>
/// <param name="data">Output</param>
private void calculate(int n, int m, double[] x, double [] data)
{
for (int i = 0; i < n; i++)
{
formulas[arguments[i]] = x[i];
}
IMeasurements mea = formulas;
mea.UpdateMeasurements();
for (int i = 0; i < m; i++)
{
data[i] = (double)mea[i].Parameter();
}
}
}
/// <summary>
/// Vector formula data transformer
/// </summary>
[Serializable()]
public class FourierSeries : DataConsumer, IMeasurements, ISerializable,
IPostSetArrow, IAssociatedObject
{
/// <summary>
/// Output measurements
/// </summary>
private IMeasure[] output = new IMeasure[2];
/// <summary>
/// Results of calculation
/// </summary>
private double[,] result = new double[2, 2];
/// <summary>
/// Arguments
/// </summary>
private string argument;
/// <summary>
/// Input measurements
/// </summary>
private IMeasure input;
/// <summary>
/// List of series
/// </summary>
private ArrayList seriesList = new ArrayList();
/// <summary>
/// Series
/// </summary>
private Series[] series = new Series[2];
/// <summary>
/// Names of unary
/// </summary>
private Hashtable seriesTable = new Hashtable();
/// <summary>
/// Constructor
/// </summary>
public FourierSeries() : base(65)
{
argument = "";
for (int i = 0; i < 2; i++)
{
seriesTable[i] = "";
}
Double a = 0;
output[0] = new MeasureDerivation(a, new MeasureParameter(getRe), new MeasureParameter(getReDerivation), "Real");
output[1] = new MeasureDerivation(a, new MeasureParameter(getIm), new MeasureParameter(getImDerivation), "Image");
}
/// <summary>
/// Constructor
/// </summary>
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
public FourierSeries(SerializationInfo info, StreamingContext context) :
base(65)
{
try
{
argument = (string)info.GetValue("Argument", typeof(string));
seriesTable = info.GetValue("SeriesTable", typeof(Hashtable)) as Hashtable;
}
catch (Exception)
{
seriesTable = new Hashtable();
seriesTable[0] = "";
seriesTable[1] = "";
}
if (seriesTable == null)
{
}
Double a = 0;
output[0] = new MeasureDerivation(a, new MeasureParameter(getRe), new MeasureParameter(getReDerivation), "Real");
output[1] = new MeasureDerivation(a, new MeasureParameter(getIm), new MeasureParameter(getImDerivation), "Image");
}
/// <summary>
/// ISerializable interface implementation
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
new public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Argument", argument);
info.AddValue("SeriesTable", seriesTable);
}
/// <summary>
/// Creates correspond xml
/// </summary>
/// <param name="doc">document to create element</param>
/// <returns>The created element</returns>
/*new public XmlElement CreateXml(XmlDocument doc)
{
XmlElement el = doc.CreateElement("FourierSeries");
return el;
}*/
/// <summary>
/// Series table
/// </summary>
public Hashtable SeriesTable
{
get
{
return seriesTable;
}
}
/// <summary>
/// Table of series names
/// </summary>
/* public Hashtable SeriesNames
{
get
{
return seriesNames;
}
}*/
/// <summary>
/// Adds series to list
/// </summary>
/// <param name="series">Series to remove</param>
public void AddSeries(Series series)
{
if (seriesList.Count == 2)
{
throw new Exception("Too many series");
}
seriesList.Add(series);
}
/// <summary>
/// Removes series
/// </summary>
/// <param name="series">Series to remove</param>
public void RemoveSeries(Series series)
{
seriesList.Remove(series);
}
/// <summary>
/// The count of measurements
/// </summary>
int IMeasurements.Count
{
get
{
return 2;
}
}
/// <summary>
/// Access to n - th measurement
/// </summary>
IMeasure IMeasurements.this[int n]
{
get
{
return output[n];
}
}
/// <summary>
/// Updates measurements data
/// </summary>
public void UpdateMeasurements()
{
if (IsUpdated)
{
return;
}
try
{
UpdateChildrenData();
result[0, 0] = 0;
result[1, 0] = 0;
double x = (double)input.Parameter();
IDerivation der = input as IDerivation;
double d = (double)der.Derivation;
for (int i = 0; i < series[0].Count; i++)
{
double om = series[0][i, 0];
d *= om;
double a = x * om;
double s = Math.Sin(a);
double c = Math.Cos(a);
double re = series[0][i, 1] * c + series[1][i, 1] * s;
double im = -series[0][i, 1] * s + series[1][i, 1] * c;
result[0, 0] += re;
result[1, 0] += im;
result[0, 1] += d * im;
result[1, 1] -= d * re;
}
isUpdated = true;
}
catch (Exception e)
{
PureDesktop.ThrowException(this, e);
}
}
/// <summary>
/// The operation that performs after arrows setting
/// </summary>
public void PostSetArrow()
{
acceptArgument();
AcceptSeries();
}
/// <summary>
/// The name of measurements source
/// </summary>
public string SourceName
{
get
{
INamedComponent comp = obj as INamedComponent;
return comp.Name;
}
}
/// <summary>
/// Argument
/// </summary>
public string Argument
{
get
{
return argument;
}
set
{
argument = value;
acceptArgument();
}
}
public DynamicalParameter Parameter
{
set
{
if (value.Variables.Length != 1)
{
throw new Exception("Fourier transform should have one parameter");
}
input = value['x'];
argument = input.Name;
}
}
/// <summary>
/// Gets i - th unary
/// </summary>
/// <param name="i">Unary number</param>
/// <returns>The i - th unary</returns>
public IUnary GetUnary(int i)
{
return seriesList[i] as IUnary;
}
/// <summary>
/// Count of unaries
/// </summary>
public int UnaryCount
{
get
{
return seriesList.Count;
}
}
public void AcceptSeries()
{
if (seriesTable.Count != 2)
{
return;
}
for (int i = 0; i < 2; i++)
{
string sn = seriesTable[i] as string;
foreach (Series s in seriesList)
{
//INamedComponent nc = s.Object as INamedComponent;
if (sn.Equals(PureDesktop.GetRelativeName(this, s)))//nc.Name))
{
series[i] = s;
continue;
}
}
}
}
/// <summary>
/// Accepts arguments
/// </summary>
private void acceptArgument()
{
foreach (IMeasurements measurements in measurementsData)
{
/*IAssociatedObject cont = measurements as IAssociatedObject;
INamedComponent c = cont.Object as INamedComponent;*/
string name = DataConsumer.GetName(this, measurements);//c.Name;
for (int i = 0; i < measurements.Count; i++)
{
IMeasure measure = measurements[i];
string p = name + "." + measure.Name;
if (argument.Substring(4).Equals(p))
{
input = measure;
break;
}
}
}
if (argument.Equals("Time"))
{
input = DataConsumer.TimeMeasure;
}
}
/// <summary>
/// Gets function value
/// </summary>
/// <returns>The value</returns>
private object getRe()
{
return result[0, 0];
}
/// <summary>
/// Gets function value
/// </summary>
/// <returns>The value</returns>
private object getIm()
{
return result[1, 0];
}
/// <summary>
/// Gets function derivation
/// </summary>
/// <returns>The derivation</returns>
private object getReDerivation()
{
return result[0, 1];
}
/// <summary>
/// Gets function derivation
/// </summary>
/// <returns>The derivation</returns>
private object getImDerivation()
{
return result[1, 1];
}
}
/// <summary>
/// Processor for solving ordinary differential equations system
/// </summary>
public abstract class DifferentialEquationProcessor
{
/// <summary>
/// Processor
/// </summary>
static private DifferentialEquationProcessor processor;
/// <summary>
/// The is busy sign
/// </summary>
protected bool isBusy = false;
/// <summary>
/// Processor
/// </summary>
public static DifferentialEquationProcessor Object
{
get
{
return processor;
}
set
{
processor = value;
}
}
/// <summary>
/// Systems of equations
/// </summary>
protected ArrayList equations = new ArrayList();
/// <summary>
/// Children measurements
/// </summary>
protected ArrayList measurements = new ArrayList();
/// <summary>
/// Constructor
/// </summary>
protected DifferentialEquationProcessor()
{
}
/// <summary>
/// Sets root data consumers
/// </summary>
/// <param name="consumers">Consumers to set</param>
public virtual void Set(ArrayList consumers)
{
equations.Clear();
measurements.Clear();
foreach (IDataConsumer c in consumers)
{
DataConsumer.GetMeasurements(c, measurements);
}
foreach (IMeasurements m in measurements)
{
if (m is IDifferentialEquationSolver)
{
equations.Add(m);
}
}
}
/// <summary>
/// Count of equations system
/// </summary>
public int Count
{
get
{
return equations.Count;
}
}
/// <summary>
/// Access to i - th equations sistem
/// </summary>
public IDifferentialEquationSolver this[int i]
{
get
{
return equations[i] as IDifferentialEquationSolver;
}
}
/// <summary>
/// Resets "is updated" sign
/// </summary>
public void Reset()
{
foreach (IMeasurements m in measurements)
{
m.IsUpdated = false;
}
}
/// <summary>
/// Sets root data consumer
/// </summary>
/// <param name="consumer">The consumer to set</param>
public void Set(IDataConsumer consumer)
{
ArrayList l = new ArrayList();
l.Add(consumer);
Set(l);
}
/// <summary>
/// Dimension of state vector
/// </summary>
public int Dim
{
get
{
int n = 0;
foreach (IMeasurements m in equations)
{
n += m.Count;
}
return n;
}
}
public void UpdateMeasurements()
{
if (Dim > 0)
{
foreach (IMeasurements m in measurements)
{
m.UpdateMeasurements();
}
}
}
/// <summary>
/// Performs step of integration
/// </summary>
/// <param name="t0">Step start</param>
/// <param name="t2">Step finish</param>
abstract public void Step(double t0, double t2);
/// <summary>
/// The "is busy" sign
/// </summary>
public bool IsBusy
{
get
{
return isBusy;
}
}
}
/// <summary>
/// Runge processor for solving ordinary differential equations system
/// </summary>
public class RungeProcessor : DifferentialEquationProcessor
{
/// <summary>
/// Coefficients of method
/// </summary>
static readonly double[] a = {0.5, 0.5, 1.0, 1.0, 0.5};
/// <summary>
/// One divide by three
/// </summary>
//static readonly double one_to_three = 1.0 / 3.0;
/// <summary>
/// Auxiliary buffer variable
/// </summary>
private double[] z;
/// <summary>
/// Auxiliary buffer variable
/// </summary>
private double[] w;
/// <summary>
/// Auxiliary buffer variable
/// </summary>
private double[] f;
/// <summary>
/// Auxiliary buffer variable
/// </summary>
private double[,] k;
/// <summary>
/// Singleton
/// </summary>
static public readonly RungeProcessor Processor = new RungeProcessor();
protected RungeProcessor()
{
}
/// <summary>
/// Performs step of integration
/// </summary>
/// <param name="t0">Step start</param>
/// <param name="t2">Step finish</param>
public override void Step(double t0, double t1)
{
isBusy = true;
if (Dim == 0)
{
return;
}
double dt = t1 - t0;
int i = 0;
foreach (IMeasurements m in equations)
{
for (int j = 0; j < m.Count; j++)
{
w[i] = (double)m[j].Parameter();
f[i] = w[i];
++i;
}
}
double t = t0;
DataPerformerStrategy.Object.Time = t;
UpdateMeasurements();
Reset();
i = 0;
foreach (IMeasurements m in equations)
{
IDifferentialEquationSolver s = m as IDifferentialEquationSolver;
s.CalculateDerivations();
for (int j = 0; j < m.Count; j++)
{
IDerivation der = m[j] as IDerivation;
z[i] = der.Derivation;
k[0, i] = z[i] * dt;
w[i] = f[i] + 0.5 * k[0, i];
++i;
}
s.SetVariables(i - m.Count, w);
}
t = t0 + 0.5 * dt;
DataPerformerStrategy.Object.Time = t;
UpdateMeasurements();
Reset();
i = 0;
foreach (IMeasurements m in equations)
{
IDifferentialEquationSolver s = m as IDifferentialEquationSolver;
s.CalculateDerivations();
for (int j = 0; j < m.Count; j++)
{
IDerivation der = m[j] as IDerivation;
z[i] = der.Derivation;
k[1, i] = z[i] * dt;
w[i] = f[i] + 0.5 * k[1, i];
++i;
}
s.SetVariables(i - m.Count, w);
}
t = t0 + 0.5 * dt;
DataPerformerStrategy.Object.Time = t;
UpdateMeasurements();
Reset();
i = 0;
foreach (IMeasurements m in equations)
{
IDifferentialEquationSolver s = m as IDifferentialEquationSolver;
s.CalculateDerivations();
for (int j = 0; j < m.Count; j++)
{
IDerivation der = m[j] as IDerivation;
z[i] = der.Derivation;
k[2, i] = z[i] * dt;
w[i] = f[i] + k[2, i];
++i;
}
s.SetVariables(i - m.Count, w);
}
t = t0 + dt;
DataPerformerStrategy.Object.Time = t;
UpdateMeasurements();
Reset();
i = 0;
foreach (IMeasurements m in equations)
{
IDifferentialEquationSolver s = m as IDifferentialEquationSolver;
s.CalculateDerivations();
for (int j = 0; j < m.Count; j++)
{
IDerivation der = m[j] as IDerivation;
z[i] = der.Derivation;
k[3, i] = z[i] * dt;
++i;
}
}
i = 0;
foreach (IMeasurements m in equations)
{
IDifferentialEquationSolver s = m as IDifferentialEquationSolver;
for (int j = 0; j < m.Count; j++)
{
f[i] += (k[0, i] + 2 * k[1, i] + 2 * k[2, i] + k[3, i]) / 6;
++i;
}
s.SetVariables(i - m.Count, f);
}
isBusy = false;
}
/// <summary>
/// Sets root data consumers
/// </summary>
/// <param name="consumers">Consumers to set</param>
public override void Set(ArrayList consumers)
{
base.Set(consumers);
int n = Dim;
w = new double[n];
z = new double[n];
f = new double[n];
k = new double[4, n];
}
}
public class EulerProcessor: DifferentialEquationProcessor
{
/// <summary>
/// Singleton
/// </summary>
static public readonly DifferentialEquationProcessor Processor = new EulerProcessor();
/// <summary>
/// Auxiliary variable
/// </summary>
private double[] w;
/// <summary>
/// Constructor
/// </summary>
private EulerProcessor()
{
}
/// <summary>
/// Performs step of integration
/// </summary>
/// <param name="t0">Step start</param>
/// <param name="t2">Step finish</param>
public override void Step(double t0, double t1)
{
isBusy = true;
if (Dim == 0)
{
return;
}
double dt = t1 - t0;
int i = 0;
double t = t0;
foreach (IMeasurements m in equations)
{
for (int j = 0; j < m.Count; j++)
{
w[i] = (double)m[j].Parameter();
++i;
}
}
DataPerformerStrategy.Object.Time = t;
DataConsumer.ResetUpdatedMeasurements(DataConsumer.Desktop);
UpdateMeasurements();
i = 0;
foreach (IMeasurements m in equations)
{
IDifferentialEquationSolver s = m as IDifferentialEquationSolver;
s.CalculateDerivations();
for (int j = 0; j < m.Count; j++)
{
IDerivation der = m[j] as IDerivation;
w[i] = w[i] + der.Derivation * dt;
++i;
}
s.SetVariables(i - m.Count, w);
}
isBusy = false;
}
/// <summary>
/// Sets root data consumers
/// </summary>
/// <param name="consumers">Consumers to set</param>
public override void Set(ArrayList consumers)
{
base.Set(consumers);
int n = Dim;
w = new double[n];
}
}
//Finished code!!! But it don't working right.
public class AdamsProcessor: DifferentialEquationProcessor
{
/// <summary>
/// Values of previous steps
/// </summary>
private double[,] prevDeri;
/// <summary>
/// Values of parameters in previous ptep
/// </summary>
private double[] prevStep;
/// <summary>
/// Values of old step
/// </summary>
private double[] oldStep;
/// <summary>
/// Counter of steps
/// </summary>
private int stepCount;
/// <summary>
/// Counter of parameters in equations
/// </summary>
private int paramCount;
/// <summary>
/// Additional Runge - Kutta processor
/// </summary>
private RungeProcessor runge = RungeProcessor.Processor;
/// <summary>
/// Singleton
/// </summary>
static public readonly AdamsProcessor Processor = new AdamsProcessor();
/// <summary>
/// The massive of coefficients
/// </summary>
private double[] prCoeff;
/// <summary>
/// Accurate coefficient
/// </summary>
private double[] aqCoeff;
/// <summary>
/// The order of precision
/// </summary>
private int order;
protected AdamsProcessor()
{
}
/// <summary>
/// Order
/// </summary>
public int Order
{
set
{
order = value;
}
}
public override void Set(ArrayList consumers)
{
base.Set(consumers);
int n = Dim;
stepCount = 0;
prevStep = new double[n];
oldStep = new Double[n];
prevDeri = new double[n, order];
prCoeff = new double[order];
aqCoeff = new Double[order];
RealPolynom pNom = new RealPolynom(1);
RealPolynom mult = new RealPolynom(2);
mult[0] = 0;
mult[1] = 1;
for (int i = 0; i < order; i++)
{
pNom = new RealPolynom(1);
pNom[0] = 1;
for (int j = 0; j < order; j++)
{
if (i != j)
{
mult[0] = j;
pNom *= mult / (j - i);
}
}
pNom = ~pNom;
prCoeff[i] = pNom[(double)(1)];
aqCoeff[i] = - pNom[(double)(-1)];
}
runge.Set(consumers);
}
public override void Step(double t0, double t1)
{
isBusy = true;
paramCount = 0;
if (stepCount < order)
{
runge.Step(t0, t1);
foreach (IMeasurements m in equations)
{
runge.Step(t0, t1);
IDifferentialEquationSolver s = m as IDifferentialEquationSolver;
s.CalculateDerivations();
for (int j = 0; j < m.Count; j++)
{
IDerivation der = m[j] as IDerivation;
prevDeri[paramCount, stepCount] = der.Derivation;
prevStep[paramCount] = (double)m[j].Parameter();
++paramCount;
}
s.SetVariables(paramCount - m.Count, prevStep);
++stepCount;
}
paramCount = 0;
}
else
{
foreach (IMeasurements m in equations)
{
IDifferentialEquationSolver s = m as IDifferentialEquationSolver;
s.CalculateDerivations();
for (int j = 0; j < m.Count; j++)
{
prevStep[paramCount] = (double)m[j].Parameter();
oldStep[paramCount] = prevStep[paramCount];
for (int i = 0; i < order; i++)
{
prevStep[paramCount] += prevDeri[paramCount, i] * prCoeff[i] * (t1 - t0);
}
++paramCount;
}
s.SetVariables(paramCount - m.Count, prevStep);
}
paramCount = 0;
foreach (IMeasurements m in equations)
{
for (int j = 0; j < m.Count; j++)
{
for (int i = 0; i < order - 1; i++)
{
prevDeri[paramCount, i] = prevDeri[paramCount, i + 1];
}
++paramCount;
}
}
paramCount = 0;
foreach (IMeasurements m in equations)
{
IDifferentialEquationSolver s = m as IDifferentialEquationSolver;
s.CalculateDerivations();
for(int j = 0; j < m.Count; j++)
{
IDerivation der = m[j] as IDerivation;
prevDeri[paramCount, order - 1] = der.Derivation;
++paramCount;
}
}
paramCount = 0;
foreach (IMeasurements m in equations)
{
IDifferentialEquationSolver s = m as IDifferentialEquationSolver;
for (int j = 0; j < m.Count; j++)
{
prevStep[paramCount] = oldStep[paramCount];
for (int i = 0; i < order; i++)
{
prevStep[paramCount] += prevDeri[paramCount, i] * aqCoeff[i] * (t1 - t0);
}
++paramCount;
}
s.SetVariables(paramCount - m.Count, prevStep);
}
++stepCount;
}
isBusy = false;
}
}
[Serializable()]
public class TimeProvider : IDataConsumer, IMeasurements, ISerializable, ICategoryObject, IAlias,
IPostSetArrow
{
/// <summary>
/// The singleton
/// </summary>
public static readonly TimeProvider Singleton = new TimeProvider();
private List<IMeasurements> measurementsData = new List<IMeasurements>();
private string formulaString;
private MathFormula formula;
/// <summary>
/// Trees
/// </summary>
private ObjectFormulaTree tree;
/// <summary>
/// Formula arguments
/// </summary>
private ElementaryObjectArgument arg;
/// <summary>
/// Input parameter
/// </summary>
private DynamicalParameter par;
/// <summary>
/// Input arguments
/// </summary>
private ArrayList arguments = new ArrayList();
/// <summary>
/// All variables
/// </summary>
private string allVariables;
/// <summary>
/// Parameters
/// </summary>
private Hashtable parameters = new Hashtable();
/// <summary>
/// Derivation trees
/// </summary>
//private Hashtable derivations;
/// <summary>
/// External unaries
/// </summary>
private ArrayList unary = new ArrayList();
/// <summary>
/// Names of unaries
/// </summary>
private Hashtable unaryNames = new Hashtable();
/// <summary>
/// The "is serialized" sign
/// </summary>
private bool isSerialized = false;
/// <summary>
/// Comments
/// </summary>
protected ArrayList comments = new ArrayList();
private object obj;
bool isActive = true;
bool isUpdated;
private TimeProvider()
{
}
/// <summary>
/// Create aliases
/// </summary>
/// <param name="str">String of aliases</param>
public void CreateAliases(string str)
{
parameters.Clear();
foreach (char c in str)
{
double a = 0;
parameters["" + c] = a;
}
}
#region ISerializable Members
public TimeProvider(SerializationInfo info, StreamingContext context)
{
try
{
formulaString = (string)info.GetValue("Formulas", typeof(string));
isSerialized = true;
arguments = (ArrayList)info.GetValue("Arguments", typeof(ArrayList));
parameters = (Hashtable)info.GetValue("Parameters", typeof(Hashtable));
unaryNames = (Hashtable)info.GetValue("Unaries", typeof(Hashtable));
comments = (ArrayList)info.GetValue("Comments", typeof(ArrayList));
}
catch (Exception)
{
}
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Formulas", formulaString);
info.AddValue("Arguments", arguments);
info.AddValue("Parameters", parameters);
info.AddValue("Unaries", unaryNames);
info.AddValue("Comments", comments);
}
#endregion
#region IDataConsumer Members
public void Add(IMeasurements arrow)
{
measurementsData.Add(arrow);
}
public void Remove(IMeasurements arrow)
{
measurementsData.Remove(arrow);
}
public void UpdateChildrenData()
{
try
{
foreach (IMeasurements link in measurementsData)
{
link.UpdateMeasurements();
}
}
catch (Exception e)
{
PureDesktop.ThrowException(this, e);
}
}
public int Count
{
get
{
return measurementsData.Count;
}
}
IMeasurements IDataConsumer.this[int n]
{
get
{
return measurementsData[n];
}
}
public void Reset()
{
DataConsumer.Reset(this);
}
#endregion
#region IMeasurements Members
IMeasure IMeasurements.this[int n]
{
get
{
return DataConsumer.TimeMeasure;
}
}
public void UpdateMeasurements()
{
if (!isActive)
{
return;
}
if (IsUpdated)
{
return;
}
try
{
if (par == null)
{
throw new Exception(DynamicalParameter.UndefinedParameters);
}
if (tree == null)
{
throw new Exception("Formula are not accepted");
}
UpdateChildrenData();
par.Set(arg);
DataPerformerStrategy.Object.Time = ElementaryIntegerOperation.ToDouble(tree.Result);
isUpdated = true;
}
catch (Exception e)
{
PureDesktop.ThrowException(this, e);
}
}
public string SourceName
{
get
{
return "Timer";
}
}
public bool IsUpdated
{
get
{
return isUpdated;
}
set
{
isUpdated = value;
}
}
#endregion
public bool IsActive
{
get
{
return isActive;
}
set
{
isActive = value;
}
}
#region ICategoryObject Members
public ICategory Category
{
get
{
// TODO: Add TimeProvider.Category getter implementation
return null;
}
}
public ICategoryArrow Id
{
get
{
// TODO: Add TimeProvider.Id getter implementation
return null;
}
}
#endregion
#region IAssociatedObject Members
public object Object
{
get
{
return obj;
}
set
{
obj = value;
}
}
#endregion
#region IAlias Members
public List<string> AliasNames
{
get
{
List<string> s = new List<string>();
foreach (string str in parameters.Keys)
{
s.Add(str);
}
return s;
}
}
object DiagramUI.IAlias.this[string alias]
{
get
{
return parameters[alias];
}
set
{
char c = alias[0];
double a = (double)value;
arg[c] = a;
parameters[alias] = a;
DataPerformerStrategy.Object.Time = ElementaryIntegerOperation.ToDouble(tree.Result);
}
}
public object GetType(int n)
{
Double a = 0;
return a;
}
#endregion
/// <summary>
/// The operation that performs after arrows setting
/// </summary>
public void PostSetArrow()
{
DynamicalParameter parameter = new DynamicalParameter();
foreach (IMeasurements measurements in measurementsData)
{
IAssociatedObject cont = measurements as IAssociatedObject;
INamedComponent nc = cont.Object as INamedComponent;
string name = nc.Name;
for (int i = 0; i < measurements.Count; i++)
{
IMeasure measure = measurements[i];
string p = name + "." + measure.Name;
foreach (string s in arguments)
{
if (s.Substring(4).Equals(p))
{
char c = s[0];
parameter.Add(c, measure);
}
}
}
}
foreach (string s in arguments)
{
if (s.Substring(4).Equals("Time"))
{
parameter.Add(s[0], DataConsumer.TimeMeasure);
}
}
Parameter = parameter;
string argStr = AllVariables;
foreach (string key in parameters.Keys)
{
arg[key[0]] = parameters[key];
}
postSetUnary();
}
/// <summary>
/// Comments
/// </summary>
public ArrayList Comments
{
get
{
return comments;
}
set
{
comments = value;
}
}
/// <summary>
/// String representation of formula
/// </summary>
public string Formula
{
get
{
return formulaString;
}
set
{
formulaString = value;
}
}
/// <summary>
/// Accepts formulas
/// </summary>
public void AcceptFormulas()
{
try
{
parameters.Clear();
arguments.Clear();
par = null;
formula = MathFormula.FromString(MathSymbolFactory.Sizes, formulaString);
allVariables = ElementaryObjectDetector.GetVariables(formula);
}
catch (Exception e)
{
PureDesktop.ThrowException(this, e);
}
}
/// <summary>
/// Variables
/// </summary>
public string Variables
{
get
{
try
{
string s = "";
string str = ElementaryObjectDetector.GetVariables(formula);
foreach (char c in str)
{
if (!parameters.ContainsKey("" + c) & s.IndexOf(c) < 0)
{
s += c;
}
}
return s;
}
catch (Exception)
{
}
return "";
}
}
/// <summary>
/// Arguments of this object
/// </summary>
public ArrayList Arguments
{
get
{
return arguments;
}
set
{
string str = Variables;
bool b = false;
foreach (char c in str)
{
foreach (string s in value)
{
if (s[0] == c)
{
goto m;
}
}
throw new Exception(VectorFormulaConsumer.VariablesShortage);
m:
b = b;
}
arguments = value;
}
}
/// <summary>
/// All formulas variables
/// </summary>
public string AllVariables
{
get
{
try
{
if (allVariables == null)
{
formula = MathFormula.FromString(MathSymbolFactory.Sizes, formulaString);
allVariables = ElementaryObjectDetector.GetVariables(formula);
}
return allVariables;
}
catch (Exception)
{
}
return "";
}
}
/// <summary>
/// Adds unary source
/// </summary>
/// <param name="u">The source to add</param>
public void AddUnary(IUnary u)
{
unary.Add(u);
}
/// <summary>
/// Count of external unaries
/// </summary>
public int UnaryCount
{
get
{
return unary.Count;
}
}
/// <summary>
/// Gets i - th external unary
/// </summary>
/// <param name="i">The index of unary</param>
/// <returns>The i - th unary</returns>
public IUnary GetUnary(int i)
{
return unary[i] as IUnary;
}
/// <summary>
/// Table of unaries
/// </summary>
public Hashtable UnaryTable
{
set
{
setUnaryNames(value);
setUnaryTrees(value);
}
get
{
if (tree != null)
{
return ElementaryUnaryOperation.GetUnaryTable(tree);
}
return new Hashtable();
}
}
/// <summary>
/// Names of external unatries
/// </summary>
public Hashtable UnaryNames
{
get
{
return unaryNames;
}
}
/// <summary>
/// Removes unary source
/// </summary>
/// <param name="u">The source to add</param>
public void RemoveUnary(IUnary u)
{
unary.Remove(u);
}
/// <summary>
/// List of outside unary functions
/// </summary>
public ArrayList UnaryList
{
get
{
return ElementaryUnaryOperation.GetUnaryIndexes(tree);
}
}
/// <summary>
/// Input parameters
/// </summary>
public string InputParameters
{
get
{
string var = Variables;
string s = "";
foreach (char c in var)
{
if (parameters.ContainsKey("" + c))
{
continue;
}
s += c;
}
return s;
}
}
/// <summary>
/// The input dynamical parameter
/// </summary>
public DynamicalParameter Parameter
{
set
{
par = value;
if (!isSerialized)
{
arguments.Clear();
}
isSerialized = false;
Hashtable table = new Hashtable();
string var = par.Variables;
Double a = 0;
if (allVariables == null)
{
allVariables = AllVariables;
}
foreach (char c in allVariables)
{
table[c] = a;
}
foreach (char c in var)
{
IMeasure m = par[c];
table[c] = m.Type;
}
IFormulaObjectCreator creator = new FormulaArrayObjectCreator(
new ElementaryObjectsCreator(table));
MathFormula f = formula.FullTransform;
tree = new ObjectFormulaTree(f, creator);
arg = new ElementaryObjectArgument();
arg.Add(tree);
string str = par.Variables;
Hashtable unaryTable = ElementaryUnaryOperation.GetUnaryTable(tree);
}
}
private void setUnaryNames(Hashtable table)
{
unaryNames.Clear();
foreach (int i in table.Keys)
{
ICategoryObject o = table[i] as ICategoryObject;
//IObjectLabel l = o.Object as IObjectLabel;
unaryNames[i] = PureDesktop.GetRelativeName(this, o);//l.Name;
}
}
private void setUnaryTrees(Hashtable table)
{
string str = Variables;
ElementaryUnaryOperation.SetUnary(tree, table);
}
private void postSetUnary()
{
Hashtable t = new Hashtable();
foreach (ICategoryObject o in unary)
{
//IObjectLabel l = o.Object as IObjectLabel;
string name = PureDesktop.GetRelativeName(this, o);//l.Name;
if (!unaryNames.ContainsValue(name))
{
continue;
}
foreach (int i in unaryNames.Keys)
{
if (name.Equals(unaryNames[i]))
{
t[i] = o;
break;
}
}
}
setUnaryTrees(t);
}
}
/// <summary>
/// Solver of differential equations system
/// </summary>
public interface IDifferentialEquationSolver : IMeasurements
{
/// <summary>
/// Calculates derivations
/// </summary>
void CalculateDerivations();
/// <summary>
/// Sets variables to array
/// </summary>
/// <param name="b">Offset</param>
/// <param name="x">The array</param>
void SetVariables(int b, double[] x);
}
/// <summary>
/// The parametrized series
/// </summary>
public class ParametrizedSeries : Series
{
protected MeasureParameter x;
protected MeasureParameter y;
public ParametrizedSeries(MeasureParameter x, MeasureParameter y)
{
this.x = x;
this.y = y;
}
public virtual void Step()
{
AddXY(ElementaryIntegerOperation.ToDouble(x()), ElementaryIntegerOperation.ToDouble(y()));
}
}
public interface IDataPerformerStrategy
{
/// <summary>
/// Updates all components
/// </summary>
/// <param name="d">Desktop</param>
void UpdateAll(IDesktop d);
/// <summary>
/// Starts all components
/// </summary>
/// <param name="d">Desktop</param>
void StartAll(IDesktop d);
/// <summary>
/// Preparation
/// </summary>
/// <param name="d">Desktop</param>
void PrepareAll(IDesktop d);
/// <summary>
/// Clears all components
/// </summary>
void ClearAll();
/// <summary>
/// Time
/// </summary>
double Time
{
get;
set;
}
}
public class DataPerformerStrategy : IDataPerformerStrategy, IStep
{
protected ArrayList components = new ArrayList();
protected ArrayList objects = new ArrayList();
protected ArrayList arrows = new ArrayList();
protected ArrayList updatable = new ArrayList();
protected int step;
protected ArrayList dynamical = new ArrayList();
protected ArrayList measurements = new ArrayList();
protected double time;
static private DataPerformerStrategy strategy;
public DataPerformerStrategy()
{
}
#region IDataPerformerStrategy Members
/// <summary>
/// Updates all elements
/// </summary>
public virtual void UpdateAll(IDesktop d)
{
foreach (IUpdatableObject up in updatable)
{
up.UpdateObject();
}
}
/// <summary>
/// Starts all desktop elements
/// </summary>
public virtual void StartAll(IDesktop d)
{
ICollection components = d.AllComponents;
foreach (INamedComponent c in components)
{
if (c is IObjectLabel)
{
IObjectLabel l = c as IObjectLabel;
if (!(l.Object is IStarted))
{
continue;
}
IStarted s = l.Object as IStarted;
s.Start();
continue;
}
if (c is IArrowLabel)
{
IArrowLabel l = c as IArrowLabel;
if (!(l.Arrow is IStarted))
{
continue;
}
IStarted s = l.Arrow as IStarted;
s.Start();
continue;
}
}
}
public virtual void PrepareAll(IDesktop d)
{
ClearAll();
prepareAll(d);
updatable.Clear();
foreach (INamedComponent c in components)
{
object o = null;
if (c is IObjectLabel)
{
IObjectLabel l = c as IObjectLabel;
o = l.Object;
}
else if (c is IArrowLabel)
{
IArrowLabel l = c as IArrowLabel;
o = l.Arrow;
}
if (o == null)
{
continue;
}
if (o is IDynamical)
{
continue;
}
if (!(o is IUpdatableObject))
{
continue;
}
IUpdatableObject up = o as IUpdatableObject;
if (up.ShouldUpdate)
{
updatable.Add(up);
}
}
foreach (INamedComponent comp in components)
{
IDynamical dyn = null;
if (comp is IObjectLabel)
{
IObjectLabel label = comp as IObjectLabel;
ICategoryObject obj = label.Object;
if (!(obj is IDynamical))
{
continue;
}
dyn = obj as IDynamical;
}
else if (comp is IArrowLabel)
{
IArrowLabel label = comp as IArrowLabel;
ICategoryArrow arr = label.Arrow;
if (!(arr is IDynamical))
{
continue;
}
dyn = arr as IDynamical;
}
dynamical.Add(dyn);
}
foreach (INamedComponent comp in components)
{
if (!(comp is IObjectLabel))
{
continue;
}
IObjectLabel l = comp as IObjectLabel;
object ob = l.Object;
if (!(ob is IMeasurements))
{
continue;
}
IMeasurements m = ob as IMeasurements;
measurements.Add(m);
}
}
/// <summary>
/// Clears all components
/// </summary>
public void ClearAll()
{
if (components != null)
{
components.Clear();
}
if (objects != null)
{
objects.Clear();
}
if (arrows != null)
{
arrows.Clear();
}
updatable.Clear();
dynamical.Clear();
measurements.Clear();
GC.Collect();
}
public double Time
{
get
{
return time;
}
set
{
time = value;
foreach (IDynamical dyn in dynamical)
{
dyn.Time = value;
}
UpdateAll(null);
ResetUpdatedMeasurements();
}
}
#endregion
#region IStep Members
public int Step
{
get
{
return step;
}
set
{
step = value;
foreach (object c in components)
{
object o = null;
if (c is IObjectLabel)
{
IObjectLabel l = c as IObjectLabel;
o = l.Object;
}
if (c is IArrowLabel)
{
IArrowLabel l = c as IArrowLabel;
o = l.Arrow;
}
if (!(o is IStep))
{
continue;
}
IStep s = o as IStep;
s.Step = value;
}
}
}
public void ResetUpdatedMeasurements()
{
foreach (IMeasurements m in measurements)
{
m.IsUpdated = false;
}
}
#endregion
#region Specific Members
public static DataPerformerStrategy Object
{
get
{
return strategy;
}
set
{
strategy = value;
}
}
public ICollection Components
{
get
{
return components;
}
}
private void prepareAll(IDesktop d)
{
ICollection comps = d.Components;
foreach (INamedComponent c in comps)
{
components.Add(c);
if (c is IArrowLabel)
{
arrows.Add(c);
continue;
}
if (!(c is IObjectLabel))
{
continue;
}
objects.Add(c);
IObjectLabel l = c as IObjectLabel;
if (l.Object is ObjectContainer)
{
ObjectContainer cont = l.Object as ObjectContainer;
prepareAll(cont.Desktop);
}
}
}
#endregion
}
public class ArraySelectionCollection : IStructuredSelectionCollection, IMeasurements
{
#region Fields
private ArraySelection[] selections;
#endregion
#region Constructors
protected ArraySelectionCollection()
{
}
#endregion
#region IStructuredSelectionCollection Members
int IStructuredSelectionCollection.Count
{
get
{
return selections.Length;
}
}
IStructuredSelection IStructuredSelectionCollection.this[int i]
{
get
{
return selections[i];
}
}
#endregion
#region IMeasurements Members
int IMeasurements.Count
{
get
{
return selections.Length;
}
}
IMeasure IMeasurements.this[int n]
{
get
{
return selections[n];
}
}
public void UpdateMeasurements()
{
}
public string SourceName
{
get
{
return "";
}
}
public bool IsUpdated
{
get
{
return true;
}
set
{
}
}
#endregion
#region Specific Members
protected void Set(string[] names, double[][] data)
{
if (names.Length != data.Length)
{
throw new Exception("Names length does not coincides with data length");
}
selections = new ArraySelection[names.Length];
for (int i = 0; i < selections.Length; i++)
{
selections[i] = new ArraySelection(names[i], data[i]);
}
}
#endregion
}
/// <summary>
/// Scale selector
/// </summary>
public interface IScaleSelector
{
/// <summary>
/// Selects scale
/// </summary>
/// <param name="scale">Scale</param>
/// <returns>Selected scale</returns>
double SelectScale(double scale);
}
/// <summary>
/// Power scale selector
/// </summary>
public class PowerScaleSelector : IScaleSelector
{
#region Fields
double begin;
double pow;
double[] scales;
#endregion
#region Constructors
public PowerScaleSelector(double begin, double pow, double[] scales)
{
this.begin = begin;
this.pow = pow;
this.scales = scales;
}
#endregion
#region IScaleSelector Members
public double SelectScale(double scale)
{
double log = Math.Floor(Math.Log(scale / (begin * scales[0])) / Math.Log(pow));
double b = begin * Math.Exp(log * Math.Log(pow));
for (int i = 0; i < scales.Length; i++)
{
if (b * scales[i] > scale)
{
return b * scales[i];
}
}
return 1;
}
#endregion
}
/// <summary>
/// Histogram
/// </summary>
public class Histogram
{
/// <summary>
/// Gets histogram
/// </summary>
/// <param name="selection">Selection</param>
/// <param name="scaleSelector">Scale selector</param>
/// <param name="prefferedSize">Preffered size</param>
/// <returns>The histogram</returns>
public static double[,] GetHistogram(double[] selection, IScaleSelector scaleSelector, int prefferedSize)
{
ArrayList l = new ArrayList(selection);
l.Sort();
double min = (double) l[0];
double max = (double) l[selection.Length - 1];
double a = (max - min) / (prefferedSize + 1);
double scale = a;
if (scaleSelector != null)
{
scale = scaleSelector.SelectScale(a);
}
int nmin = (int) (Math.Floor(min) / scale);
int nmax = (int) (Math.Ceiling(max) / scale);
int diapCount = nmax - nmin;
double[,] data = new double[diapCount, 2];
double current = (double) (nmin * scale);
int nSel = 0;
for (int i = 0; i < diapCount; i++)
{
data[i, 0] = current;
data[i, 1] = 0;
if (nSel < l.Count)
{
while (true)
{
double x = (double) l[nSel];
if (x > (current + scale))
{
break;
}
++data[i, 1];
++nSel;
if (nSel >= l.Count)
{
break;
}
}
}
current += scale;
}
return data;
}
}
}