public RotationalComponents(double x, double y, double z)
        {
            EulerAngle           = new MathExpression.Expression.Vector <double>(3);
            EulerAngle.Values[0] = x;
            EulerAngle.Values[1] = y;
            EulerAngle.Values[2] = z;

            Quaternion = FromEuler(EulerAngle.Values[0], EulerAngle.Values[1], EulerAngle.Values[2]);
        }
        MathExpression.Expression.Vector <double> FromEuler(double x, double y, double z)
        {
            // Abbreviations for the various angular functions
            double cy = Math.Cos(z * 0.5);
            double sy = Math.Sin(z * 0.5);
            double cr = Math.Cos(x * 0.5);
            double sr = Math.Sin(x * 0.5);
            double cp = Math.Cos(y * 0.5);
            double sp = Math.Sin(y * 0.5);

            MathExpression.Expression.Vector <double> q = new MathExpression.Expression.Vector <double>(4);
            // w
            q.Values[0] = (float)(cy * cr * cp + sy * sr * sp);
            // x
            q.Values[1] = (float)(cy * sr * cp - sy * cr * sp);
            // y
            q.Values[2] = (float)(cy * cr * sp + sy * sr * cp);
            // z
            q.Values[3] = (float)(sy * cr * cp - cy * sr * sp);
            return(q);
        }
    // Use this for initialization
    void Start()
    {
        decimal piTest = MathExpression.Expression.BuiltInMethods.PiCalculator.PI(1000M);

        decimal sqrt2_2 = Sqrt(2M) / 2M;
        decimal cos45_1 = MathExpression.Expression.BuiltInMethods.AngleCosine(0.5M);
        decimal sine45_1 = MathExpression.Expression.BuiltInMethods.AngleSine(0.5M);
        decimal cos45 = MathExpression.Expression.BuiltInMethods.CosineTaylor(0.5M, 9);
        decimal sine45 = MathExpression.Expression.BuiltInMethods.SineTaylor(0.5M, 9);

        decimal deltaCos = cos45 - cos45_1;
        decimal deltaSine = sine45 - sine45_1;

        //Debug.Log(sqrt2_2);
        Debug.Log(cos45);
        Debug.Log(sine45);
        Debug.Log(deltaCos);
        Debug.Log(deltaSine);
        //Debug.Log(sqrt2_2 - cos45);
        //Debug.Log(sqrt2_2 - sine45);

        //MathExpression.Expression.BuiltInMethods.TestAngles();
        //return;

        System.Random r = new System.Random();
        List<double> doubles = new List<double>();
        for (int z=0;z<2048;z++)
        {
            int rand = r.Next(1024);
            //double randDouble = (double)(rand - 512) / 1024.0;
            //randDouble *= 500.0;
            double xval = (double)z / (double)2048;
            double randDouble = 1000.0 * Math.Cos(2.0 * Math.PI * xval * (0.247 * 2048.0));
            //double randDouble = 1000.0 * Math.Cos(2.0 * Math.PI * xval);
            //double xVal = (double)z / (double)1024;
            //double randDouble = 1000.0 * (Math.Pow(Math.Cos(xVal), 2.0) + Math.Pow(Math.Sin(xVal), 2.0));
            doubles.Add(randDouble);
            //doubles.Add(1.0);
        }

        JObject test = Newtonsoft.Json.Linq.JObject.Parse(JsonTextString);
        testData = new List<DataClass>();
        string stockSymbol = (test["Meta Data"] as JObject)["2. Symbol"].ToString();
        foreach (var t in test["Monthly Adjusted Time Series"] as JObject)
        {
            string key = t.Key;
            DateTime dd = DateTime.Parse(key);
            JObject j = t.Value as JObject;
            double d1 = double.Parse(j["1. open"].ToString());
            double d2 = double.Parse(j["2. high"].ToString());
            double d3 = double.Parse(j["3. low"].ToString());
            double d4 = double.Parse(j["4. close"].ToString());
            double d5 = double.Parse(j["5. adjusted close"].ToString());
            double d6 = double.Parse(j["6. volume"].ToString());
            double d7 = double.Parse(j["7. dividend amount"].ToString());

            DataClass dataClass = new DataClass();
            dataClass.StockSymbol = stockSymbol;
            dataClass.StockDate = dd;
            dataClass.StockOpen = d1;
            dataClass.StockHigh = d2;
            dataClass.StockLow = d3;
            dataClass.StockClose = d4;
            dataClass.StockAdjustedClose = d5;
            dataClass.Volume = d6;
            dataClass.DividendAmount = d7;

            testData.Add(dataClass);
        }
        DateTime firstDate = testData.Min(x => x.StockDate);
        foreach(DataClass d in testData)
        {
            d.TotalSeconds = (d.StockDate - firstDate).TotalSeconds;
        }
        double maxSeconds = testData.Max(x => x.TotalSeconds);
        foreach (DataClass d in testData)
        {
            d.TimeValue = d.TotalSeconds / maxSeconds;
        }
        testData = testData.OrderBy(x => x.TimeValue).ToList();

        data = new MathExpression.Expression.BuiltInMethods.TimeSampledData[testData.Count];
        for (int z=0;z<testData.Count;z++)
        {
            data[z] = new MathExpression.Expression.BuiltInMethods.TimeSampledData(testData[z].TimeValue, testData[z].StockClose);
        }
        double[] dpoints = data.Select(x => x.Value).ToArray();
        double[] smoothPoints = MathExpression.Expression.BuiltInMethods.SmoothDFT(dpoints, 0.9);

        //Vector3[] pointsA = new Vector3[doubles.Count];
        Vector3[] pointsA = new Vector3[testData.Count];
        for (int z=0;z<pointsA.Length;z++)
        {
            pointsA[z] = new Vector3(0f, (float)testData[z].StockClose, (float)testData[z].TimeValue / (float)1.0f * 1000f);
        }
        //for (int z=0;z<doubles.Count;z++)
        //{
        //    float v = (float)doubles[z];
        //    pointsA[z] = new Vector3(0f, v, (float)z / (float)doubles.Count * 1000f);
        //}

        //double inputMax = 0.0;

        ////frequencies = new List<MathExpression.Expression.BuiltInMethods.FrequencyOutput>();
        ////chart = MathExpression.Expression.BuiltInMethods.HGT(data, data.Length, data.Length, out inputMax, out frequencies, 1.0, 1.0);

        //double[] inputs = data.OrderBy(x => x.Time).Select(x => x.Value).ToArray();
        //MathExpression.Expression.Vector<double>[] r1 = MathExpression.Expression.BuiltInMethods.DFT(inputs);
        //double[] outputs = MathExpression.Expression.BuiltInMethods.InverseDFTHarmonic(r1, 3, data.Length);

        //MathExpression.Expression.Vector<double>[] frequencies = MathExpression.Expression.BuiltInMethods.HGT(doubles.ToArray(), 2048, 2048, out inputMax, 1, 1);
        //MathExpression.Expression.Vector<double>[] frequencies = MathExpression.Expression.BuiltInMethods.HGT(data, 2048, 2048, out inputMax, 1, 1);
        //double[] inverse = MathExpression.Expression.BuiltInMethods.InverseHGT(frequencies, 2048, 2048, inputMax, 1, 1, 768);

        //double inMax = doubles.Max();
        //double invMax = inverse.Max();
        //double multiplier = inMax / invMax;

        //Vector3[] points1 = new Vector3[chart.ClampedRotationValues.Count];
        //for (int z = 0; z < points1.Length; z++)
        //{
        //    points1[z] = new Vector3(0f, (float)(chart.ClampedRotationValues[z].Total / 2048.0 * 50.0), (float)z / (float)points1.Length * 1000f);
        //}

        //Vector3[] points2 = new Vector3[chart.ClampedRotationValues.Count];
        //for (int z = 0; z < points2.Length; z++)
        //{
        //    points2[z] = new Vector3(0f, (float)(chart.ClampedRotationValues[z].Total / 2048.0 * 50.0), (float)z / (float)points2.Length * 1000f);
        //}

        // 1/21/2019 marked
        //Vector3[] points1 = new Vector3[smoothPoints.Length];
        //for (int z = 0; z < points1.Length; z++)
        //{
        //    points1[z] = new Vector3(0f, (float)(smoothPoints[z]), (float)(z+1) / (float)points1.Length * 1000f);
        //}

        //Vector3[] points2 = new Vector3[outputs.Length];
        //for (int z = 0; z < points2.Length; z++)
        //{
        //    //points2[z] = new Vector3(0f, (float)(chart.ClampedRotationValues[z].Total / 2048.0 * 50.0), (float)z / (float)points2.Length * 1000f);
        //}

        //MathExpression.Expression.Vector[] vectors = MathExpression.Expression.BuiltInMethods.VODFT(doubles.ToArray(), 20000);
        //MathExpression.Expression.Vector<double>[] vectors = MathExpression.Expression.BuiltInMethods.DFT(doubles.ToArray());
        //for (int z = 0; z < points1.Length; z++)
        //{
        //    points1[z] = new Vector3(0f, (float)(vectors[z].Values[0] / 2048.0 * 50.0), (float)z / (float)points1.Length * 1000f);
        //}

        double[] test1 = new double[2048];
        double[] test0 = new double[2048];
        for (int z = 0; z < 2048; z++)
        {
            test1[z] = 1000000.0;
            test0[z] = -1000000.0;
        }
        MathExpression.Expression.Vector<double>[,] vecA = MathExpression.Expression.BuiltInMethods.DFTCapture(test1);
        MathExpression.Expression.Vector<double>[,] vecB = MathExpression.Expression.BuiltInMethods.DFTCapture(test0);
        ////MathExpression.Expression.Vector<double>[,] vecB = MathExpression.Expression.BuiltInMethods.VODFTCapture(doubles.ToArray(), 20480);
        double[] out1 = MathExpression.Expression.BuiltInMethods.SumMagnitudes(vecA, true);
        double[] out2 = MathExpression.Expression.BuiltInMethods.SumMagnitudes(vecB, true);
        ////double[] dftMultiplier = MathExpression.Expression.BuiltInMethods.CreateDFTScaleMultiplier(1024, 20480);

        Vector3[] points1 = new Vector3[out1.Length];
        pointsA = new Vector3[out2.Length];
        ////////Vector3[] points2 = new Vector3[out2.Length];
        for (int z = 0; z < points1.Length; z++)
        {
            points1[z] = new Vector3(0f, (float)out1[z], (float)z / (float)points1.Length * 1000f);
            pointsA[z] = new Vector3(0f, (float)out2[z], (float)z / (float)pointsA.Length * 1000f);
        }

        ////for (int z=0;z<points2.Length;z++)
        ////{
        ////    points2[z] = new Vector3(0f, (float)out2[z], (float)z / (float)points2.Length * 1000f);
        ////}

        /*
        double lastValue = 0.0;
        for (int z = 0; z < points2.Length; z++)
        {
            double value = out2[z];
            double dftZ = dftMultiplier[z];
            if (dftZ == 0.0001)
            {
                value = lastValue;
            }
            else
            {
                value *= dftMultiplier[z];
                lastValue = value;
            }
            points2[z] = new Vector3(0f, (float)(value), (float)z / (float)points2.Length * 1000f);
        }
        */
        line.positionCount = pointsA.Length;
        line.SetPositions(pointsA);

        line2.positionCount = points1.Length;
        line2.SetPositions(points1);
        //line3.positionCount = points2.Length;
        //line3.SetPositions(points2);

        ////double[] fPointsA = MathExpression.Expression.BuiltInMethods.InverseDFTCaptureHarmonicBySums(vecA, 3);
        ////double[] fPointsB = MathExpression.Expression.BuiltInMethods.InverseDFTCaptureHarmonicBySums(vecB, 3);
        ////Vector3[] pointsI1 = new Vector3[fPointsA.Length];
        ////Vector3[] pointsI2 = new Vector3[fPointsB.Length];
        ////for (int z = 0; z < pointsI1.Length; z++)
        ////{
        ////    pointsI1[z] = new Vector3(0f, (float)fPointsA[z], (float)z / (float)pointsI1.Length * 1000f);
        ////}
        ////for (int z = 0; z < pointsI2.Length; z++)
        ////{
        ////    pointsI2[z] = new Vector3(0f, (float)fPointsB[z], (float)z / (float)pointsI2.Length * 1000f);
        ////}

        //////double[,] final = MathExpression.Expression.BuiltInMethods.InverseDFTCaptureHarmonicAll(vecB);

        //////for (int z=0;z<final.Length;z++)
        //////{
        //////    final[z] = MathExpression.Expression.BuiltInMethods.InverseDFTCaptureHarmonicSingularDistance(vecB, z);
        //////}
        //////pointsI2 = new Vector3[final.Length];
        //////for (int z = 0; z < final.Length; z++)
        //////{
        //////    pointsI2[z] = new Vector3(0f, (float)final[z], (float)z / (float)final.Length * 1000f);
        //////}

        ////lineinv1.positionCount = pointsI1.Length;
        ////lineinv1.SetPositions(pointsI1);
        ////lineinv2.positionCount = pointsI2.Length;
        ////lineinv2.SetPositions(pointsI2);

        ////Vector3[] points = new Vector3[vectors.Length];
        ////for (int z=0;z<vectors.Length;z++)
        ////{
        ////    //double magnitude = Math.Sqrt(vectors[z].Values[0] * vectors[z].Values[0] + vectors[z].Values[1] * vectors[z].Values[1]);
        ////    ////points[z] = new Vector3((float)vectors[z].Values[0], (float)vectors[z].Values[1], (float)z / (float)vectors.Length * 1000f);
        ////    //points[z] = new Vector3(0f, (float)magnitude, (float)z / (float)vectors.Length * 1000f);
        ////}
        ////double[] inverse = MathExpression.Expression.BuiltInMethods.InverseVODFT(vectors, doubles.Count);
        ////Vector3[] pointsB = new Vector3[inverse.Length];
        ////for (int z=0;z<inverse.Length;z++)
        ////{
        ////    float v = (float)inverse[z];
        ////    pointsB[z] = new Vector3(0f, (float)v, (float)z / (float)doubles.Count * 1000f);
        ////}
        ////line.positionCount = vectors.Length;
        ////line.SetPositions(points);
        ////line2.positionCount = doubles.Count;
        ////line2.SetPositions(pointsA);
        ////line3.positionCount = inverse.Length;
        ////line3.SetPositions(pointsB);
    }