Click here to Skip to main content
15,884,388 members
Articles / Desktop Programming / WPF

The Time Machine

Rate me:
Please Sign up or sign in to vote.
4.91/5 (13 votes)
9 May 2012CPOL6 min read 34K   1.2K   32  
Long time strategy of software design and development
using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Runtime.Serialization;

using CategoryTheory;

using DiagramUI;
using DiagramUI.Labels;
using DiagramUI.Interfaces;
using DiagramUI.Aliases;

using BaseTypes.Interfaces;

using DataPerformer.Interfaces;


using FormulaEditor;
using FormulaEditor.Interfaces;
using FormulaEditor.ProxyFormula;
using FormulaEditor.Symbols;


namespace DataPerformer
{
    /// <summary>
    /// Solver of ordinary differential equations system
    /// </summary>
    [Serializable()]
    public class DifferentialEquationSolver : DataConsumer, IDifferentialEquationSolver, ISerializable,
        IStarted, IAlias, ICheckCorrectness, ITimeMeasureConsumer, IVariableDetector,
        IDynamical, ITreeCollection, ITimeVariable, IStack, IPostSetArrow
    {

        #region Fields

        /// <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 Dictionary<char, VariableMeasure> parameters = new Dictionary<char, VariableMeasure>();

        /// <summary>
        /// Output parameters
        /// </summary>
        private Variable[] 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 Dictionary<Variable, AliasName> externalAliases = new Dictionary<Variable, AliasName>();

        /// <summary>
        /// List of variables
        /// </summary>
        private List<Variable> varlist = new List<Variable>();


        private List<string> variabelstr = new List<string>();


        /// <summary>
        /// The "is serialized" flag
        /// </summary>
        private bool isSerialized = false;

 
        /// <summary>
        /// Dictionary of acceptors
        /// </summary>
        private Dictionary<string, IOperationAcceptor> acc = new Dictionary<string, IOperationAcceptor>();

        /// <summary>
        /// Formula creator
        /// </summary>
        private IFormulaObjectCreator creator;

        /// <summary>
        /// Order of derivation
        /// </summary>
        private int deriOrder = 0;

        /// <summary>
        /// Start preparation
        /// </summary>
        private Action prepareStart;

        /// <summary>
        /// Update action
        /// </summary>
        private Action update;

        /// <summary>
        /// Measurements
        /// </summary>
        private List<FormulaMeasure> fm = new List<FormulaMeasure>();

        /// <summary>
        /// Time variable
        /// </summary>
        private VariableMeasure timeVariable;

        /// <summary>
        /// Orders of derivations
        /// </summary>
        private Dictionary<string, int> deriOrders = new Dictionary<string, int>();


        private double[] outputD;

        #endregion

        #region Constructors

        /// <summary>
        /// Consructor
        /// </summary>
        public DifferentialEquationSolver()
            : base(30)
        {
            init();
            vars = new Hashtable();
            pars = new Hashtable();
            aliases = new Hashtable();
            arguments = new ArrayList();

        }


        /// <summary>
        /// Deserialization constructor
        /// </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 = (byte[])info.GetValue("Comments", typeof(byte[]));
            }
            catch (Exception ex)
            {
                ex.ShowError(100);
            }
            try
            {
                deriOrder = (int)info.GetValue("DerivationOrder", typeof(int));
                deriOrders = info.GetValue("DerivationOrders", typeof(Dictionary<string, int>))
                    as Dictionary<string, int>;
            }
            catch (Exception exc)
            {
                exc.ShowError(10);
            }
        }

        #endregion

        #region Members

        /// <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);
            if (comments != null)
            {
                info.AddValue("Comments", comments);
            }
            info.AddValue("DerivationOrder", deriOrder);
            info.AddValue("DerivationOrders", deriOrders, typeof(Dictionary<string, int>));

        }


        /*	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>
        /// Copies variables from processor to solver 
        /// </summary>
        /// <param name="offset">Offset</param>
        /// <param name="variables">Vector of all desktop differential equations variables</param>
        public void CopyVariablesToSolver(int offset, double[] variables)
        {
            int i = offset;
            foreach (Variable v in output)
            {
                v.Value = variables[i];
                ++i;
            }
        }


        /// <summary>
        /// Comments
        /// </summary>
        public ArrayList Comments
        {
            get
            {
                return PureDesktopPeer.Deserialize(comments) as ArrayList;
            }
            set
            {
                comments = PureDesktopPeer.Serialize(value);
            }
        }


        /// <summary>
        /// The count of measurements
        /// </summary>
        int IMeasurements.Count
        {
            get
            {
                if (output == null)
                {
                    return 0;
                }
                return output.Length;
            }
        }

        int VariablesCount
        {
            get
            {
                IMeasurements m = this;
                return m.Count;
            }
        }


        /// <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();
                CalculateDerivations();
                isUpdated = true;
            }
            catch (Exception e)
            {
                e.ShowError(10);
                this.Throw(e);
            }
        }


        /// <summary>
        /// The time
        /// </summary>
        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)
            {
                e.ShowError(10);
                this.Throw(e);
            }
        }


        /// <summary>
        /// Accepts measurements
        /// </summary>
        private void acceptMeasurements()
        {
            timeVariable = null;
            DynamicalParameter parameter = new DynamicalParameter();
            parameters.Clear();
            foreach (IMeasurements measurements in measurementsData)
            {
                string name = this.GetMeasurementName(measurements);
                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);
                            VariableMeasure vm = VariableMeasure.Create(c, measure, this);
                            parameters[c] = vm;
                        }
                    }
                }
            }
            foreach (string s in arguments)
            {
                if (s.Substring(s.Length - 4).Equals("Time"))
                {
                   // parameter.Add(s[0], timeMeasure);
                    timeVariable = VariableMeasure.Create(s[0], DataPerformer.StaticExtensionDataPerformerBase.Factory.TimeProvider.TimeMeasure,
                        this);
                    parameters[s[0]] = timeVariable;
                }
            }
            foreach (char c in pars.Keys)
            {
                if (!parameters.ContainsKey(c))
                {
                    if (pars[c] != null)
                    {
                        this.Throw(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 = Object 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 + " : " + c);
                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(double time)
        {
            try
            {
                timeOld = time;
                foreach (Variable v in output)
                {
                    char c = v.Symbol;
                    object[] o = variables[c] as object[];
                    v.Value = (double)o[4];
                }
                prepareStart = delegate()
                {
                    UpdateChildrenData();

                    foreach (object[] o in variables.Values)
                    {
                        ObjectFormulaTree t = o[2] as ObjectFormulaTree;
                        object ob = t.Result;
                        DeltaFunction.Reset(t);
                    }
                    prepareStart = delegate()
                    {
                    };
                };
            }
            catch (Exception e)
            {
                e.ShowError(10);
                this.Throw(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, object 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>
        new public void Prepare()
        {

            //parameters.Clear();
            //string str = "";
            //            aliases.Clear();
            Double a = 0;
            string var = AllVariables;
            Hashtable table = new Hashtable();
            foreach (char c in var)
            {
                table[c] = a;
            }
            string proh = "\u03B4";
            foreach (char c in par.Variables)
            {
                IMeasure m = par[c];
                object t = m.Type;
                if (t is IOneVariableFunction)
                {
                    proh += c;
                    table[c] = m.Parameter();
                }
                else
                {
                    table[c] = t;
                }
            }
            ArrayList l = new ArrayList(variables.Keys);
            l.Sort();
            output = new Variable[l.Count];
            variabelstr.Clear();
            AssociatedAddition aa = new AssociatedAddition(this, null);
            for (int i = 0; i < l.Count; i++)
            {
                char c = (char)l[i];
                AddVariable(c, aa);
            }
            fm.Clear();
            for (int i = 0; i < l.Count; i++)
            {
                char c = (char)l[i];
                object[] o = variables[c] as object[];
                string st = o[0] as string;
                MathFormula f = MathFormula.FromString(MathSymbolFactory.Sizes, st);
                o[1] = f;
                ObjectFormulaTree t = ObjectFormulaTree.CreateTree(f.FullTransform(proh), creator);
                o[2] = t;
                string vn = c + "";
                Variable v = acc[vn] as Variable;
                output[i] = v;
                bool ne = deriOrder > 0;
                if (deriOrders.ContainsKey(vn))
                {
                    if (deriOrders[vn] > 0)
                    {
                        ne = true;
                    }
                }
                v.SetTree(t, ne, aa, fm);
            }
            SetDerivations();
        }

        /// <summary>
        /// Orders of derivations
        /// </summary>
        public Dictionary<string, int> DerivationOrders
        {
            get
            {
                return deriOrders;
            }
        }

        /// <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();
            acc.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)
        {
            VariableMeasure v = VariableMeasure.Create(c, m, this);
            parameters[c] = v;
            string s = m.Name;
            pars[c] = s;
        }


        /// <summary>
        /// String of constants names
        /// </summary>
        public string ConstantNames
        {
            get
            {
                string str = "";
                IList<string> l = AliasNames;
                foreach (string s in l)
                {
                    if (!vars.ContainsKey(s[0]))
                    {
                        str += s;
                    }
                }
                return str;
            }
        }

        /// <summary>
        /// Names of aliases
        /// </summary>
        public IList<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;
                aliases[alias] = value;
                if (variables.ContainsKey(c))
                {
                    SetValue(c, value);
                }
            }
        }

        /// <summary>
        /// Gets object type
        /// </summary>
        /// <param name="name">Object name</param>
        /// <returns>Returns type of alias object</returns>
        public object GetType(string name)
        {
            return AliasTypeDetector.Detector.DetectType(this[name]);
        }



        /// <summary>
        /// Clears set of variables
        /// </summary>
        public void ClearVariables()
        {
            variables.Clear();
            vars.Clear();
        }



        /// <summary>
        /// Performs operations after deserialization
        /// </summary>
        private void postDeserialize()
        {
            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 (char c in vars.Keys)
            {
                object[] o = vars[c] as object[];
                string st = o[0] as string;
                MathFormula f = MathFormula.FromString(MathSymbolFactory.Sizes, st);
                //o[1] = f;
                string s = ElementaryObjectDetector.GetVariables(f);
            }
            Double a = 0;
            varlist.Clear();
            // int i = 0;
            foreach (char c in variables.Keys)
            {
                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;
            }
            string proh = "\u03B4";
            foreach (char c in pars.Keys)
            {
                if (pars.ContainsKey(c))
                {
                    if (pars[c] != null)
                    {
                        VariableMeasure v = parameters[c];
                        IMeasure m = v.Measure;
                        object t = m.Type;
                        if (t is IOneVariableFunction)
                        {
                            proh += c;
                            table[c] = m.Parameter();
                        }
                        else
                        {
                            table[c] = t;
                        }
                        acc[c + ""] = VariableMeasure.Create(c + "", m, this);
                    }
                }
            }
            AssociatedAddition aa = new AssociatedAddition(this, null);
            foreach (string s in aliases.Keys)
            {
                if (variables.ContainsKey(s[0]))
                {
                    acc[s] = new Variable(s, aa);
                }
                else
                {
                    acc[s] = new AliasNameVariable(s, this, s);
                }
            }
            ArrayList l = new ArrayList(variables.Keys);
            l.Sort();
            output = new Variable[l.Count];
            for (int i = 0; i < l.Count; i++)
            {
                char c = (char)l[i];
                AddVariable(c, aa);
            }
            fm.Clear();
            for (int i = 0; i < l.Count; i++)
            {
                char c = (char)l[i];
                object[] o = variables[c] as object[];
                string st = o[0] as string;
                MathFormula f = MathFormula.FromString(MathSymbolFactory.Sizes, st);
                o[1] = f;
                ObjectFormulaTree t = ObjectFormulaTree.CreateTree(f.FullTransform(proh), creator);
                o[2] = t;
                string vn = c + "";
                Variable v = acc[vn] as Variable;
                output[i] = v;
                bool ne = deriOrder > 0;
                int dor = deriOrder;
                if (deriOrders.ContainsKey(vn))
                {
                    int dd = deriOrders[vn];
                    if (dd > dor)
                    {
                        dor = dd;
                    }
                    if (dor > 0)
                    {
                        ne = true;
                    }
                }
                v.SetTree(t, ne, aa, fm);
            }
            SetDerivations();
            try
            {
                ITreeCollectionProxy proxy = StaticPerformer.CreateProxy(this);
                update = proxy.Update;
                FormulaMeasure.Set(fm, proxy);
            }
            catch (Exception ex)
            {
                ex.ShowError(10);
            }
        }

        /// <summary>
        /// Calculates derivations
        /// </summary>
        public void CalculateDerivations()
        {
            try
            {
                foreach (Variable v in externalAliases.Keys)
                {
                    AliasName an = externalAliases[v];
                    IMeasure m = v;
                    an.SetValue(m.Parameter());
                }
                UpdateChildrenData();
                update();
            }
            catch (Exception e)
            {
                e.ShowError(10);
                this.Throw(e);
            }
        }

        /// <summary>
        /// Table of external aliases
        /// </summary>
        public Hashtable ExternalAliases
        {
            get
            {
                return aliasNames;
            }
            set
            {
                aliasNames = value;
                postSetAlias();
            }
        }

        /// <summary>
        /// Names of all aliases
        /// </summary>
        public override List<string> AllAliases
        {
            get
            {
                List<string> a = new List<string>();
                this.GetAliases(a, null);
                return a;
            }
        }

        /// <summary>
        /// Order of derivation
        /// </summary>
        public int DerivationOrder
        {
            get
            {
                return deriOrder;
            }
            set
            {
                deriOrder = value;
            }
        }


        /// <summary>
        /// Initialization
        /// </summary>
        private void init()
        {
            creator = VariableDetector.GetCreator(this);
            prepareStart = delegate()
            {
            };
            update = delegate()
            {
                foreach (Variable v in output)
                {
                    v.Update();
                }
            };

        }

        /// <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];
        }

        private IDistribution GetDistribution(char c)
        {
            object[] ob = variables[c] as object[];
            object o = ob[2];
            if (o == null)
            {
                return null;
            }
            ObjectFormulaTree t = o as ObjectFormulaTree;
            return DeltaFunction.GetDistribution(t);
        }



        private void postSetAlias()
        {
            externalAliases.Clear();
            if (aliasNames == null)
            {
                return;
            }
            foreach (char c in aliasNames.Keys)
            {
                string s = aliasNames[c] as string;
                Variable v = acc[c + ""] as Variable;
                externalAliases[v] = this.FindAliasName(s, false);
            }
        }


        private void SetDerivations()
        {
            bool next = true;
            //bool br = false;
            for (int j = 1; ; j++)
            {
                bool ret = j >= deriOrder - 1;
                if (j > (deriOrder - 1))
                {
                    next = false;
                }
                for (int k = 0; k < output.Length; k++)
                {
                    Variable lv = output[k];
                    string symb = lv.String;
                    bool ne = next;
                    bool cont = j < deriOrder;
                    if (!ne)
                    {
                        if (deriOrders.ContainsKey(symb))
                        {
                            int dor = deriOrders[symb];
                            if (j <= dor)
                            {
                                ret = false;
                                cont = true;
                                if (j < dor - 1)
                                {
                                    ret = false;
                                }
                                if (j < dor)
                                {
                                    ne = true;
                                }
                            }
                        }
                    }
                    if (cont)
                    {
                        lv.Iterate(ne);
                    }
                }
                if (ret)
                {
                    break;
                }

            }
        }

        private void AddVariable(char c, AssociatedAddition aa)
        {
            string str = c + "";
            Variable v = new Variable(str, aa);
            acc[str] = v;
            variabelstr.Add(str);
        }

        #endregion

        #region IVariableDetector Members

        IOperationAcceptor IVariableDetector.Detect(MathSymbol sym)
        {
            if (sym.SymbolType != (int)FormulaConstants.Variable)
            {
                return null;
            }
            string s = sym.Symbol + "";
            if (acc.ContainsKey(s))
            {
                return acc[s];
            }
            return null;
        }

        #endregion

        #region IDynamical Members

        double IDynamical.Time
        {
            set { prepareStart(); }
        }

        #endregion

        #region ITreeCollection Members

        ObjectFormulaTree[] ITreeCollection.Trees
        {
            get 
            {
                return FormulaMeasure.GetTrees(fm);
            }
        }

        #endregion

        #region ITimeVariable Members

        VariableMeasure ITimeVariable.Variable
        {
            get { return timeVariable; }
        }

        #endregion

        #region ITimeMeasureConsumer Members

        IMeasure ITimeMeasureConsumer.Time
        {
            get
            {
                return VariableMeasure.GetTimeMeasure(this);
            }
            set
            {
                VariableMeasure.Set(value, this);
            }
        }

        #endregion

        #region IStack Members

        void IStack.Push()
        {
            foreach (IStack s in output)
            {
                s.Push();
            }
        }

        void IStack.Pop()
        {
            foreach (IStack s in output)
            {
                s.Pop();
            }
        }

        #endregion
   
  
        #region Classes & Delegates

        class Variable : IObjectOperation, IPowered, IOperationAcceptor, IMeasure, IDerivation, IDerivationOperation, IStack
        {

            #region Fields

            private Stack<double> stack = new Stack<double>();

            const Double a = 0;

            double value;

            FormulaMeasure derivation;

            FormulaMeasureDerivation temp;

            ObjectFormulaTree tree;

            Func<object> par;


            private string symbol;

            protected AssociatedAddition addition;

            #endregion

            #region Ctor

            internal Variable(string symbol, AssociatedAddition addition)
            {
                this.symbol = symbol;
                par = GetValue;
                this.addition = addition;
            }



            #endregion

            #region IObjectOperation Members

            object[] IObjectOperation.InputTypes
            {
                get { return new object[0]; }
            }

            object IObjectOperation.this[object[] x]
            {
                get { return value; }
            }

            object IObjectOperation.ReturnType
            {
                get { return a; }
            }

            bool IPowered.IsPowered
            {
                get { return true; }
            }

            #endregion

            #region IOperationAcceptor Members

            IObjectOperation IOperationAcceptor.Accept(object type)
            {
                return this;
            }

            #endregion

            #region IDerivation Members

            IMeasure IDerivation.Derivation
            {
                get { return derivation; }
            }

            #endregion

            #region IDerivationOperation Members

            ObjectFormulaTree IDerivationOperation.Derivation(ObjectFormulaTree tree, string s)
            {
                if (s.Equals("d/dt"))
                {
                    return this.tree;
                }
                return null;
            }

            #endregion

            #region IMeasure Members

            Func<object> IMeasure.Parameter
            {
                get { return par; }
            }

            string IMeasure.Name
            {
                get { return symbol; }
            }

            object IMeasure.Type
            {
                get { return a; }
            }

            #endregion

            #region Members


            internal string String
            {
                get
                {
                    return symbol;
                }
            }

            internal void SetTree(ObjectFormulaTree tree,
                bool next,
                AssociatedAddition addition,
                IList<FormulaMeasure> list)
            {
                string dn = "D" + symbol;
                this.tree = tree;
                IDistribution d = DeltaFunction.GetDistribution(tree);
                if (next)
                {
                    if (d != null)
                    {
                        temp = new FormulaMeasureDerivationDistribution(tree, null, symbol, addition);
                    }
                    else
                    {
                        temp = new FormulaMeasureDerivation(tree, null, symbol, addition);
                    }
                    derivation = temp;
                    list.Add(derivation);
                    return;
                }
                if (d != null)
                {
                    derivation = new FormulaMeasureDistribution(tree, symbol, addition);
                }
                else
                {
                    derivation = new FormulaMeasure(tree, symbol, addition);
                }
                list.Add(derivation);
                return;
            }

            internal void Iterate(bool next)
            {
                AssociatedAddition aa = FormulaMeasureDerivation.Create(addition);
                temp = temp.Iterate(next, aa);
            }

            internal char Symbol
            {
                get
                {
                    return symbol[0];
                }
            }

            internal double Value
            {
                set
                {
                    this.value = value;
                }
            }

            internal void Update()
            {
                derivation.Update();
            }

            private object GetValue()
            {
                return value;
            }

            #endregion

            #region IStack Members

            void IStack.Push()
            {
                stack.Push(value);
            }

            void IStack.Pop()
            {
                value = stack.Pop();
            }

            #endregion
        }

        //delegate void PrepareStart();

        #endregion


  
        #region IStateDoubleVariables Members

        List<string> IStateDoubleVariables.Variables
        {
            get { return variabelstr; }
        }

        double[] IStateDoubleVariables.Vector
        {
            get
            {
                if (outputD == null)
                {
                    outputD = new double[output.Length];
                }
                else if (outputD.Length != output.Length)
                {
                    outputD = new double[outputD.Length];
                }
                int i = 0;
                foreach (IMeasure m in output)
                {
                    outputD[i] = (double)m.Parameter();
                    ++i;
                }
                return outputD;
            }
            set
            {
                int i = 0;
                foreach (Variable v in output)
                {
                    double x = value[i];
                    v.Value = x;
                    object[] o = variables[v.Symbol] as object[];
                    o[4] = x;
                    ++i;
                }
            }
        }


        void IStateDoubleVariables.Set(double[] input, int offset, int length)
        {
            int i = offset;
            foreach (Variable v in output)
            {
                double x = input[i];
                v.Value = x;
                object[] o = variables[v.Symbol] as object[];
                o[4] = x;
                ++i;
            }
        }

        #endregion
    }
}

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

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

License

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


Written By
Architect
Russian Federation Russian Federation
Ph. D. Petr Ivankov worked as scientific researcher at Russian Mission Control Centre since 1978 up to 2000. Now he is engaged by Aviation training simulators http://dinamika-avia.com/ . His additional interests are:

1) Noncommutative geometry

http://front.math.ucdavis.edu/author/P.Ivankov

2) Literary work (Russian only)

http://zhurnal.lib.ru/editors/3/3d_m/

3) Scientific articles
http://arxiv.org/find/all/1/au:+Ivankov_Petr/0/1/0/all/0/1

Comments and Discussions