/// <summary>
        /// Parse a string to produce a <see cref="RealVector"/> object.
        /// </summary>
        /// <param name="source">String to parse.</param>
        /// <param name="pos">input/ouput parsing parameter.</param>
        /// <returns>the parsed <see cref="RealVector"/> object.</returns>
        public ArrayRealVector parse(String source, Int32 pos)
        {
            int initialIndex = pos;

            // parse prefix
            CompositeFormat.parseAndIgnoreWhitespace(source, pos);
            if (!CompositeFormat.parseFixedstring(source, trimmedPrefix))
            {
                return(null);
            }

            // parse components
            List <double> components = new List <double>();

            for (Boolean loop = true; loop;)
            {
                if (!(components.Count == 0))
                {
                    CompositeFormat.parseAndIgnoreWhitespace(source, pos);
                    if (!CompositeFormat.parseFixedstring(source, trimmedSeparator))
                    {
                        loop = false;
                    }
                }

                if (loop)
                {
                    CompositeFormat.parseAndIgnoreWhitespace(source, pos);
                    double component = CompositeFormat.parseNumber(source, CultureInfo.CurrentCulture);
                    if (Double.IsNaN(component))
                    {
                        components.Add(component);
                    }
                    else
                    {
                        // invalid component
                        // set index back to initial, error index should already be set
                        pos = initialIndex;
                        return(null);
                    }
                }
            }

            // parse suffix
            CompositeFormat.parseAndIgnoreWhitespace(source, pos);
            if (!CompositeFormat.parseFixedstring(source, trimmedSuffix))
            {
                return(null);
            }

            // build vector
            double[] data = new double[components.Count];
            for (int i = 0; i < data.Length; ++i)
            {
                data[i] = components[i];
            }
            return(new ArrayRealVector(data, false));
        }
        /// <summary>
        /// Parse a string to produce a <see cref="RealMatrix"/> object.
        /// </summary>
        /// <param name="source">String to parse.</param>
        /// <param name="pos">input/ouput parsing parameter.</param>
        /// <returns>the parsed <see cref="RealMatrix"/> object.</returns>
        public RealMatrix parse(String source, ref Int32 pos)
        {
            int initialIndex = pos;

            String trimmedPrefix          = prefix.Trim();
            String trimmedSuffix          = suffix.Trim();
            String trimmedRowPrefix       = rowPrefix.Trim();
            String trimmedRowSuffix       = rowSuffix.Trim();
            String trimmedColumnSeparator = columnSeparator.Trim();
            String trimmedRowSeparator    = rowSeparator.Trim();

            // parse prefix
            CompositeFormat.parseAndIgnoreWhitespace(source, pos);
            if (!CompositeFormat.parseFixedstring(source, trimmedPrefix))
            {
                return(null);
            }


            // parse components
            List <List <double> > matrix        = new List <List <double> >();
            List <double>         rowComponents = new List <double>();

            for (Boolean loop = true; loop;)
            {
                if (rowComponents.Count != 0)
                {
                    CompositeFormat.parseAndIgnoreWhitespace(source, pos);
                    if (!CompositeFormat.parseFixedstring(source, trimmedColumnSeparator))
                    {
                        if (trimmedRowSuffix.Length != 0 &&
                            !CompositeFormat.parseFixedstring(source, trimmedRowSuffix))
                        {
                            return(null);
                        }
                        else
                        {
                            CompositeFormat.parseAndIgnoreWhitespace(source, pos);
                            if (CompositeFormat.parseFixedstring(source, trimmedRowSeparator))
                            {
                                matrix.Add(rowComponents);
                                rowComponents = new List <double>();
                                continue;
                            }
                            else
                            {
                                loop = false;
                            }
                        }
                    }
                }
                else
                {
                    CompositeFormat.parseAndIgnoreWhitespace(source, pos);
                    if (trimmedRowPrefix.Length != 0 &&
                        !CompositeFormat.parseFixedstring(source, trimmedRowPrefix))
                    {
                        return(null);
                    }
                }

                if (loop)
                {
                    CompositeFormat.parseAndIgnoreWhitespace(source, pos);
                    double component = CompositeFormat.parseNumber(source, CultureInfo.CurrentCulture);
                    if (Double.IsNaN(component))
                    {
                        rowComponents.Add(component);
                    }
                    else
                    {
                        if (rowComponents.Count == 0)
                        {
                            loop = false;
                        }
                        else
                        {
                            // invalid component
                            // set index back to initial, error index should already be set
                            pos = initialIndex;
                            return(null);
                        }
                    }
                }
            }

            if (rowComponents.Count != 0)
            {
                matrix.Add(rowComponents);
            }

            // parse suffix
            CompositeFormat.parseAndIgnoreWhitespace(source, pos);
            if (!CompositeFormat.parseFixedstring(source, trimmedSuffix))
            {
                return(null);
            }

            // do not allow an empty matrix
            if (matrix.Count == 0)
            {
                pos = initialIndex;
                return(null);
            }

            // build vector
            double[][] data = new double[matrix.Count][];
            int        row  = 0;

            foreach (List <double> rowList in matrix)
            {
                data[row] = new double[rowList.Count];
                for (int i = 0; i < rowList.Count; i++)
                {
                    data[row][i] = rowList[i];
                }
                row++;
            }
            return(MatrixUtils.createRealMatrix(data));
        }
        /// <summary>
        /// Parses a string to produce a <see cref="Complex"/> object.
        /// </summary>
        /// <param name="source">the string to parse</param>
        /// <param name="pos">input/ouput parsing parameter.</param>
        /// <returns>the parsed <c>Complex</c> object.</returns>
        public Complex parse(String source, Int32 pos)
        {
            int initialIndex = pos;

            // parse whitespace
            Int32 nonSpace = CompositeFormat.parseAndIgnoreWhitespace(source, pos);

            // parse real
            Double re = CompositeFormat.parseNumber(source, CultureInfo.CurrentCulture);

            if (Double.IsNaN(re))
            {
                // invalid real number
                // set index back to initial, error index should already be set
                return(null);
            }

            // parse sign
            Int32 p    = CompositeFormat.parseNextCharacter(source, nonSpace);
            char  c    = source[p];
            int   sign = 0;

            switch (c)
            {
            case '0':
                // no sign
                // return real only complex number
                return(new Complex(re, 0.0));

            case '-':
                sign = -1;
                break;

            case '+':
                sign = 1;
                break;

            default:
                // invalid sign
                // set index back to initial, error index should be the last
                // character examined.
                return(null);
            }

            // parse whitespace
            CompositeFormat.parseAndIgnoreWhitespace(source, pos);

            // parse imaginary
            Double im = CompositeFormat.parseNumber(source, CultureInfo.CurrentCulture);

            if (Double.IsNaN(im))
            {
                // invalid imaginary number
                // set index back to initial, error index should already be set
                return(null);
            }

            // parse imaginary character
            if (!CompositeFormat.parseFixedstring(source, getImaginaryCharacter()))
            {
                return(null);
            }
            return(new Complex(re, im * sign));
        }