Click here to Skip to main content
15,886,519 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.Collections;
using System.Text;

namespace FormulaEditor
{
    /// <summary>
    /// Elementary binary operation
    /// </summary>
    public class ElementaryBinaryOperation : IObjectOperation, ICloneable, IDerivationOperation,
        IFormulaCreatorOperation
    {

        /// <summary>
        /// Object of char type
        /// </summary>
        public const Char CharType = (char)0;

        /// <summary>
        /// Object of sbyte type
        /// </summary>
        public const SByte SbyteType = (sbyte)0;

        /// <summary>
        /// Object of short type
        /// </summary>
        public const Int16 Int16Type = (short)0;

        /// <summary>
        /// Object of int type
        /// </summary>
        public const Int32 Int32Type = (int)0;

        /// <summary>
        /// Object of long type
        /// </summary>
        public const Int64 Int64Type = (long)0;

        /// <summary>
        /// Object of byte type
        /// </summary>
        public const Byte ByteType = (byte)0;

        /// <summary>
        /// Object of ushort type
        /// </summary>
        public const UInt16 Uint16Type = (ushort)0;

        /// <summary>
        /// Object of uint type
        /// </summary>
        public const UInt32 Uint32Type = (uint)0;

        /// <summary>
        /// Object of ulong type
        /// </summary>
        public const UInt64 Uint64Type = (ulong)0;

        /// <summary>
        /// Object of bool type
        /// </summary>
        public const Boolean BooleanType = false;

        /// <summary>
        /// Object of double type
        /// </summary>
        public const Double DoubleType = 0;

        /// <summary>
        /// Object of string type
        /// </summary>
        public const string StringType = "";

        /// <summary>
        /// Types of objects
        /// </summary>
        public static readonly object[] Types = new object[]{DoubleType, BooleanType, ByteType, Uint16Type, Uint32Type, Uint64Type,
			SbyteType, Int16Type, Int32Type, Int64Type, StringType};


        /// <summary>
        /// Type of operation
        /// </summary>
        private object type;

        /// <summary>
        /// Type of operation
        /// </summary>
        private const Double a = 0;

        /// <summary>
        /// Operation symbol
        /// </summary>
        private char symbol;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="symbol">Operation symbol</param>
        /// <param name="type">Type of operation</param>
        public ElementaryBinaryOperation(char symbol, object type)
        {
            this.symbol = symbol;
            this.type = type;
        }

        /// <summary>
        /// Creates formula
        /// </summary>
        /// <param name="tree">Operation tree</param>
        /// <param name="level">Formula level</param>
        /// <param name="sizes">Sizes of symbols</param>
        /// <returns>The formula</returns>
        public MathFormula CreateFormula(ObjectFormulaTree tree, byte level, int[] sizes)
        {
            MathFormula form = new MathFormula(level, sizes);
            for (int i = 0; i < 2; i++)
            {
                IFormulaCreatorOperation op = tree[i].Operation as IFormulaCreatorOperation;
                MathFormula f = op.CreateFormula(tree[i], level, sizes);
                MathFormula fp = null;
                if (op.OperationPriority < OperationPriority)
                {
                    fp = new MathFormula(level, sizes);
                    MathSymbol s = new BracketsSymbol();
                    s.Append(fp);
                    fp.First[0] = f;
                }
                else
                {
                    fp = f;
                }
                form.Add(fp);
                if (i == 0)
                {
                    MathSymbol s = new BinarySymbol(symbol);
                    s.Append(form);
                }
            }
            return form;
        }



        /// <summary>
        /// Operation priority
        /// </summary>
        public int OperationPriority
        {
            get
            {
                if (symbol == '*')
                {
                    return (int)ElementaryOperationPriorities.Multiply;
                }
                return (int)ElementaryOperationPriorities.PlusMinus;
            }
        }


        /// <summary>
        /// Clones itself
        /// </summary>
        /// <returns>A clone</returns>
        public object Clone()
        {
            return new ElementaryBinaryOperation(symbol, type);
        }

        /// <summary>
        /// Calculates derivation
        /// </summary>
        /// <param name="tree">The function for derivation calculation</param>
        /// <param name="s">Derivation string</param>
        /// <returns>The derivation</returns>
        public ObjectFormulaTree Derivation(ObjectFormulaTree tree, string s)
        {
            Double a = 0;
            if ((symbol == '+') | (symbol == '-'))
            {
                IObjectOperation op = new ElementaryBinaryOperation(symbol, a);
                List<ObjectFormulaTree> l = new List<ObjectFormulaTree>();
                for (int i = 0; i < tree.Count; i++)
                {
                    l.Add(DerivationPerformer.Derivation(tree[i], s));
                }
                return new ObjectFormulaTree(op, l);
            }
            ObjectFormulaTree[] der = new ObjectFormulaTree[2];
            for (int i = 0; i < 2; i++)
            {
                der[i] = DerivationPerformer.Derivation(tree[i], s);
            }
            if (symbol == '*')
            {
                List<ObjectFormulaTree> list = new List<ObjectFormulaTree>();
                for (int i = 0; i < 2; i++)
                {
                    ElementaryBinaryOperation o = new ElementaryBinaryOperation('*', a);
                    List<ObjectFormulaTree> l = new List<ObjectFormulaTree>();
                    l.Add(tree[i].Clone() as ObjectFormulaTree);
                    l.Add(der[1 - i]);
                    list.Add(new ObjectFormulaTree(o, l));
                }
                ElementaryBinaryOperation op = new ElementaryBinaryOperation('+', a);
                return new ObjectFormulaTree(op, list);
            }
            return null;
        }

        /// <summary>
        /// Arity of this operation
        /// </summary>
        public int Arity
        {
            get
            {
                return 2;
            }
        }

        /// <summary>
        /// Calculates result of this operation
        /// </summary>
        public object this[object[] x]
        {
            get
            {
                return calculate(x);
            }
        }

        /// <summary>
        /// Return type
        /// </summary>
        public object ReturnType
        {
            get
            {
                return type;
            }
        }

        /// <summary>
        /// The "is powered" sign
        /// </summary>
        public bool IsPowered
        {
            get
            {
                return false;
            }
        }

        #region Specific Members

        /// <summary>
        /// Detects whether object type is integer
        /// </summary>
        /// <param name="o">The object</param>
        /// <returns>True if type is integer and false otherwise</returns>
        public static bool IsInteger(object o)
        {
            return (o is SByte) | (o is Byte) | (o is Int16) | (o is UInt16)
                | (o is Int32) | (o is UInt32) | (o is Int64) | (o is UInt64);
        }

        /// <summary>
        /// Detects whether object type is unsigned
        /// </summary>
        /// <param name="o">The object</param>
        /// <returns>True if type is unsigned and false otherwise</returns>
        public static bool IsUnsigned(object o)
        {
            return (o is Byte) | (o is UInt16) | (o is UInt32) | (o is UInt64);
        }

        /// <summary>
        /// Detects whether object type is double
        /// </summary>
        /// <param name="o">The object</param>
        /// <returns>True if type is double and false otherwise</returns>
        public static bool IsReal(object o)
        {
            return o is Double;
        }

        /// <summary>
        /// Detects whether object type is numercial
        /// </summary>
        /// <param name="o">The object</param>
        /// <returns>True if type is numercial and false otherwise</returns>
        public static bool IsNumber(object o)
        {
            return IsReal(o) | IsInteger(o);
        }

        /// <summary>
        /// Detects whether object is 64 bit integer
        /// </summary>
        /// <param name="o">The object</param>
        /// <returns>True if object is 64 bit integer and false otherwise</returns>
        public static bool IsInteger64(object o)
        {
            return (o is UInt64) | (o is Int64);
        }

        /// <summary>
        /// Detects whether object is negative
        /// </summary>
        /// <param name="o">The object</param>
        /// <returns>True if object is negative and false otherwise</returns>
        public static bool IsNegative(object o)
        {
            return ElementaryIntegerOperation.ToDouble(o) < 0;
        }

        /// <summary>
        /// Calculates number of object bits
        /// </summary>
        /// <param name="o">The object</param>
        /// <returns>Number of bits</returns>
        public static int NBits(object o)
        {
            if ((o is Byte) | (o is SByte))
            {
                return 8;
            }
            if ((o is Int16) | (o is UInt16))
            {
                return 16;
            }
            if ((o is Int32) | (o is UInt32))
            {
                return 32;
            }
            if ((o is Int64) | (o is UInt64))
            {
                return 64;
            }
            return 0;
        }

        public char Symbol
        {
            get
            {
                return symbol;
            }
        }


        public static object DetectType(object typeA, object typeB)
        {
            if (!IsNumber(typeA) | !IsNumber(typeB))
            {
                return null;
            }
            if (IsReal(typeA) | IsReal(typeB))
            {
                return a;
            }
            int nA = NBits(typeA);
            int nB = NBits(typeB);
            if (nA > nB)
            {
                return typeA;
            }
            if (nB > nA)
            {
                return typeB;
            }
            if (IsUnsigned(typeA) & IsUnsigned(typeB))
            {
                return typeA;
            }
            if (!IsUnsigned(typeA))
            {
                return typeA;
            }
            if (!IsUnsigned(typeB))
            {
                return typeB;
            }
            return null;
        }


        /// <summary>
        /// Calculates itself
        /// </summary>
        /// <param name="x">Arguments</param>
        /// <returns>Result of calculation</returns>
        private object calculate(object[] x)
        {
            if (IsReal(type))
            {
                double a = ElementaryIntegerOperation.ToDouble(x[0]);
                double b = ElementaryIntegerOperation.ToDouble(x[1]);
                switch (symbol)
                {
                    case '+':
                        return a + b;
                    case '-':
                        return a - b;
                    case '*':
                        return a * b;
                }
            }
            if (type is SByte)
            {
                sbyte a = ElementaryIntegerOperation.ToSByte(x[0]);
                sbyte b = ElementaryIntegerOperation.ToSByte(x[1]);
                switch (symbol)
                {
                    case '+':
                        return a + b;
                    case '-':
                        return a - b;
                    case '*':
                        return a * b;
                }
            }
            if (type is Int16)
            {
                short a = ElementaryIntegerOperation.ToInt16(x[0]);
                short b = ElementaryIntegerOperation.ToInt16(x[1]);
                switch (symbol)
                {
                    case '+':
                        return a + b;
                    case '-':
                        return a - b;
                    case '*':
                        return a * b;
                }
            }
            if (type is Int32)
            {
                int a = ElementaryIntegerOperation.ToInt32(x[0]);
                int b = ElementaryIntegerOperation.ToInt32(x[1]);
                switch (symbol)
                {
                    case '+':
                        return a + b;
                    case '-':
                        return a - b;
                    case '*':
                        return a * b;
                }
            }
            if (type is Int64)
            {
                long a = ElementaryIntegerOperation.ToInt64(x[0]);
                long b = ElementaryIntegerOperation.ToInt64(x[1]);
                switch (symbol)
                {
                    case '+':
                        return a + b;
                    case '-':
                        return a - b;
                    case '*':
                        return a * b;
                }
            }
            if (type is Byte)
            {
                byte a = ElementaryIntegerOperation.ToByte(x[0]);
                byte b = ElementaryIntegerOperation.ToByte(x[1]);
                switch (symbol)
                {
                    case '+':
                        return a + b;
                    case '-':
                        return a - b;
                    case '*':
                        return a * b;
                }
            }
            if (type is UInt16)
            {
                ushort a = ElementaryIntegerOperation.ToUInt16(x[0]);
                ushort b = ElementaryIntegerOperation.ToUInt16(x[1]);
                switch (symbol)
                {
                    case '+':
                        return a + b;
                    case '-':
                        return a - b;
                    case '*':
                        return a * b;
                }
            }
            if (type is UInt32)
            {
                uint a = ElementaryIntegerOperation.ToUInt32(x[0]);
                uint b = ElementaryIntegerOperation.ToUInt32(x[1]);
                switch (symbol)
                {
                    case '+':
                        return a + b;
                    case '-':
                        return a - b;
                    case '*':
                        return a * b;
                }
            }
            if (type is UInt64)
            {
                ulong a = ElementaryIntegerOperation.ToUInt64(x[0]);
                ulong b = ElementaryIntegerOperation.ToUInt64(x[1]);
                switch (symbol)
                {
                    case '+':
                        return a + b;
                    case '-':
                        return a - b;
                    case '*':
                        return a * b;
                }
            }
            return 0;
        }

        /// <summary>
        /// Converts double variale
        /// </summary>
        /// <param name="type">Return type</param>
        /// <param name="x">The variable</param>
        /// <returns>Coversion result</returns>
        static public object Convert(object type, double x)
        {
            if (type.Equals(DoubleType))
            {
                return x;
            }
            if (type.Equals(BooleanType))
            {
                if (x == 0)
                {
                    return false;
                }
                if (x == 1)
                {
                    return true;
                }
                throw new Exception("Can not convert double parameter value to boolean");
            }
            if (type.Equals(SbyteType))
            {
                return (sbyte)x;
            }
            if (type.Equals(Int16Type))
            {
                return (short)x;
            }
            if (type.Equals(Int32Type))
            {
                return (int)x;
            }
            if (type.Equals(Int64Type))
            {
                return (long)x;
            }
            if (type.Equals(ByteType))
            {
                return (byte)x;
            }
            if (type.Equals(Uint16Type))
            {
                return (ushort)x;
            }
            if (type.Equals(Uint32Type))
            {
                return (uint)x;
            }
            if (type.Equals(Uint64Type))
            {
                return (ulong)x;
            }
            throw new Exception("Type cannot be converted from double");
        }
        #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