public static double[] rotQuatAvg(CircularBuffer <SensorCalibratorData> calibrators)
        {
            double[] sums   = new double[4];
            double[] output = new double[4];
            for (int i = 0; i < calibrators.Capacity; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    sums[j] += calibrators[i].rotquat[j] * calibrators[i].rotquat[j];
                }
            }

            for (int j = 0; j < 4; j++)
            {
                output[j] = Math.Sqrt(sums[j] / calibrators.Capacity);
            }

            return(output);


            //adapted from Tolga Birdal

            /*
             * Based on
             * Markley, F. Landis, Yang Cheng, John Lucas Crassidis, and Yaakov Oshman.
             * "Averaging quaternions." Journal of Guidance, Control, and Dynamics 30,
             * no. 4 (2007): 1193-1197.
             * */
            /*
             * int M = calibrators.size;
             * //A = zeros(4,4)
             * double[,] A = new double[,] { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } };
             *
             * for (int i = 0; i < M; i++)
             * {
             *  //q = Q(i,:)';
             *  double[] q = new double[4];
             *  for (int j = 0; j < 4; j++ )
             *      q[j] = calibrators[i].rotquat[j];
             *
             *  //A = q*q'+A; % rank 1 update
             *  for (int j = 0; j < 4; j++)
             *      for (int k = 0; k < 4; k++)
             *      {
             *          //q*q'[j, k] = q[j] * q[k];
             *          A[j, k] += q[j] * q[k];
             *      }
             * }
             *
             * //% scale
             * //A=(1.0/M)*A;
             * double s = 1.0/M;
             * for (int j = 0; j < 4; j++)
             *  for (int k = 0; k < 4; k++)
             *      A[j, k] *= s;
             *
             * //% Get the eigenvector corresponding to largest eigen value
             * //[Qavg, Eval] = eigs(A,1);
             * double[] wr, wi;
             * double[,] vl, vr;
             * alglib.rmatrixevd(A, 4, 3, out wr,out wi,out vl,out vr);
             *
             * ShowArrayInfo(wr);
             * ShowArrayInfo(wi);
             *
             * ShowArrayInfo(vl);
             * ShowArrayInfo(vr);
             *
             * double[] Qavg = new double[4];
             * for (int i = 0; i < 4; i++)
             *  Qavg[i] = wr[i];
             *
             * return Qavg;
             * */
        }