docs: @Override
  	public CharacteristicFunctionInterface apply(final double time) {
  		return new CharacteristicFunctionInterface() {
  			@Override
  			public Complex apply(Complex argument) {
  
  				Complex iargument = argument.multiply(Complex.I);
  
  				Complex c = iargument
  						.multiply(iargument)
  						.add(iargument.multiply(-1))
  						.multiply(0.5*delta*delta)
  						.exp()
  						.multiply(new Complex(1+k).pow(iargument))
  						.add(-1)
  						.add(iargument.multiply(-k));
  
  				Complex[] gamma = new Complex[numberOfFactors];
  				Complex[] a = new Complex[numberOfFactors];
  				Complex[] b = new Complex[numberOfFactors];
  				for(int i = 0; i < numberOfFactors; i++) {
  					gamma[i] = iargument
  							.multiply(rho[i]*sigma[i])
  							.subtract(beta[i])
  							.pow(2)
  							.subtract(
  									iargument.multiply(iargument)
  									.add(iargument.multiply(-1))
  									.multiply(0.5)
  									.add(c.multiply(lambda[i+1]))
  									.multiply(2*sigma[i]*sigma[i])
  									)
  							.sqrt()
  							;
  
  
  					a[i] =
  							iargument
  							.multiply(rho[i] * sigma[i])
  							.subtract(beta[i])
  							.subtract(gamma[i])
  							.multiply((-alpha[i]*time)/(sigma[i]*sigma[i]))
  							.subtract(iargument
  									.multiply(rho[i]*sigma[i])
  									.subtract(beta[i])
  									.subtract(gamma[i])
  									.multiply(new Complex(1).divide(gamma[i].multiply(time).exp())
  											.subtract(1)
  											.divide(gamma[i])
  											)
  									.multiply(0.5)
  									.add(new Complex(1).divide(gamma[i].multiply(time).exp()))
  									.log()
  									.add(gamma[i].multiply(time))
  									.multiply((2*alpha[i])/(sigma[i]*sigma[i]))
  									)
  							;
  
  					b[i] = iargument
  							.multiply(iargument)
  							.add(iargument.multiply(-1))
  							.multiply(0.5)
  							.add(c.multiply(lambda[i+1]))
  							.multiply(-2)
  							.divide(iargument
  									.multiply(rho[i] * sigma[i])
  									.subtract(beta[i])
  									.add(gamma[i]
  											.multiply(new Complex(1).divide(gamma[i].multiply(time).exp())
  													.add(1)
  													.divide(new Complex(1).divide(gamma[i].multiply(time).exp())
  															.subtract(1)
  															)
  													)
  											)
  									)
  							;
  
  				}
  
  				Complex characteristicFunction =
  						a[0]
  								.add(b[0].multiply(volatility[0]))
  								.add(c.multiply(time*lambda[0]))
  								.add(iargument.multiply(Math.log(initialValue)+time*riskFreeRate))
  								.add(-discountRate*time);
  
  				if(numberOfFactors == 2) {
  					characteristicFunction = characteristicFunction
  							.add(a[1])
  							.add(b[1].multiply(volatility[1]));
  				}
  
  				characteristicFunction = characteristicFunction.exp();
  
  				return characteristicFunction;
  			}
  		};
  	}