private static TenorRawOptionData rawData(double[][][] dataArray)
        {
            IDictionary <Tenor, RawOptionData> raw = new SortedDictionary <Tenor, RawOptionData>();

            for (int looptenor = 0; looptenor < dataArray.Length; looptenor++)
            {
                DoubleMatrix matrix = DoubleMatrix.ofUnsafe(dataArray[looptenor]);
                raw[TENORS.get(looptenor)] = RawOptionData.of(EXPIRIES, MONEYNESS, SIMPLE_MONEYNESS, matrix, NORMAL_VOLATILITY);
            }
            return(TenorRawOptionData.of(raw));
        }
        /// <summary>
        /// Create a <seealso cref="RawOptionData"/> object for calibration from data.
        /// </summary>
        /// <param name="tenors">  the list of tenors </param>
        /// <param name="expiries">  the list of expiries </param>
        /// <param name="strikeLikeType">  the type of the strike-like dimension </param>
        /// <param name="strikeLikeData">  the data related to the strike-like dimension </param>
        /// <param name="dataType">  the type of the data </param>
        /// <param name="dataArray">  the array with the raw data, including potential Double.NaN for missing data. </param>
        /// <returns> the raw option data object </returns>
        public static TenorRawOptionData rawData(IList <Tenor> tenors, IList <Period> expiries, ValueType strikeLikeType, DoubleArray strikeLikeData, ValueType dataType, double[][][] dataArray)
        {
            IDictionary <Tenor, RawOptionData> raw = new SortedDictionary <Tenor, RawOptionData>();

            for (int looptenor = 0; looptenor < dataArray.Length; looptenor++)
            {
                DoubleMatrix matrix = DoubleMatrix.ofUnsafe(dataArray[looptenor]);
                raw[tenors[looptenor]] = RawOptionData.of(expiries, strikeLikeData, strikeLikeType, matrix, dataType);
            }
            return(TenorRawOptionData.of(raw));
        }
        /// <summary>
        /// Create a <seealso cref="RawOptionData"/> object for calibration from data and shift one point.
        /// </summary>
        /// <param name="tenors">  the list of tenors </param>
        /// <param name="expiries">  the list of expiries </param>
        /// <param name="strikeLikeType">  the type of the strike-like dimension </param>
        /// <param name="strikeLikeData">  the data related to the strike-like dimension </param>
        /// <param name="dataType">  the type of the data </param>
        /// <param name="dataArray">  the array with the raw data, including potential Double.NaN for missing data. </param>
        /// <param name="i">  the index of the tenor to shift </param>
        /// <param name="j">  the index of the expiry to shift </param>
        /// <param name="k">  the index of the strike-like dimension to shift </param>
        /// <param name="shift">  the size of the shift </param>
        /// <returns> the raw option data object </returns>
        public static TenorRawOptionData rawDataShiftPoint(IList <Tenor> tenors, IList <Period> expiries, ValueType strikeLikeType, DoubleArray strikeLikeData, ValueType dataType, double[][][] dataArray, int i, int j, int k, double shift)
        {
            IDictionary <Tenor, RawOptionData> raw = new SortedDictionary <Tenor, RawOptionData>();

            for (int looptenor = 0; looptenor < dataArray.Length; looptenor++)
            {
                double[][] shiftedData = java.util.dataArray[looptenor].Select(row => row.clone()).ToArray(l => new double[l][]);   // deep copy of 2d array
                if (looptenor == i)
                {
                    shiftedData[j][k] += shift;
                }
                DoubleMatrix matrix = DoubleMatrix.ofUnsafe(shiftedData);
                raw[tenors[looptenor]] = RawOptionData.of(expiries, strikeLikeData, strikeLikeType, matrix, dataType);
            }
            return(TenorRawOptionData.of(raw));
        }