Click here to Skip to main content
15,892,059 members
Articles / Programming Languages / C#

Universal Framework for Science and Engineering - Part 4: Space elevator

Rate me:
Please Sign up or sign in to vote.
4.56/5 (6 votes)
14 Aug 20066 min read 36.6K   2.2K   37  
An article on framework applications to the space elevator.
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace FormulaEditor
{
    /// <summary>
    /// Math formula
    /// </summary>
    [Serializable()]
    public class MathFormula : ICloneable, ISerializable
    {


        #region Fields
        /// <summary>
        /// Epsilon to round numbers
        /// </summary>
        private const double ROUND_EPS = 0.0000000001;

        /// <summary>
        /// Formatter
        /// </summary>
        static private readonly BinaryFormatter formatter = new BinaryFormatter();

        /// <summary>
        /// Separator
        /// </summary>
        static private readonly char[] byteSep = ";".ToCharArray();


        /// <summary>
        /// The vector of formula symbols
        /// </summary>
        private ArrayList symbols = new ArrayList();


        /// <summary>
        /// Temporary list of math symbol for serialization
        /// </summary>
        private List<MathSymbol> temp = null;

        /// <summary>
        /// The sizes of symbols
        /// </summary>
        protected int[] sizes;

        /// <summary>
        /// The formula level. Main formula has level = 0. 
        /// Its pow has level 1, etc.
        /// </summary>
        protected byte level;

        /// <summary>
        /// The value of the formula
        /// </summary>
        //private double doubleValue;


        /// <summary>
        /// Auxiliary variable
        /// </summary>
        protected MathFormula form;

        /// <summary>
        /// Auxiliary variables
        /// </summary>
        private MathSymbol s, s1;


        /// <summary>
        /// Formula resources
        /// </summary>
        protected static Hashtable resources;

        /// <summary>
        /// Formula resources
        /// </summary>
        protected static Hashtable errorResources;

        #endregion

        #region Constructors

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="level">the level of formula</param>
        public MathFormula(byte level)
        {
            this.level = level;
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="level">the level of formula</param>
        /// <param name="sizes">the symbols sizes</param>
        public MathFormula(byte level, int[] sizes)
            : this(level)
        {
            this.sizes = sizes;
        }

        /// <summary>
        /// Constructor that creates formula from string vector
        /// </summary>
        /// <param name="level"> the level of formula</param>
        /// <param name="sizes">the symbols sizes</param>
        /// <param name="v">the string vector</param>
        /// <param name="b">the formula string begin</param>
        /// <param name="e">the formula string end</param>
        public MathFormula(byte level, int[] sizes, ArrayList v, int b, int e)
            :
            this(level, sizes)
        {
            if (b >= e)
            {
                return;
            }
            for (int i = b; i < e; )
            {
                int j = MathSymbolFactory.Next(v, i);
                int k = (j == -1) ? e - 1 : j - 1;
                MathSymbol sym = MathSymbolFactory.CreateSymbol(this, v, i, k);
                if (j == -1)
                {
                    return;
                }
                i = j;
            }
        }

        public MathFormula(byte level, int[] sizes, string str, int b, int e,
            MathFormulaStringConverter convertor)
            :
            this(level, sizes)
        {
            if (b >= e)
            {
                return;
            }
            for (int i = b; i < e; )
            {
                int j = convertor.Next(str, i);
                int k = (j == -1) ? e - 2 : j - 1;
                if (i == k)
                {
                    return;
                }
                MathSymbol sym = convertor.CreateSymbol(this, str, i, k);
                if (j == -1)
                {
                    return;
                }
                i = j;
            }
        }

        public MathFormula(MathFormula formula, IMathSymbolConverter convertor)
            : this(formula.Level, formula.Sizes)
        {
            for (int i = 0; i < formula.Count; i++)
            {
                MathSymbol s = formula[i];
                MathSymbol sym = convertor.Convert(s);
                sym.Append(this);
                sym = Last;
                for (int j = 0; j < s.Count; j++)
                {
                    if (s[j] != null)
                    {
                        sym[j] = new MathFormula(s[j], convertor);
                    }
                }
            }
        }


        public MathFormula(SerializationInfo info, StreamingContext context)
        {
            temp = info.GetValue("Temp", typeof(List<MathSymbol>)) as List<MathSymbol>;
        }




        #endregion

        #region ISerializable Members

        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {
            temp = new List<MathSymbol>();
            foreach (MathSymbol s in symbols)
            {
                temp.Add(s);
            }
            info.AddValue("Temp", temp, typeof(List<MathSymbol>));
        }

       #endregion

        #region Members




        /// <summary>
        /// Post serialization method
        /// </summary>
        public virtual void Post()
        {
            foreach (MathSymbol symbol in temp)
            {
                symbol.Post();
                symbol.AppendWithChildren(this);
            }
            temp = null;
        }


        /// <summary>
        /// Formula resources
        /// </summary>
        public static Hashtable Resources
        {
            get
            {
                return resources;
            }
            set
            {
                resources = value;
            }
        }


        /// <summary>
        /// Formula error resources
        /// </summary>
        public static Hashtable ErrorResources
        {
            get
            {
                return errorResources;
            }
            set
            {
                errorResources = value;
            }
        }

        public static void ThrowErrorException(string s)
        {
            string str = s;
            /*
			if (errorResources != null)
			{
                str = errorResources.GetString(str);
                if (errorURLResources != null)
                {
                    //string hs = errorURLResources.GetString(s);
                    Exception e = new Exception(str);
                    //e.HelpLink = hs;
                    throw e;
                }
            }*/
            string h = null;
            try
            {
                h = errorResources[str] as string;
            }
            catch (Exception)
            {
            }
            //throw new FormulaException(str, h);
        }




        /// <summary>
        /// Creates formula from string
        /// </summary>
        /// <param name="sizes">The sizes</param>
        /// <param name="str">The string</param>
        /// <returns>The formula</returns>
        public static MathFormula FromString(int[] sizes, string str)
        {
            MathFormula f = null;
            try
            {
                //string[] s = str.Split(byteSep);
                byte[] b = new byte[str.Length];
                for (int i = 0; i < b.Length; i++)
                {
                    b[i] = (byte)(str[i]);
                }
                System.IO.MemoryStream stream = new System.IO.MemoryStream(b);
                MathFormula form = formatter.Deserialize(stream) as MathFormula;
                form.Post();
                form.Sizes = sizes;
                return form;
            }
            catch (Exception eee)
            {
                string sm = eee.StackTrace;
                sm = null;
            }
            try
            {
                f = new MathFormula(0, sizes, str, 0, str.Length,
                    ElementaryFormulaStringConverter.Object);
                new ObjectFormulaTree(f.FullTransform(null));
                return f;
            }
            catch (Exception)
            {
                ArrayList list = new ArrayList();
                for (int i = 0; i < str.Length; i++)
                {
                    char c = str[i];
                    byte[] b = new byte[] { (byte)c };
                    list.Add(b);
                }
                try
                {
                    MathFormula fo = new MathFormula(0, sizes, list, 0, str.Length);
                    //new ObjectFormulaTree(fo.FullTransform);
                    return fo;
                }
                catch (Exception)
                {
                }
            }
            return f;
        }

        /// <summary>
        /// Constructor of subformula 
        /// </summary>
        /// <param name="form">the initial formula</param>
        /// <param name="n1">the index of start symbol</param>
        /// <param name="n2">the index of finish symbol</param>
        public MathFormula(MathFormula form, int n1, int n2)
            : this(form.level, form.sizes)
        {
            for (int i = n1; i <= n2; i++)
            {
                Add(form[i]);
            }
        }

        /// <summary>
        /// sizes of formula symbols
        /// </summary>
        public int[] Sizes
        {
            get
            {
                return sizes;
            }
            set
            {
                sizes = value;
            }
        }


        /// <summary>
        /// Saves intself to stream
        /// </summary>
        /// <param name="stream">The Steam</param>
        public void Save(System.IO.Stream stream)
        {
            formatter.Serialize(stream, this);
        }

        /// <summary>
        /// Saves itself to stream
        /// </summary>
        /// <param name="filemame"></param>
        public void Save(string filemame)
        {
            System.IO.Stream stream = System.IO.File.Open(filemame, System.IO.FileMode.Create);
            Save(stream);
            stream.Close();
        }


        /// <summary>
        /// Transforms formula string to bytes
        /// </summary>
        /// <param name="str">The formula string</param>
        /// <returns>The bytes</returns>
        public static byte[] GetBytes(string str)
        {
            byte[] b = new byte[str.Length];
            for (int i = 0; i < b.Length; i++)
            {
                b[i] = (byte)str[i];
            }
            return b;
        }

        /// <summary>
        /// Thansforms bytes to formula string
        /// </summary>
        /// <param name="bytes">The bytes</param>
        /// <returns>The string</returns>
        public static string GetString(byte[] bytes)
        {
            string str = "";
            for (int i = 0; i < bytes.Length; i++)
            {
                str += (char)bytes[i];
            }
            return str;
        }


        /// <summary>
        /// The string representation of the formula
        /// </summary>
        public string FormulaString
        {
            get
            {
                try
                {
                    System.IO.MemoryStream stream = new System.IO.MemoryStream();
                    formatter.Serialize(stream, this);
                    byte[] bytes = stream.GetBuffer();
                    string s = "";
                    foreach (byte b in bytes)
                    {
                        s += (char)b;
                    }
                    return s;
                }
                catch (Exception eee)
                {
                    string s = eee.StackTrace;
                    s = "";
                }
                try
                {
                    return ElementaryFormulaStringConverter.Object.Convert(this);
                }
                catch (Exception)
                {
                    ArrayList list = ToArray();
                    string s = "";
                    for (int i = 0; i < list.Count; i++)
                    {
                        char c = (char)(((byte[])list[i])[0]);
                        s += c;
                    }
                    return s;
                }
            }
        }

        /// <summary>
        /// Clones itself
        /// </summary>
        /// <returns>The clone</returns>
        public object Clone()
        {
            return Copy();
        }

        /// <summary>
        /// Adds the symbol
        /// </summary>
        /// <param name="s">Symbol to add</param>
        public void Add(MathSymbol s)
        {
            symbols.Add(s);
        }

        /// <summary>
        /// Count of symbols
        /// </summary>
        public int Count
        {
            get
            {
                return symbols.Count;
            }
        }

        /// <summary>
        /// The n th symbol
        /// </summary>
        public MathSymbol this[int n]
        {
            get
            {
                return symbols[n] as MathSymbol;
            }
        }

        /// <summary>
        /// Index of symbol
        /// </summary>
        /// <param name="s">The symbol</param>
        /// <returns>The index</returns>
        public int IndexOf(MathSymbol s)
        {
            for (int i = 0; i < symbols.Count; i++)
            {
                if (symbols[i] == s)
                {
                    return i;
                }
            }
            return -1;
        }

        /// <summary>
        /// Deletes brackets
        /// </summary>
        /// <returns>this formula with deleted brackets</returns>
        public MathFormula DeleteBrackets()
        {
            if (Count == 0)
            {
                throw new Exception();
            }
            MathSymbol b = this[0];
            MathSymbol e = this[Count - 1];
            if (b == null)
            {
                return this;
            }
            if ((b.Symbol != '(') | (e.Symbol != ')'))
            {
                return this;
            }
            if (e.HasChildren)
            {
                return this;
            }
            int m = 0;
            for (int i = 0; i < Count - 1; i++)
            {
                MathSymbol x = this[i];
                char c = x.Symbol;
                if (c == '(')
                {
                    m++;
                }
                if (c == ')')
                {
                    m--;
                    if (m == 0)
                    {
                        return this;
                    }
                }
            }
            return (new MathFormula(this, 1, Count - 2)).DeleteBrackets();
        }

        /// <summary>
        /// the formula level
        /// </summary>
        public byte Level
        {
            get
            {
                return level;
            }
        }





        /// <summary>
        /// Convetrs the formula to byte array vector
        /// </summary>
        /// <returns>The vector</returns>
        public ArrayList ToArray()
        {
            ArrayList vec = new ArrayList();
            for (int i = 0; i < Count; i++)
            {
                ArrayList v = this[i].ToArray();
                for (int j = 0; j < v.Count; j++)
                {
                    vec.Add(v[j]);
                }
            }
            return vec;
        }






        /// <summary>
        /// Simplifyes the formula
        /// </summary>
        public void Simplify()
        {
            delZero();
            delMult();
            reverseNumber();
        }

        /// <summary>
        /// Contructor of formula that corresponds the double value
        /// </summary>
        /// <param name="level">the level</param>
        /// <param name="sizes">the array of different level symbols' sizes</param>
        /// <param name="a">the value</param>
        public MathFormula(byte level, int[] sizes, double a)
            : this(level, sizes)
        {
            MathSymbol s = new SimpleSymbol('?', (byte)FormulaConstants.Number, false);
            s.Append(this);
            First.DoubleValue = a;
        }


        /// <summary>
        /// Adds the formula to this formula
        /// </summary>
        /// <param name="formula">the formula to add</param>
        public void Add(MathFormula formula)
        {
            int n = formula.Count;
            for (int i = 0; i < n; i++)
            {
                if (formula[i].Children == null)
                {
                    formula[i].Append(this);
                }
                else
                {
                    symbols.Add(formula[i]);
                    formula[i].Parent = this;
                }
            }
        }

        /// <summary>
        /// Inserts symbol before n th symbol
        /// </summary>
        /// <param name="n">The n</param>
        /// <param name="s">The symbol</param>
        public void Insert(int n, MathSymbol s)
        {
            symbols.Insert(n, s);
        }

        /// <summary>
        /// Inserts object
        /// </summary>
        /// <param name="symbol">Symbol to insert</param>
        /// <returns>Inserted object</returns>
        public MathFormula InsertObject(MathSymbol symbol)
        {
            symbol.Append(this);
            MathSymbol s = this[Count - 1];
            if (s is BracketsSymbol)
            {
                return s[0];
            }
            return this;
        }


        /// <summary>
        /// The "is empty" indicator
        /// </summary>
        public bool IsEmpty
        {
            get
            {
                return Count == 0;
            }
        }

        /// <summary>
        /// Copies this formula
        /// </summary>
        /// <returns>the copy</returns>
        public virtual MathFormula Copy()
        {
            form = new MathFormula(level, sizes);
            for (int i = 0; i < Count; i++)
            {
                MathSymbol s = this[i].Copy();
                s.Parent = form;
                form.Add(s);
            }
            return form;
        }

        /// <summary>
        /// Removes a symbol from formula
        /// </summary>
        /// <param name="s">The symbol to remove</param>
        public void Remove(MathSymbol s)
        {
            symbols.Remove(s);
        }

        /// <summary>
        /// Full transformation
        /// </summary>
        public MathFormula FullTransform(string prohibited)
        {
                MathFormula f = Copy();
                zero();
                f.TranNumber();
                f.WrapFunctions();
                f.Wrap(prohibited);
                f.InsertMult(prohibited);
                StringDetector sDetector = new StringDetector(0x0, false, false);
                f = sDetector.Convert(f);
                return f;
        }

        /// <summary>
        /// Transforms numbers of the formula
        /// </summary>
        public void TranNumber()
        {
            s = First;
            if (s == null)
            {
                return;
            }
            do
            {
                if (s.Count > 0)
                {
                    for (int i = 0; i < s.Count; i++)
                    {
                        s[i].TranNumber();
                    }
                }
                s = s.TranNumber();
            }
            while (s != null);
        }

        /// <summary>
        /// Wrapping
        /// </summary>
        public void Wrap(string prohibited)
        {
            s = First;
            if (s == null)
            {
                return;
            }
            do
            {
                if (prohibited != null)
                {
                    if (prohibited.IndexOf(s.Symbol) >= 0)
                    {
                        s = s.Next;
                        continue;
                    }
                }
                s = s.Wrap(prohibited);
            }
            while (s != null);
        }

        /// <summary>
        /// Inserts multiplications
        /// </summary>
        public void InsertMult(string prohibited)
        {
            s = First;
            if (s == null)
            {
                return;
            }
            s1 = s.Next;
            while (s1 != null)
            {
                bool bo = ((s.Symbol == ')' | s is BracketsSymbol) &
                    ((s1.Symbol == '(' | s1 is BracketsSymbol) |
                    (s1.SymbolType == (byte)FormulaConstants.Unary | s1.SymbolType == (byte)FormulaConstants.Series) 
                    & s1.Symbol != ')'));
                if (prohibited != null)
                {
                    if (prohibited.IndexOf(s1.Symbol) >= 0)
                    {
                        bo = false;
                    }
                }
                if (bo)
                {
                    s.Append(new BinarySymbol('*'));
                }
                s = s1;
                s1 = s.Next;
            }
            s = First;
            do
            {
                if (s.HasChildren)
                {
                    for (int i = 0; i < s.Count; i++)
                    {
                        s[i].InsertMult(prohibited);
                    }
                }
                s = s.Next;
            }
            while (s != null);
        }

        /// <summary>
        /// Wraps elementary functions by brackets for further processing
        /// </summary>
        void WrapFunctions()
        {
            s = First;
            while (s != null)
            {
                if (s.HasChildren)
                {
                    for (int i = 0; i < s.Count; i++)
                    {
                        s[i].WrapFunctions();
                    }
                }
                if (s.SymbolType == (byte)FormulaConstants.Unary | s.SymbolType == (byte)FormulaConstants.Series)
                {
                    s1 = s.Next;
                    if (s1 == null)
                    {
                        return;
                    }
                    if (!s1.ShouldWrapped | s1 is BracketsSymbol)
                    {
                        s = s1;
                        continue;
                    }
                    s.Append(MathSymbol.Bra);
                    s1 = s.Next;
                    while (s1 != null)
                    {
                        bool b = false;
                        MathSymbol ss = s1.Next;
                        if (ss == null)
                        {
                            b = true;
                        }
                        else if (!ss.ShouldWrapped | s1 is BracketsSymbol)
                        {
                            b = true;
                        }
                        if (b)
                        {
                            s1.Append(MathSymbol.Ket);
                            s = s1.Next;
                            break;
                        }
                        MathSymbol s2 = s1;
                        s1 = s1.Next;
                        if (s1 == null)
                        {
                            s2.Append(MathSymbol.Ket);
                            break;
                        }
                    }
                }
                s = s.Next;
            }
        }

        /// <summary>
        /// Finds first symbol of the formula
        /// </summary>
        public MathSymbol First
        {
            get
            {
                if (Count == 0)
                {
                    return null;
                }
                return this[0];
            }
        }

        /// <summary>
        /// Finds last symbol of the formula
        /// </summary>
        public MathSymbol Last
        {
            get
            {
                if (Count == 0)
                {
                    return null;
                }
                return this[Count - 1];
            }

        }

        /// <summary>
        /// Checks whether the formula contains the symbol
        /// </summary>
        /// <param name="sym">sym the symbol</param>
        /// <returns>true if contains and false otherwise</returns>
        public bool Contains(MathSymbol sym)
        {
            if (symbols.Contains(sym))
            {
                return true;
            }
            s = First;
            while (s != null)
            {
                if (s.Contains(sym))
                {
                    s = null;
                    return true;
                }
                s = s.Next;
            }
            s = null;
            return false;
        }

        /// <summary>
        /// Resets auxiliary variables
        /// </summary>
        private void zero()
        {
            s = First;
            while (s != null)
            {
                if (s.HasChildren)
                {
                    for (int i = 0; i < s.Count; i++)
                    {
                        s[i].zero();
                    }
                }
                s = s.Next;
            }
            s = null;
            s1 = null;
            form = null;
        }


        /// <summary>
        /// Deletes zeros
        /// </summary>
        private void delZero()
        {
            MathSymbol s = First;
            if (s != null)
            {
                MathSymbol s1 = s.Next;
                if (s1 != null)
                {
                    if (s.SymbolType == (int)FormulaConstants.Number & s.DoubleValue == 0 & s.Symbol == '?' & s1.Symbol == '-')
                    {
                        s.Remove();
                    }
                }
            }
            s = First;
            while (s != null)
            {
                if (s.HasChildren)
                {
                    for (int i = 0; i < s.Count; i++)
                    {
                        s[i].delZero();
                    }
                }
                s = s.Next;
            }
        }


        /// <summary>
        /// Deletes unnecessary multiplication symbols
        /// </summary>
        private void delMult()
        {
            MathSymbol s = First;
            if (s != null)
            {
                MathSymbol s1 = s.Next;
                while (s1 != null)
                {
                    if (s1.SymbolType == (int)FormulaConstants.Binary & s1.Symbol == '*')
                    {
                        if (s.SymbolType != (int)FormulaConstants.Number | s1.Next.SymbolType != (int)FormulaConstants.Number)
                        {
                            s1.Remove();
                            s = s.Next;
                            if (s == null)
                            {
                                break;
                            }
                            s1 = s.Next;
                            continue;
                        }
                    }
                    s = s1;
                    s1 = s.Next;
                }
            }
            s = First;
            while (s != null)
            {
                if (s.HasChildren)
                {
                    for (int i = 0; i < s.Count; i++)
                    {
                        s[i].delMult();
                    }
                }
                s = s.Next;
            }
        }

        /// <summary>
        /// Reverses digital to symbolic represrntation
        /// </summary>
        private void reverseNumber()
        {
            MathSymbol s = First;
            while (s != null)
            {
                if (s.SymbolType == (int)FormulaConstants.Number)
                {
                    if (s.Symbol == '?')
                    {
                        ArrayList f = s.Children;
                        double a = s.DoubleValue;
                        if (a == Math.E | a == Math.PI)
                        {
                            s.Append(new SimpleSymbol((a == Math.E) ? 'e' : 'p'));
                            MathSymbol s1 = s.Next;
                            s.Remove();
                            s1.Children = f;
                            s = s1.Next;
                            continue;
                        }
                        int b = 0;
                        bool intv = false;
                        if (Math.Abs(a - Math.Ceiling(a)) < ROUND_EPS)
                        {
                            b = (int)Math.Ceiling(a);
                            intv = true;
                        }
                        else if (Math.Abs(a - Math.Floor(a)) < ROUND_EPS)
                        {
                            b = (int)Math.Floor(a);
                            intv = true;
                        }
                        string str = "";
                        if (intv)
                        {
                            str = b + "";
                        }
                        else
                        {
                            str = a + "";
                        }
                        MathSymbol sOne = s;
                        for (int i = 0; i < str.Length; i++)
                        {
                            MathSymbol symb = (str[i] == MathSymbol.DecimalSep[0]) ?
                                new BinarySymbol('.') :
                                new SimpleSymbol(str[i], false, (int)FormulaConstants.Number);
                            sOne.Append(symb);
                            sOne = sOne.Next;
                        }
                        s.Remove();
                        sOne.Children = f;
                        s = sOne.Next;
                    }
                }
                else
                {
                    s = s.Next;
                }
            }
            s = First;
            while (s != null)
            {
                if (s.HasChildren)
                {
                    ArrayList f = s.Children;
                    if (f != null)
                    {
                        for (int i = 0; i < f.Count; i++)
                        {
                            MathFormula form = f[i] as MathFormula;
                            if (form.Count > 0)
                            {
                                form.reverseNumber();
                            }
                        }
                    }
                }
                s = s.Next;
            }
        }
        #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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


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