code: @Override
  	public synchronized double[][][] getIntegratedLIBORCovariance() {
  		if(integratedLIBORCovariance != null) {
  			return integratedLIBORCovariance;
  		}
  
  		TimeDiscretization liborPeriodDiscretization = getLiborPeriodDiscretization();
  		TimeDiscretization simulationTimeDiscretization = getTimeDiscretization();
  
  		integratedLIBORCovariance = new double[simulationTimeDiscretization.getNumberOfTimeSteps()][liborPeriodDiscretization.getNumberOfTimeSteps()][liborPeriodDiscretization.getNumberOfTimeSteps()];
  		for(int componentIndex1 = 0; componentIndex1 < liborPeriodDiscretization.getNumberOfTimeSteps(); componentIndex1++) {
  			// Sum the libor cross terms (use symmetry)
  			for(int componentIndex2 = componentIndex1; componentIndex2 < liborPeriodDiscretization.getNumberOfTimeSteps(); componentIndex2++) {
  				double integratedLIBORCovarianceValue = 0.0;
  				for(int timeIndex = 0; timeIndex < simulationTimeDiscretization.getNumberOfTimeSteps(); timeIndex++) {
  					double dt = getTime(timeIndex+1) - getTime(timeIndex);
  					RandomVariable[] factorLoadingOfComponent1 = getCovarianceModel().getFactorLoading(timeIndex, componentIndex1, null);
  					RandomVariable[] factorLoadingOfComponent2 = getCovarianceModel().getFactorLoading(timeIndex, componentIndex2, null);
  					for(int factorIndex = 0; factorIndex < getNumberOfFactors(); factorIndex++) {
  						integratedLIBORCovarianceValue += factorLoadingOfComponent1[factorIndex].get(0) * factorLoadingOfComponent2[factorIndex].get(0) * dt;
  					}
  					integratedLIBORCovariance[timeIndex][componentIndex1][componentIndex2] = integratedLIBORCovarianceValue;
  				}
  			}
  		}
  
  		return integratedLIBORCovariance;
  	}
docs: /* (non-Javadoc)
  @see net.finmath.montecarlo.interestrate.LIBORMarketModel#getIntegratedLIBORCovariance()