void vanillaSwapComparaisonExemple()
{

	double strike		=	0.02;
	size_t indexStart	=	3;
	size_t indexEnd		=	19;
	Tenor tenorStruture	=	Tenor::_6M;
	Tenor floatingTenor	=	Tenor::_6M;
	Tenor fixedTenor	=	Tenor::_12M;
	LMMTenorStructure_PTR lmmTenorStructure(new LMMTenorStructure(tenorStruture, 10));
	size_t liborIndex	=	lmmTenorStructure->get_horizon()+1;
	std::vector<double> myInitialLibor(liborIndex);

	for (size_t i = 0; i <myInitialLibor.size(); i++)
	{
		myInitialLibor[i]=0.02;							//+((double)i)*0.01;
	}

	cout	<<	"strike:                        "	<<	strike												<<	endl;
	cout	<<	"indexStart:                    "	<<	indexStart											<<	endl;
	cout	<<	"indexEnd:                      "	<<	indexEnd											<<	endl;
	cout	<<	"tenorStrutureYearFraction:     "	<<	lmmTenorStructure->get_tenorType().YearFraction()	<<	endl;
	cout	<<	"floatingVStenorStrutureRatio:  "	<<	floatingTenor.ratioTo(tenorStruture)				<<	endl;
	cout	<<	"fixedVStenorStrutureRatio:     "	<<	fixedTenor.ratioTo(tenorStruture)					<<	endl;
	cout	<<	"myInitialLibor:  ";
	for (size_t i = 0; i <myInitialLibor.size(); i++)
	{
		cout	<<	myInitialLibor[i]	<<	" ";
	}
	cout	<<	 endl;
	cout	<<	 endl;

	//VanillaSwap_Chi_Trang
	VanillaSwap myVS(strike, indexStart , indexEnd, floatingTenor, fixedTenor, lmmTenorStructure);
	LmmVanillaSwapPricer myVSP(lmmTenorStructure);
	double prix_swap=myVSP.swapNPV_Analytical_1(myVS, myInitialLibor);


	//GeneticSwap test
	//build geneticVanillaSwap
	GenericSwap_CONSTPTR vanillaSwap_Genetic=InstrumentFactory::createVanillaSwap(
		strike,indexStart,indexEnd,floatingTenor,fixedTenor,lmmTenorStructure,1.0);

	GenericVanillaSwapPricer_PTR geneticVanillaSwapPricer(new GenericVanillaSwapPricer());
	double geneticPrice=geneticVanillaSwapPricer->genericVanillaSwap_Analytical(vanillaSwap_Genetic, myInitialLibor);

	cout << "FirstVersionSwapPrice: "	<<	prix_swap				<< endl;
	cout << "GeneticSwapTest:       "	<<	geneticPrice			<< endl;
	cout << "Difference:            "	<<	geneticPrice-prix_swap	<< endl;
}
Exemple #2
0
void test_TruncatedLocalResetGMatrixMapping()
{
	{
		size_t nbYear = 6;
		Tenor tenorfixedleg = Tenor::_1YR;
		Tenor tenorfloatleg = Tenor::_6M;
		const double increment_matrix = 10;

		LMMTenorStructure_PTR pLmmTenorStructure( new LMMTenorStructure(tenorfloatleg, nbYear) );

		size_t fixedfloatRatio = tenorfixedleg.ratioTo(tenorfloatleg);
		size_t horizon = pLmmTenorStructure->get_horizon() ;

		size_t        g_matrix_size = GMatrixMapping::get_gSizeFromNbYear(nbYear,fixedfloatRatio );
		size_t delegate_matrix_size = GMatrixMapping::get_gDelegateSizeFromHorizon(horizon,fixedfloatRatio );

		UpperTriangularDoubleMatrix empty_delegate_matrix(delegate_matrix_size,delegate_matrix_size);

		Initiate_UpperTriangularDoubleMatrix(empty_delegate_matrix, increment_matrix);

		UpperTriangleVanillaSwaptionQuotes_ConstPTR atm_swaption_implied_vol_ptr = create_UpperTriangleVanillaSwaptionQuotes(pLmmTenorStructure, tenorfixedleg, tenorfloatleg);

		GMatrixMapping gMatrixMapping(
			g_matrix_size
			, empty_delegate_matrix
			, atm_swaption_implied_vol_ptr->get_UpperTriangularIndexPairMatrix() );

		std::vector<size_t> truncated_cols;
		truncated_cols.push_back(2);
		truncated_cols.push_back(3);

		std::vector<size_t> truncated_rows;
		truncated_rows.push_back(2);
		truncated_rows.push_back(3);

		gMatrixMapping.reset_Truncated_gDelegate_Rows(truncated_rows);
		gMatrixMapping.reset_Truncated_gDelegate_Cols(truncated_cols);
		std::vector<size_t> non_truncated_row = get_NonTruncatedIndices(truncated_rows,nbYear);

		size_t value_counter=1;
		for(size_t iRow=0;iRow<non_truncated_row.size();++iRow)
		{
			const size_t iDelegate = non_truncated_row[iRow];

			QuantLib::Array x = gMatrixMapping.get_DelegateArray(iDelegate);
			for(size_t jX=0;jX<x.size();++jX)
			{
				x[jX]=value_counter*0.1;
				++value_counter;
			}
			gMatrixMapping.reset_gDelegate(x,iDelegate);
			std::cout<<" Delegate Row["<<iDelegate<<"]   "<<x<<std::endl;
			std::ostringstream local_gDelegate_file; 
			local_gDelegate_file<< "test_TruncatedLocalResetGMatrixMapping_"<<iDelegate<<"thRow.csv";

			gMatrixMapping.print(local_gDelegate_file.str() );
		}
	}

}
Exemple #3
0
void test_LocalResetGMatrixMapping()
{
	std::cout<<"hello test_LocalResetGMatrixMapping() "<<std::endl;

	size_t nbYear = 5;
	Tenor tenorfixedleg = Tenor::_1YR;
	Tenor tenorfloatleg = Tenor::_6M;
	const double increment_matrix = 10;

	LMMTenorStructure_PTR pLmmTenorStructure( new LMMTenorStructure(tenorfloatleg, nbYear) );

	size_t fixedfloatRatio = tenorfixedleg.ratioTo(tenorfloatleg);
	size_t horizon = pLmmTenorStructure->get_horizon() ;

	size_t        g_matrix_size = GMatrixMapping::get_gSizeFromNbYear(nbYear,fixedfloatRatio );
	size_t delegate_matrix_size = GMatrixMapping::get_gDelegateSizeFromHorizon(horizon,fixedfloatRatio );

	UpperTriangularDoubleMatrix empty_delegate_matrix(delegate_matrix_size,delegate_matrix_size);

	UpperTriangleVanillaSwaptionQuotes_ConstPTR atm_swaption_implied_vol_ptr = create_UpperTriangleVanillaSwaptionQuotes(pLmmTenorStructure, tenorfixedleg, tenorfloatleg);

	GMatrixMapping gMatrixMapping(
		g_matrix_size
		, empty_delegate_matrix
		, atm_swaption_implied_vol_ptr->get_UpperTriangularIndexPairMatrix() );

	gMatrixMapping.print("test_LocalResetGMatrixMapping_init.csv");

	Initiate_UpperTriangularDoubleMatrix(empty_delegate_matrix, increment_matrix);

	// loop reset delegate rows
	size_t max_DelegateRowIndex =	gMatrixMapping.get_MaxDelegateRowIndex();

	for(size_t iRowDelegate=1;iRowDelegate<=max_DelegateRowIndex;++iRowDelegate)
	{
		QuantLib::Array row_values = gMatrixMapping.get_DelegateArray(iRowDelegate);
		for(size_t jarray=0;jarray<row_values.size();++jarray)
		{
			size_t jColDelegate = jarray+1;
			row_values[jarray] = empty_delegate_matrix(iRowDelegate,jColDelegate);
			gMatrixMapping.reset_gDelegate(row_values,iRowDelegate);

			std::ostringstream local_gDelegate_file; 
			local_gDelegate_file<< "test_LocalResetGMatrixMapping_reset_"<<iRowDelegate<<"th-Col.csv";
			gMatrixMapping.print( local_gDelegate_file.str() );
		}	
	}

	check_gMatrix(gMatrixMapping.get_g_Ref(), increment_matrix);
}
Exemple #4
0
void test_CascadeResetGMatrixMapping()
{
	{
		size_t nbYear = 5;
		Tenor tenorfixedleg = Tenor::_1YR;
		Tenor tenorfloatleg = Tenor::_6M;
		const double increment_matrix = 10;

		LMMTenorStructure_PTR pLmmTenorStructure( new LMMTenorStructure(tenorfloatleg, nbYear) );

		size_t fixedfloatRatio = tenorfixedleg.ratioTo(tenorfloatleg);
		size_t horizon = pLmmTenorStructure->get_horizon() ;

		size_t        g_matrix_size = GMatrixMapping::get_gSizeFromNbYear(nbYear,fixedfloatRatio );
		size_t delegate_matrix_size = GMatrixMapping::get_gDelegateSizeFromHorizon(horizon,fixedfloatRatio );

		UpperTriangularDoubleMatrix empty_delegate_matrix(delegate_matrix_size,delegate_matrix_size);

		UpperTriangleVanillaSwaptionQuotes_ConstPTR atm_swaption_implied_vol_ptr = create_UpperTriangleVanillaSwaptionQuotes(pLmmTenorStructure, tenorfixedleg, tenorfloatleg);

		GMatrixMapping gMatrixMapping(
			g_matrix_size
			, empty_delegate_matrix
			, atm_swaption_implied_vol_ptr->get_UpperTriangularIndexPairMatrix() );

		gMatrixMapping.print("test_CascadeResetGMatrixMapping_init.csv");

		Initiate_UpperTriangularDoubleMatrix(empty_delegate_matrix, increment_matrix);

		// loop reset delegate rows
		size_t max_DelegateRowIndex =	gMatrixMapping.get_MaxDelegateRowIndex();

		for(size_t iRowDelegate=1;iRowDelegate<=max_DelegateRowIndex;++iRowDelegate)
		{
			size_t max_DelegateColIndex = delegate_matrix_size - (iRowDelegate+1);

			for(size_t jColDelegate=1;jColDelegate<=max_DelegateColIndex;++jColDelegate)
			{
				std::pair<size_t,size_t> gDelegate_cell(iRowDelegate,jColDelegate);
				gMatrixMapping.reset_gDelegate(empty_delegate_matrix(iRowDelegate,jColDelegate) ,gDelegate_cell);

				std::ostringstream local_gDelegate_file; 
				local_gDelegate_file<< "test_CascadeResetGMatrixMapping_reset_"<<iRowDelegate<<"row_"<< jColDelegate<<"col"  <<".csv";
				gMatrixMapping.print( local_gDelegate_file.str() );	
			}	
		}
	}
}
Exemple #5
0
void test_GlobalResetGMatrixMapping()
{
	std::cout<<"hello test_GlobalResetGMatrixMapping() "<<std::endl;

	size_t nbYear = 5;
	Tenor tenorfixedleg = Tenor::_1YR;
	Tenor tenorfloatleg = Tenor::_6M;
	const double increment_matrix = 10;

	LMMTenorStructure_PTR pLmmTenorStructure( new LMMTenorStructure(tenorfloatleg, nbYear) );

	size_t fixedfloatRatio = tenorfixedleg.ratioTo(tenorfloatleg);
	size_t horizon = pLmmTenorStructure->get_horizon() ;

	size_t        g_matrix_size = GMatrixMapping::get_gSizeFromNbYear(nbYear,fixedfloatRatio );
	size_t delegate_matrix_size = GMatrixMapping::get_gDelegateSizeFromHorizon(horizon,fixedfloatRatio );

	UpperTriangularDoubleMatrix empty_delegate_matrix(delegate_matrix_size,delegate_matrix_size);

	Initiate_UpperTriangularDoubleMatrix(empty_delegate_matrix, increment_matrix);

	UpperTriangleVanillaSwaptionQuotes_ConstPTR atm_swaption_implied_vol_ptr = create_UpperTriangleVanillaSwaptionQuotes(pLmmTenorStructure, tenorfixedleg, tenorfloatleg);

	GMatrixMapping gMatrixMapping(
		g_matrix_size
		, empty_delegate_matrix
		, atm_swaption_implied_vol_ptr->get_UpperTriangularIndexPairMatrix() );

	gMatrixMapping.print("test_GlobalResetGMatrixMapping.csv");

	//check_gMatrix(gMatrixMapping.get_g_Ref(), increment_matrix);

	QuantLib::Array x = gMatrixMapping.get_DelegateArray();

	std::cout<<std::endl<<std::endl<<x<<std::endl;

	LmmGnuplotPrinterMatrix gnuplot_printer(pLmmTenorStructure);
	const LowerTriangularDoubleMatrix& lower_matrix = gMatrixMapping.get_g_Ref();

	gnuplot_printer.printVolMatrix(lower_matrix,"test_GlobalResetGMatrixMapping");
}
Exemple #6
0
void test_TruncatedCascadeResetGMatrixMapping()
{
	// use of reset parallelograme truncated row
	{
		size_t nbYear = 5;
		Tenor tenorfixedleg = Tenor::_1YR;
		Tenor tenorfloatleg = Tenor::_6M;
		const double increment_matrix = 10;

		LMMTenorStructure_PTR pLmmTenorStructure( new LMMTenorStructure(tenorfloatleg, nbYear) );

		size_t fixedfloatRatio = tenorfixedleg.ratioTo(tenorfloatleg);
		size_t horizon = pLmmTenorStructure->get_horizon() ;

		size_t        g_matrix_size = GMatrixMapping::get_gSizeFromNbYear(nbYear,fixedfloatRatio );
		size_t delegate_matrix_size = GMatrixMapping::get_gDelegateSizeFromHorizon(horizon,fixedfloatRatio );

		UpperTriangularDoubleMatrix empty_delegate_matrix(delegate_matrix_size,delegate_matrix_size);

		UpperTriangleVanillaSwaptionQuotes_ConstPTR atm_swaption_implied_vol_ptr = create_UpperTriangleVanillaSwaptionQuotes(pLmmTenorStructure, tenorfixedleg, tenorfloatleg);

		GMatrixMapping gMatrixMapping(
			g_matrix_size
			, empty_delegate_matrix
			, atm_swaption_implied_vol_ptr->get_UpperTriangularIndexPairMatrix() );

		gMatrixMapping.print("test_TruncatedCascadeResetGMatrixMapping_init.csv");

		//Initiate_UpperTriangularDoubleMatrixConstantDiagonal(empty_delegate_matrix, increment_matrix);
		Initiate_UpperTriangularDoubleMatrix(empty_delegate_matrix, increment_matrix);

		std::vector<std::pair<size_t,size_t> > truncated_cells;

		truncated_cells.push_back(std::pair<size_t,size_t>(1,1) );
		//truncated_cells.push_back(std::pair<size_t,size_t>(1,4) );
		//truncated_cells.push_back(std::pair<size_t,size_t>(2,2) );
		//truncated_cells.push_back(std::pair<size_t,size_t>(4,1) );
				
		for(size_t i=0;i<truncated_cells.size();++i)
		{
			gMatrixMapping.add_Truncated_gDelegate_Cells(truncated_cells[i]);
		}
		
		// loop reset delegate rows
		size_t max_DelegateRowIndex =	gMatrixMapping.get_MaxDelegateRowIndex();

		for(size_t iRowDelegate=1;iRowDelegate<=max_DelegateRowIndex;++iRowDelegate)
		{

			size_t max_DelegateColIndex = delegate_matrix_size - (iRowDelegate+1);

			for(size_t jColDelegate=1;jColDelegate<=max_DelegateColIndex;++jColDelegate)
			{
				std::pair<size_t,size_t> gDelegate_cell(iRowDelegate,jColDelegate);
				if( std::find(truncated_cells.begin(),truncated_cells.end(),gDelegate_cell) == truncated_cells.end() )
				{
						std::pair<size_t,size_t> gDelegate_cell(iRowDelegate,jColDelegate);
						gMatrixMapping.reset_gDelegate(empty_delegate_matrix(iRowDelegate,jColDelegate) , gDelegate_cell);

						std::ostringstream local_gDelegate_file; 
						local_gDelegate_file<< "test_TruncatedCascadeResetGMatrixMapping_reset_"<<iRowDelegate<<"row_"<< jColDelegate<<"col"  <<".csv";
						gMatrixMapping.print( local_gDelegate_file.str() );	
				}
			}	
		}
	}
}
Exemple #7
0
void test_TruncatedGlobalResetGMatrixMapping()
{
	{
		size_t nbYear = 6;
		Tenor tenorfixedleg = Tenor::_1YR;
		Tenor tenorfloatleg = Tenor::_6M;
		const double increment_matrix = 10;

		LMMTenorStructure_PTR pLmmTenorStructure( new LMMTenorStructure(tenorfloatleg, nbYear) );

		size_t fixedfloatRatio = tenorfixedleg.ratioTo(tenorfloatleg);
		size_t horizon = pLmmTenorStructure->get_horizon() ;

		size_t        g_matrix_size = GMatrixMapping::get_gSizeFromNbYear(nbYear,fixedfloatRatio );
		size_t delegate_matrix_size = GMatrixMapping::get_gDelegateSizeFromHorizon(horizon,fixedfloatRatio );

		UpperTriangularDoubleMatrix empty_delegate_matrix(delegate_matrix_size,delegate_matrix_size);

		Initiate_UpperTriangularDoubleMatrix(empty_delegate_matrix, increment_matrix);

		UpperTriangleVanillaSwaptionQuotes_ConstPTR atm_swaption_implied_vol_ptr = create_UpperTriangleVanillaSwaptionQuotes(pLmmTenorStructure, tenorfixedleg, tenorfloatleg);

		GMatrixMapping gMatrixMapping(
			g_matrix_size
			, empty_delegate_matrix
			, atm_swaption_implied_vol_ptr->get_UpperTriangularIndexPairMatrix() );

		std::vector<std::pair<size_t,size_t> > truncated_cells;
		truncated_cells.push_back( std::pair<size_t,size_t>(1,1) );
		truncated_cells.push_back( std::pair<size_t,size_t>(1,5) );
		truncated_cells.push_back( std::pair<size_t,size_t>(5,1) );
				
		for(size_t iCell=0;iCell<truncated_cells.size();++iCell)
		{
			gMatrixMapping.add_Truncated_gDelegate_Cells( truncated_cells[iCell] );
		}

		QuantLib::Array x = gMatrixMapping.get_DelegateArray();

		for(size_t i=0;i<x.size();++i){ x[i]=(1+i)*0.1;}
			
		gMatrixMapping.reset_gDelegate(x);

		gMatrixMapping.print("test_TruncatedGlobalResetGMatrixMapping_Extrapolation.csv");
	}

		{
		size_t nbYear = 6;
		Tenor tenorfixedleg = Tenor::_1YR;
		Tenor tenorfloatleg = Tenor::_6M;
		const double increment_matrix = 10;

		LMMTenorStructure_PTR pLmmTenorStructure( new LMMTenorStructure(tenorfloatleg, nbYear) );

		size_t fixedfloatRatio = tenorfixedleg.ratioTo(tenorfloatleg);
		size_t horizon = pLmmTenorStructure->get_horizon() ;

		size_t        g_matrix_size = GMatrixMapping::get_gSizeFromNbYear(nbYear,fixedfloatRatio );
		size_t delegate_matrix_size = GMatrixMapping::get_gDelegateSizeFromHorizon(horizon,fixedfloatRatio );

		UpperTriangularDoubleMatrix empty_delegate_matrix(delegate_matrix_size,delegate_matrix_size);

		Initiate_UpperTriangularDoubleMatrix(empty_delegate_matrix, increment_matrix);

		UpperTriangleVanillaSwaptionQuotes_ConstPTR atm_swaption_implied_vol_ptr = create_UpperTriangleVanillaSwaptionQuotes(pLmmTenorStructure, tenorfixedleg, tenorfloatleg);

		GMatrixMapping gMatrixMapping(
			g_matrix_size
			, empty_delegate_matrix
			, atm_swaption_implied_vol_ptr->get_UpperTriangularIndexPairMatrix() );

		std::vector<std::pair<size_t,size_t> > truncated_cells;
		truncated_cells.push_back( std::pair<size_t,size_t>(2,2) );
		truncated_cells.push_back( std::pair<size_t,size_t>(1,3) );
		truncated_cells.push_back( std::pair<size_t,size_t>(3,1) );
		truncated_cells.push_back( std::pair<size_t,size_t>(3,3) );

		for(size_t iCell=0;iCell<truncated_cells.size();++iCell)
		{
			gMatrixMapping.add_Truncated_gDelegate_Cells( truncated_cells[iCell] );
		}

		QuantLib::Array x = gMatrixMapping.get_DelegateArray();

		for(size_t i=0;i<x.size();++i){ x[i]=(1+i)*0.1;}
			
		gMatrixMapping.reset_gDelegate(x);

		gMatrixMapping.print("test_TruncatedGlobalResetGMatrixMapping_Interpolation.csv");
	}


	//{
	//	size_t nbYear = 6;
	//	Tenor tenorfixedleg = Tenor::_1YR;
	//	Tenor tenorfloatleg = Tenor::_6M;
	//	const double increment_matrix = 10;

	//	LMMTenorStructure_PTR pLmmTenorStructure( new LMMTenorStructure(tenorfloatleg, nbYear) );

	//	size_t fixedfloatRatio = tenorfixedleg.ratioTo(tenorfloatleg);
	//	size_t horizon = pLmmTenorStructure->get_horizon() ;

	//	size_t        g_matrix_size = GMatrixMapping::get_gSizeFromNbYear(nbYear,fixedfloatRatio );
	//	size_t delegate_matrix_size = GMatrixMapping::get_gDelegateSizeFromHorizon(horizon,fixedfloatRatio );

	//	UpperTriangularDoubleMatrix empty_delegate_matrix(delegate_matrix_size,delegate_matrix_size);

	//	Initiate_UpperTriangularDoubleMatrix(empty_delegate_matrix, increment_matrix);

	//	UpperTriangleVanillaSwaptionQuotes_ConstPTR atm_swaption_implied_vol_ptr = create_UpperTriangleVanillaSwaptionQuotes(pLmmTenorStructure, tenorfixedleg, tenorfloatleg);

	//	GMatrixMapping gMatrixMapping(
	//		g_matrix_size
	//		, empty_delegate_matrix
	//		, atm_swaption_implied_vol_ptr->get_UpperTriangularIndexPairMatrix() );

	//	std::vector<size_t> truncated_rows;
	//	truncated_rows.push_back(1);
	//	truncated_rows.push_back(3);
	//	truncated_rows.push_back(5);

	//	gMatrixMapping.reset_Truncated_gDelegate_Rows(truncated_rows);

	//	QuantLib::Array x = gMatrixMapping.get_DelegateArray();
	//	for(size_t i=0;i<x.size();++i){ x[i]=(1+i)*0.1;}
	//	gMatrixMapping.reset_gDelegate(x);

	//	gMatrixMapping.print("test_TruncatedGlobalResetGMatrixMapping_Row.csv");
	//}

	//{
	//	size_t nbYear = 6;
	//	Tenor tenorfixedleg = Tenor::_1YR;
	//	Tenor tenorfloatleg = Tenor::_6M;
	//	const double increment_matrix = 10;

	//	LMMTenorStructure_PTR pLmmTenorStructure( new LMMTenorStructure(tenorfloatleg, nbYear) );

	//	size_t fixedfloatRatio = tenorfixedleg.ratioTo(tenorfloatleg);
	//	size_t horizon = pLmmTenorStructure->get_horizon() ;

	//	size_t        g_matrix_size = GMatrixMapping::get_gSizeFromNbYear(nbYear,fixedfloatRatio );
	//	size_t delegate_matrix_size = GMatrixMapping::get_gDelegateSizeFromHorizon(horizon,fixedfloatRatio );

	//	UpperTriangularDoubleMatrix empty_delegate_matrix(delegate_matrix_size,delegate_matrix_size);

	//	Initiate_UpperTriangularDoubleMatrix(empty_delegate_matrix, increment_matrix);

	//	UpperTriangleVanillaSwaptionQuotes_ConstPTR atm_swaption_implied_vol_ptr = create_UpperTriangleVanillaSwaptionQuotes(pLmmTenorStructure, tenorfixedleg, tenorfloatleg);

	//	GMatrixMapping gMatrixMapping(
	//		g_matrix_size
	//		, empty_delegate_matrix
	//		, atm_swaption_implied_vol_ptr->get_UpperTriangularIndexPairMatrix() );

	//	std::vector<size_t> truncated_cols;
	//	truncated_cols.push_back(2);
	//	truncated_cols.push_back(3);

	//	std::vector<size_t> truncated_rows;
	//	truncated_rows.push_back(2);
	//	truncated_rows.push_back(3);

	//	gMatrixMapping.reset_Truncated_gDelegate_Rows(truncated_rows);
	//	gMatrixMapping.reset_Truncated_gDelegate_Cols(truncated_cols);

	//	QuantLib::Array x = gMatrixMapping.get_DelegateArray();
	//	for(size_t i=0;i<x.size();++i){ x[i]=(1+i)*0.1;}
	//	gMatrixMapping.reset_gDelegate(x);

	//	gMatrixMapping.print("test_TruncatedGlobalResetGMatrixMapping_ColRow.csv");
	//}

}
UpperTriangleVanillaSwaptionQuotes_ConstPTR UpperTriangleVanillaSwaptionQuotes::create_ATMSwaptionImpliedVol
	(
	LiborQuotes_ConstPTR libor_quotes_ptr,
	const Tenor&  fixedTenor,
	const Tenor&  floatingTenor,
	LmmVanillaSwaptionApproxPricer_Rebonato_PTR black_vol_approx_ptr,
	const double&  strike_bump
	)
{
	LMMTenorStructure_PTR pLMMTenorStructure = libor_quotes_ptr->get_LMMTenorStructure_PTR() ;
	size_t fix_float_ratio = fixedTenor.ratioTo(floatingTenor);
	size_t lastLiborIndex  = pLMMTenorStructure->get_nbLIBOR()-1;
	assert(lastLiborIndex%fix_float_ratio == 0);
	size_t last_year = lastLiborIndex / fix_float_ratio ;

	size_t matrix_size = last_year + 1 ;
	UpperTriangularDoubleMatrix swap_rate_matrix(matrix_size,matrix_size);
	UpperTriangularDoubleMatrix black_vol_matrix(matrix_size,matrix_size);

	//first row and first column never used
	for(size_t k=0;k<matrix_size;++k)
	{
		swap_rate_matrix(k,0) = -1000000; swap_rate_matrix(0,k) = -1000000;
		black_vol_matrix(k,0) = -1000000; black_vol_matrix(0,k) = -1000000;
	}


	const std::vector<double> & init_libor = libor_quotes_ptr->get_InitLibor();
	LmmVanillaSwapPricer swap_pricer(pLMMTenorStructure);
	for(size_t iMaturity=1;iMaturity<matrix_size;++iMaturity)
	{
		for(size_t jTenor=1;jTenor<matrix_size - iMaturity ;++jTenor)
		{
			size_t start_swap_index = iMaturity * fix_float_ratio;
			size_t end_swap_index   = (iMaturity+jTenor) * fix_float_ratio;	

			double empty_strike = -100000000;
			VanillaSwap swap_ij(empty_strike,start_swap_index,end_swap_index,floatingTenor,fixedTenor,pLMMTenorStructure);
			double swap_rate_ij = strike_bump+swap_pricer.swapRate_Analytical(swap_ij,init_libor);

			swap_ij.set_strike(swap_rate_ij);
			swap_rate_matrix(iMaturity,jTenor) = swap_rate_ij;

			VanillaSwaption swaption_ij(swap_ij, OptionType::OptionType::CALL);
			double black_vol_ij = black_vol_approx_ptr->volBlack(swaption_ij,init_libor);

			black_vol_matrix(iMaturity,jTenor)=black_vol_ij;
		}
	}

	UpperTriangleVanillaSwaptionQuotes_PTR atm_swaption_implied_vol 
		(new UpperTriangleVanillaSwaptionQuotes(
		pLMMTenorStructure,
		last_year,
		fixedTenor,
		floatingTenor,
		swap_rate_matrix,
		black_vol_matrix
		) 
		);

	atm_swaption_implied_vol->set_Data_FileName("VirtuallyCreatedData");

	return atm_swaption_implied_vol;
}
void Test_McGeneticSwapLMMPricer()
{

	//! Parameters
	double	strike			=	0.02;
	LMM::Index	indexStart	=	0;
	LMM::Index	indexEnd	=	20;
	Tenor	floatingTenor	=	Tenor::_6M;
	Tenor	fixedTenor		=	Tenor::_12M;
	Tenor	tenorStruture	=	Tenor::_6M;
	size_t	horizonYear		=	10;
	LMMTenorStructure_PTR lmmTenorStructure( new LMMTenorStructure(tenorStruture, horizonYear));

	cout	<<	"strike:                        "	<<	strike												<<	endl;
	cout	<<	"indexStart:                    "	<<	indexStart											<<	endl;
	cout	<<	"indexEnd:                      "	<<	indexEnd											<<	endl;
	cout	<<	"tenorStrutureYearFraction:     "	<<	lmmTenorStructure->get_tenorType().YearFraction()	<<	endl;
	cout	<<	"floatingVStenorStrutureRatio:  "	<<	floatingTenor.ratioTo(tenorStruture)				<<	endl;
	cout	<<	"fixedVStenorStrutureRatio:     "	<<	fixedTenor.ratioTo(tenorStruture)					<<	endl;

	double	fwdRate		=	0.02;
	std::vector<double> liborsInitValue(lmmTenorStructure->get_horizon()+1, fwdRate);
	cout	<<	"myInitialLibor:  ";
	for (size_t i = 0; i <liborsInitValue.size(); i++)
	{
		cout	<<	liborsInitValue[i]	<<	" ";
	}
	cout	<<	 endl;
	cout	<<	 endl;


	//VanillaSwap_Chi_Trang
	VanillaSwap firstVersionVanillaSwap(strike, indexStart , indexEnd, floatingTenor, fixedTenor, lmmTenorStructure);
	LmmVanillaSwapPricer myVSP(lmmTenorStructure);
	double FirstVersionSwapPrice	=	myVSP.swapNPV_Analytical_1(firstVersionVanillaSwap, liborsInitValue);

	//---------------------------Build Lmm and McLmm's structure--------------------------------------
	//! Parameter of h
	double a = -0.06;
	double b = 0.17;
	double c = 0.54;
	double d = 0.17;
	Shifted_HGVolatilityParam::ABCDParameter abcdParam (a,b,c,d);
	//Parameter of hg
	double g_constParam = 1.0;
	double shift_constParam = -0.01;
	ConstShifted_HGVolatilityParam_PTR hgParam( new ConstShifted_HGVolatilityParam(lmmTenorStructure,abcdParam,g_constParam,shift_constParam));
	
	//! Correlation 1
	size_t nbFactor       = 3; // need to test nbFactor  = 3, and nbFactor = 
	size_t correlFullRank = lmmTenorStructure->get_horizon()+1;
	size_t correlReducedRank = nbFactor;
	//!"Check Parameters(): Condition not implemented yet."
	std::cout << "checkParams(): ";
	CorrelationReductionType::CorrelationReductionType correlReductionType = CorrelationReductionType::PCA;
	double correlAlpha = 0.0;
	double correlBeta  = 0.1;
	Correlation_PTR correlation(new XY_beta_Correlation(correlFullRank,correlReducedRank, correlReductionType,correlAlpha,correlBeta));
	correlation->calculate(); // for print.
	correlation->print("test_McTerminalLmm_Correlation.csv");
	//hgVolatilityFunction
	ConstShifted_HGVolatilityFunction_PTR hgVolatilityFunction (new ConstShifted_HGVolatilityFunction(lmmTenorStructure, correlation, hgParam)); 
	hgVolatilityFunction->print("test_McTerminalLmm_Volatility.csv");
	//! Dispersion
	Dispersion dispersion(hgVolatilityFunction);

	unsigned long seed = 5033;
	RNGenerator_PTR  rnGenerator(new McGenerator(seed));

	//build lmm and mcLmm model
	Lmm_PTR shiftedLmm (new Lmm(dispersion));
	McLmm_PTR mcLmm(new McTerminalLmm(shiftedLmm, liborsInitValue, rnGenerator, MCSchemeType::EULER));

	//build a McGeneticSwapLMMPricer
	McGeneticSwapLMMPricer_PTR mcGeneticSwapLMMPricer(new McGeneticSwapLMMPricer(mcLmm));

	//build the geneticVanillaSwap
	GeneticSwap_CONSTPTR vanillaSwap_Genetic=InstrumentFactory::createVanillaSwap(
			strike,indexStart,indexEnd,floatingTenor,fixedTenor,lmmTenorStructure,1.0);

	//use Monte Carlo Method
	size_t nbSimulation=10000;
	double	MonteCarloPrice		=	mcGeneticSwapLMMPricer->swapNPV(vanillaSwap_Genetic, nbSimulation);

	//ordinaryGeneticVanillaSwapPricer
	GeneticVanillaSwapPricer_PTR geneticVanillaSwapPricer(new GeneticVanillaSwapPricer());
	double	OrdinaryGeneticVanillaSwapPrice		=	geneticVanillaSwapPricer->geneticVanillaSwap_Analytical(vanillaSwap_Genetic,liborsInitValue);

	//subVanillaSwap
	LMM::Index	subIndexStart	=	10;
	LMM::Index	subIndexEnd		=	16;
	GeneticSwap_CONSTPTR subVanillaSwap_Genetic=InstrumentFactory::createVanillaSwap(
			strike,subIndexStart,subIndexEnd,floatingTenor,fixedTenor,lmmTenorStructure,1.0);
	double	subMonteCarloPrice	=	mcGeneticSwapLMMPricer->swapNPV(subVanillaSwap_Genetic, nbSimulation);
	//subOrdinaryGeneticVanillaSwapPrice
	double	subOrdinaryGeneticVanillaSwapPrice		=	geneticVanillaSwapPricer->geneticVanillaSwap_Analytical(subVanillaSwap_Genetic,liborsInitValue);
	//subFirstVersionVanillaSwapPrice
	VanillaSwap subFirstVersionVanillaSwap(strike, subIndexStart , subIndexEnd, floatingTenor, fixedTenor, lmmTenorStructure);
	double subFirstVersionSwapPrice		=	myVSP.swapNPV_Analytical_1(subFirstVersionVanillaSwap, liborsInitValue);


	cout	<<	"MonteCarloPrice: "																		<<	MonteCarloPrice													<<	endl;
	cout	<<	"OrdinaryGeneticVanillaSwapPrice: "														<<	OrdinaryGeneticVanillaSwapPrice									<<	endl;
	cout	<< "FirstVersionSwapPrice: "																<< FirstVersionSwapPrice											<< endl;
	cout	<<	"Difference between MonteCarloPrice and OrdinaryGeneticVanillaSwapPrice: "				<<	MonteCarloPrice-OrdinaryGeneticVanillaSwapPrice					<<	endl;	
	cout	<<	"Difference between OrdinaryGeneticVanillaSwapPrice and FirstVersionSwapPrice: "		<<	OrdinaryGeneticVanillaSwapPrice-FirstVersionSwapPrice			<<	endl;	
	cout	<<	"subMonteCarloPrice: "																	<<	subMonteCarloPrice												<<	endl;
	cout	<<	"subOrdinaryGeneticVanillaSwapPrice: "													<<	subOrdinaryGeneticVanillaSwapPrice								<<	endl;
	cout	<< "subFirstVersionSwapPrice: "																<< subFirstVersionSwapPrice											<< endl;
	cout	<<	"Difference between subMonteCarloPrice and subOrdinaryGeneticVanillaSwapPrice: "		<<	subMonteCarloPrice-subOrdinaryGeneticVanillaSwapPrice			<<	endl;	
	cout	<<	"Difference between subOrdinaryGeneticVanillaSwapPrice and subFirstVersionSwapPrice: "	<<	subOrdinaryGeneticVanillaSwapPrice-subFirstVersionSwapPrice		<<	endl;

	ofstream o;
	o.open("TestResult_GeneticVanillaSwap_05_06.csv",  ios::out | ios::app );
	o	<<	endl;
	o	<<	endl;
	o	<<	endl;
	o	<<	"strike: "									<<	strike														<<	endl;
	o	<<	"indexStart: "								<<	indexStart													<<	endl;
	o	<<	"indexEnd: "								<<	indexEnd													<<	endl;
	o	<<	"floatingTenorVSLmmStructureTenorRatio: "	<<	floatingTenor.ratioTo(lmmTenorStructure->get_tenorType())	<<	endl;
	o	<<	"fixedTenorVSLmmStructureTenorRatio: "		<<	fixedTenor.ratioTo(lmmTenorStructure->get_tenorType())		<<	endl;
	o	<<	"floatingTenorYearFraction: "				<<	floatingTenor.YearFraction()								<<	endl;
	o	<<	"fixedTenorYearFraction: "					<<	fixedTenor.YearFraction()									<<	endl;
	o	<<	"horizonYear: "								<<	horizonYear													<<	endl;
	o	<<	"liborsInitValue: ";
	for(size_t i=0; i<liborsInitValue.size(); i++)
	{
		o	<<	liborsInitValue[i]	<<	" ";
	}
	o	<<	endl;
	o	<<	"nbSimulation: "																		<<	nbSimulation													<<	endl;
	o	<<	"PRICES: "	<<	endl;
	o	<<	"MonteCarloPrice: "																		<<	MonteCarloPrice													<<	endl;
	o	<<	"OrdinaryGeneticVanillaSwapPrice: "														<<	OrdinaryGeneticVanillaSwapPrice									<<	endl;
	o	<<	"FirstVersionSwapPrice: "																<< FirstVersionSwapPrice											<<	endl;
	o	<<	"Difference between MonteCarloPrice and OrdinaryGeneticVanillaSwapPrice: "				<<	MonteCarloPrice-OrdinaryGeneticVanillaSwapPrice					<<	endl;	
	o	<<	"Difference between OrdinaryGeneticVanillaSwapPrice and FirstVersionSwapPrice: "		<<	OrdinaryGeneticVanillaSwapPrice-FirstVersionSwapPrice			<<	endl;
	o	<<	"SUBPRICES: "<<	endl;
	o	<<	"subIndexStart: "																		<<	subIndexStart													<<	endl;
	o	<<	"subIndexEnd: "																			<<	subIndexEnd														<<	endl;
	o	<<	"subMonteCarloPrice: "																	<<	subMonteCarloPrice												<<	endl;
	o	<<	"subOrdinaryGeneticVanillaSwapPrice: "													<<	subOrdinaryGeneticVanillaSwapPrice								<<	endl;
	o	<<	"subFirstVersionSwapPrice: "															<< subFirstVersionSwapPrice											<<	endl;
	o	<<	"Difference between subMonteCarloPrice and subOrdinaryGeneticVanillaSwapPrice: "		<<	subMonteCarloPrice-subOrdinaryGeneticVanillaSwapPrice			<<	endl;	
	o	<<	"Difference between subOrdinaryGeneticVanillaSwapPrice and subFirstVersionSwapPrice: "	<<	subOrdinaryGeneticVanillaSwapPrice-subFirstVersionSwapPrice		<<	endl;	

	o.close();
}
Shifted_HGVolatilityFunction_PTR JB_marketData_LMM_ABCD_calibration(const LmmCalibrationConfig& config, LmmSwaptionMarketData_PTR pLmmSwaptionMarketData)
{
	std::string base_name = pLmmSwaptionMarketData->get_MarketDataBaseFileName() ;

	size_t nbYear = pLmmSwaptionMarketData->get_nbYear();
	Tenor tenorfixedleg = Tenor::_1YR ;      // A corriger
	Tenor tenorfloatleg = Tenor::_6M  ;
	size_t fixedfloatRatio = tenorfixedleg.ratioTo(tenorfloatleg);

	//create LMM components
	LMMTenorStructure_PTR pLMMTenorStructure( new LMMTenorStructure(tenorfloatleg,nbYear) );


	ConstShifted_HGVolatilityParam_PTR pNoShifted_HGVolatilityParam( new ConstShifted_HGVolatilityParam(pLMMTenorStructure, config.vol_abcd_ , 1., 0.));

	//! create correlation
	Correlation_PTR pCorrelation = JB_create_InitCorrelation(config);

	Shifted_HGVolatilityFunction_PTR pVolatilityFunction (new ConstShifted_HGVolatilityFunction(pLMMTenorStructure, pCorrelation, pNoShifted_HGVolatilityParam)); 
	Dispersion dispersion(pVolatilityFunction);
	Lmm_PTR lmm_ptr(new Lmm(dispersion) );

	//! Create Approximation Rebonato 
	LmmVanillaSwaptionApproxPricer_Rebonato_PTR pLmmVanillaSwaptionApproxPricer_Rebonato(new LmmVanillaSwaptionApproxPricer_Rebonato(lmm_ptr));	

	pLmmVanillaSwaptionApproxPricer_Rebonato->update_VolatilityParam(pNoShifted_HGVolatilityParam);

	LmmBaseCostFunction_PTR abcd_costFucntion (new LmmABCDCostFunction ( pLmmVanillaSwaptionApproxPricer_Rebonato
		, pLmmSwaptionMarketData->get_LiborQuotes()
		, pLmmSwaptionMarketData->get_SwaptionQuotes_ATM()
		, pNoShifted_HGVolatilityParam
		));

	QuantLib::Array init_abcd(4);
	init_abcd[0]=config.vol_abcd_.a_;
	init_abcd[1]=config.vol_abcd_.b_;
	init_abcd[2]=config.vol_abcd_.c_;
	init_abcd[3]=config.vol_abcd_.d_;

	size_t maxIterations = 1000;
	size_t minStatIterations = 100;
	double rootEpsilon =1e-14;
	double functionEpsilon =1e-14;
	double gradientNormEpsilon =0;

	LmmABCDCalibrator  lmm_abcd_calibrator(init_abcd, maxIterations, rootEpsilon,functionEpsilon,abcd_costFucntion);


	lmm_abcd_calibrator.add_ConstraintCell(std::pair<size_t,size_t>(1,1) );
	lmm_abcd_calibrator.add_ConstraintCell(std::pair<size_t,size_t>(2,2) );
	lmm_abcd_calibrator.add_ConstraintCell(std::pair<size_t,size_t>(1,3) );
	lmm_abcd_calibrator.add_ConstraintCell(std::pair<size_t,size_t>(3,1) );
	//lmm_abcd_calibrator.add_ConstraintCell(std::pair<size_t,size_t>(6,6) );
	//lmm_abcd_calibrator.add_ConstraintCell(std::pair<size_t,size_t>(8,8) );

	lmm_abcd_calibrator.activate_PositiveConstraint();
	lmm_abcd_calibrator.solve();

	std::string result_file =base_name + "_abcd_calibration_result.csv";
	lmm_abcd_calibrator.printPlusPlus(result_file);

	std::string calibrated_abcd_file = base_name + "_abcd_calibrated.csv";
	pNoShifted_HGVolatilityParam->print(calibrated_abcd_file);

	// print in a common file
	{
		std::string common_result_file_name = "calib_result_ABCD.csv";
		std::string full_common_result_file = LMMPATH::get_Root_OutputPath() + common_result_file_name ;

		std::ofstream final_result ;
		final_result.open(full_common_result_file.c_str(), std::ios::app);

		final_result<<std::endl<<std::endl<< "============= Test At    "<<LMMPATH::get_TimeDateNow()
			<<",,,,,, Error LInf, "<<lmm_abcd_calibrator.get_QuoteError_LInf() <<std::endl ;
		final_result<< lmm_abcd_calibrator.get_BaseGeneral_Result_Info();

		final_result.close();	
	}
	
	return pVolatilityFunction;
}
void Test_evaluation_basis()
{
	LMM::Index  indexStart = 2;		//1Y
	LMM::Index  indexEnd   = 20;		//10Y
	Tenor	floatingLegTenorType = Tenor::_6M;
	Tenor	fixedLegTenorType    = Tenor::_1YR;
	assert(indexStart%2==0&&indexEnd%2==0);
	LMMTenorStructure_PTR lmmTenorStructure( new LMMTenorStructure(floatingLegTenorType, indexEnd/2));

	std::vector<std::string> mkt_file_list = InputFileManager::get_VCUB_FileList();
	const std::string& mkt_data_file = mkt_file_list.back();
	std::string folder_name;   // = "TotalCalib\\" ;  config.use_positive_constraint_=true;
	std::string base_name_file = LMMPATH::get_BaseFileName(mkt_data_file) + "\\";
	folder_name+=base_name_file;
	LMMPATH::reset_Output_SubFolder(folder_name );

	LmmCalibrationConfig config;

	config.floatLegTenor_=floatingLegTenorType;
	config.fixedLegTenor_=fixedLegTenorType;

	config.model_nbYear_		=	indexEnd/2;
	size_t fixedFloatRatio		=	config.fixedLegTenor_.ratioTo(config.floatLegTenor_);
	config.correl_FullRank_		=	fixedFloatRatio*config.model_nbYear_+1;

	LmmSwaptionMarketData_PTR pLmmSwaptionMarketData	=	get_LmmSwaptionMarketData(config, mkt_data_file);
	const std::vector<double>&	initLiborValues			=	pLmmSwaptionMarketData->get_LiborQuotes()->get_InitLibor();

	double strike = 0.0137;

	std::vector<LMM::Index> exerciseDates;
	exerciseDates.push_back(2);
	//exerciseDates.push_back(4);
	//exerciseDates.push_back(6);
	//exerciseDates.push_back(8);
	//exerciseDates.push_back(10);
	//exerciseDates.push_back(12);
	//exerciseDates.push_back(14);
	//exerciseDates.push_back(16);
	//exerciseDates.push_back(18);
	exerciseDates.push_back(20);

	McLmm_PTR mcLmm_for_pricer = getMcLmmExample(lmmTenorStructure, initLiborValues, LmmCalibrationConfig());

	size_t fixedFloatingRatio = fixedLegTenorType.ratioTo(floatingLegTenorType);

	std::vector<std::vector<size_t>> subset;
	for(size_t i = 0; i <= 2; i++) 
	{
		subset.push_back(std::vector<size_t>());
		subset.back().push_back(0);
		subset.back().push_back(0);
		subset.back().push_back(i);							
	}
	//for(size_t j = 1; j <= 2; j++) 
	//{
	//	subset.push_back(std::vector<size_t>());
	//	subset.back().push_back(0);
	//	subset.back().push_back(j);
	//	subset.back().push_back(0);
	//}	
/*	for(size_t k = 1; k <= 2; k++) 
	{
		subset.push_back(std::vector<size_t>());
		subset.back().push_back(k);
		subset.back().push_back(0);
		subset.back().push_back(0);
	}	*/			



	size_t regressionIndex=2;
	LMM::Index liborIndex	= indexStart + regressionIndex*fixedFloatingRatio;
	LMM::Index paymentIndex = indexStart + regressionIndex*fixedFloatingRatio + 1;

	VanillaSwap vanillaSwap(	strike, 
								liborIndex, 
								indexEnd, 
								floatingLegTenorType, 
								fixedLegTenorType, 
								lmmTenorStructure);
		
	std::vector<Basis_CONSTPTR> basis_vect;
	std::vector<Basis_Evaluator_CONSTPTR> basis_evaluator_vect;

	for(size_t basisIndex = 0; basisIndex<subset.size(); basisIndex++)
	{
			basis_vect.push_back(getBasis(subset[basisIndex], 1.0, vanillaSwap, strike, liborIndex));
			basis_evaluator_vect.push_back(getBasisEvaluator(subset[basisIndex], McLmmVanillaSwapPricer(mcLmm_for_pricer)));	
	}

	LS::Regression rg(LS::RegressionRepresentation(basis_vect, basis_evaluator_vect));

	McLmm_PTR mcLmm = getMcLmmExample(lmmTenorStructure, initLiborValues, LmmCalibrationConfig());
	McLmm_LS mcLmm_LS(mcLmm);
	mcLmm_LS.simulateLMM(1);

	size_t nb = 30000;
	clock_t startTime = clock();
	std::vector<std::vector<double>> vect(nb);
	for(size_t i=0; i<nb; i++)
	{
		//rg.getRegressionRepresentation().evaluate_basis(mcLmm_LS.lmmSimualtionResults_[0]);
		vect[i].resize(3);
		vect[i]=rg.getRegressionRepresentation().getBasis_val_buffer();
		vect[i]=std::vector<double>(3, 1.0);
	}

	clock_t endTime = clock();

	clock_t time = endTime - startTime;
	double time_in_second = time/(double) CLOCKS_PER_SEC;

	cout << "time_in_second  "<< time_in_second << endl;

	const matrix& m = mcLmm_LS.lmmSimualtionResults_[0].get_liborMatrix();
	const std::vector<double>& numeraire = mcLmm_LS.lmmSimualtionResults_[0].get_numeraire();

	std::vector<size_t> basis1;
	basis1.push_back(1);
	basis1.push_back(0);
	basis1.push_back(0);
	Basis_CONSTPTR basisA=getBasis(basis1, 1.0, vanillaSwap, strike, liborIndex);
	Basis_Evaluator_CONSTPTR basis_EvaluatorA = getBasisEvaluator(basis1, McLmmVanillaSwapPricer(mcLmm_for_pricer));

	basis_EvaluatorA->evaluate(basisA,m, numeraire);
	clock_t startTime1 = clock();
	for(size_t i=0; i<1000; i++)
		basis_EvaluatorA->evaluate(basisA,m, numeraire);

	clock_t endTime1 = clock();

	clock_t time1 = endTime1 - startTime1;
	double time1_in_second = time1/(double) CLOCKS_PER_SEC;

	cout << "time1_in_second  "<< time1_in_second << endl;

	std::vector<size_t> basis2;
	basis2.push_back(0);
	basis2.push_back(1);
	basis2.push_back(0);
	Basis_CONSTPTR basisB=getBasis(basis2, 1.0, vanillaSwap, strike, liborIndex);
	Basis_Evaluator_CONSTPTR basis_EvaluatorB = getBasisEvaluator(basis2, McLmmVanillaSwapPricer(mcLmm_for_pricer));

	clock_t startTime2 = clock();
	for(size_t i=0; i<1000; i++)
		basis_EvaluatorB->evaluate(basisB, m, numeraire);

	clock_t endTime2 = clock();

	clock_t time2 = endTime2 - startTime2;
	double time2_in_second = time2/(double) CLOCKS_PER_SEC;

	cout << "time2_in_second  "<< time2_in_second << endl;

	std::vector<size_t> basis3;
	basis3.push_back(0);
	basis3.push_back(0);
	basis3.push_back(1);
	Basis_CONSTPTR basisC=getBasis(basis3, 1.0, vanillaSwap, strike, liborIndex);
	Basis_Evaluator_CONSTPTR basis_EvaluatorC = getBasisEvaluator(basis3, McLmmVanillaSwapPricer(mcLmm_for_pricer));

	
	clock_t startTime3 = clock();
	for(size_t i=0; i<1000; i++)
		basis_EvaluatorC->evaluate(basisC, m, numeraire);

	clock_t endTime3 = clock();

	clock_t time3 = endTime3 - startTime3;
	double time3_in_second = time3/(double) CLOCKS_PER_SEC;

	cout << "time3_in_second  "<< time3_in_second << endl;

	EV_Evaluator_CONSTPTR ev_evaluator_libor(new EV_LiborRate_Evaluator());
	EV_Evaluator_CONSTPTR ev_evaluator_swaprate(new EV_VanillaSwapRate_Evaluator(McLmmVanillaSwapPricer(mcLmm_for_pricer)));

	EV_CONSTPTR ev_swaprate(new EV_VanillaSwapRate( Rate1_CONSTPTR( new VanillaSwapRate(VanillaSwap(vanillaSwap)))));

	EV_CONSTPTR ev_libor(new EV_LiborRate(Rate1_CONSTPTR(new LiborRate(2,Tenor(Tenor::_6M)))));

	clock_t startTime4 = clock();
	for(size_t i=0; i<1000; i++)
		ev_evaluator_swaprate->evaluate(ev_swaprate,m,numeraire);

	clock_t endTime4 = clock();

	clock_t time4 = endTime4 - startTime4;
	double time4_in_second = time4/(double) CLOCKS_PER_SEC;

	cout << "time4_in_second  "<< time4_in_second << endl;



	clock_t startTime5 = clock();
	for(size_t i=0; i<1000; i++)
		ev_evaluator_libor->evaluate(ev_libor,m,numeraire);

	clock_t endTime5 = clock();

	clock_t time5 = endTime5 - startTime5;
	double time5_in_second = time5/(double) CLOCKS_PER_SEC;

	cout << "time5_in_second  "<< time5_in_second << endl;

}
Shifted_HGVolatilityFunction_PTR JB_marketData_LMM_shift_Calibration(	const LmmCalibrationConfig& config
											, LmmSwaptionMarketData_PTR pLmmSwaptionMarketData 
											, Shifted_HGVolatilityFunction_PTR param_h_g_function
											)
{
	assert(!config.use_local_calib_);
	size_t  nbYear= pLmmSwaptionMarketData->get_nbYear();
	std::string base_file_name = pLmmSwaptionMarketData->get_MarketDataBaseFileName();

	Tenor tenorfixedleg = Tenor::_1YR ;
	Tenor tenorfloatleg = Tenor::_6M  ;
	size_t fixedfloatRatio = tenorfixedleg.ratioTo(tenorfloatleg);

	std::string base_name;
	base_name = base_file_name+"_shift_gMatrix_Calibration" ;

	Shifted_HGVolatilityParam_PTR	param_h_g	=	param_h_g_function->get_ShiftedHGVolatilityParam_PTR();

	//create LMM components
	LMMTenorStructure_PTR pLMMTenorStructure( new LMMTenorStructure(tenorfloatleg,nbYear) );
	const double a=param_h_g->get_ABCD().a_;
	const double b=param_h_g->get_ABCD().b_;
	const double c=param_h_g->get_ABCD().c_;
	const double d=param_h_g->get_ABCD().d_;

	Shifted_HGVolatilityParam::ABCDParameter abcdParam(a,b,c,d);

	const Shifted_HGVolatilityParam::LowerTriangularMatrix& gMatrix=param_h_g->get_gMatrix();

	QuantLib::Array shiftValues_QL = param_h_g->get_ArrayFrom_Shift();
	std::vector<double> shiftValues(shiftValues_QL.size());
	for(size_t i=0; i<shiftValues_QL.size(); i++)
		shiftValues[i]=shiftValues_QL[i];
	//const std::vector<double> shiftedVector(gMatrix.size1(), 0.0);

	ConstShifted_HGVolatilityParam_PTR pShifted_HGVolatilityParam( new ConstShifted_HGVolatilityParam(
																pLMMTenorStructure, abcdParam, gMatrix, shiftValues));
	Shifted_HGVolatilityFunction_PTR pShifted_VolatilityFunction (new ConstShifted_HGVolatilityFunction(
										pLMMTenorStructure, param_h_g_function->get_Correlation_PTR(), pShifted_HGVolatilityParam)); 
	Dispersion dispersion(pShifted_VolatilityFunction);
	Lmm_PTR lmm_ptr(new Lmm(dispersion) );

	LmmVanillaSwaptionApproxPricer_Rebonato_PTR pLmmVanillaSwaptionApproxPricer_Rebonato(new LmmVanillaSwaptionApproxPricer_Rebonato(lmm_ptr));	

	// create gMatrixMapping
	//size_t        g_matrix_size = GMatrixMapping::get_gSizeFromNbYear(nbYear,fixedfloatRatio );
	//size_t delegate_matrix_size = GMatrixMapping::get_gDelegateSizeFromHorizon(pLMMTenorStructure->get_horizon() ,fixedfloatRatio );
	//UpperTriangularDoubleMatrix empty_delegate_matrix(delegate_matrix_size,delegate_matrix_size);



	//pShifted_HGVolatilityParam->reset_g_matrix(gMatrix);
	pLmmVanillaSwaptionApproxPricer_Rebonato->update_VolatilityParam(pShifted_HGVolatilityParam);

	// Create const function
	//LmmPenalty_PTR pLmmPenalty(new LmmPenalty(config.penalty_time_homogeneity_,config.penalty_libor_) );

	//LmmBaseCostFunction_PTR pLmmCostFunction(new LmmGlobal_gCostFunction
	//	(
	//	pLmmVanillaSwaptionApproxPricer_Rebonato,
	//	pLmmSwaptionMarketData->get_LiborQuotes(),
	//	pLmmSwaptionMarketData->get_SwaptionQuotes_ATM(),
	//	pGMatrixMapping,
	//	pNoShifted_HGVolatilityParam,
	//	pLmmPenalty
	//	) );

	const double const_rate=0.02;
	const double quoted_strike_bump=0.0001;
	LmmSwaptionMarketData_PTR lmmSwaptionMarketData(new LmmSwaptionMarketData(tenorfixedleg, tenorfloatleg, gMatrix.size1()+3));

	

	LmmSkewCostFunction lmmSkewCostFunction(	pLmmVanillaSwaptionApproxPricer_Rebonato                // pricer  
											   , pLmmSwaptionMarketData->get_LiborQuotes()
											   , quoted_strike_bump
											   , pLmmSwaptionMarketData->get_SwaptionQuotes_skew()// instrument to calibrate 
											   , param_h_g );

	//for(size_t i = 0; i < 3; i++)
	//{
	//	for (size_t j = 1; j < nbYear-i; j++)
	//		{
	//			lmmSkewCostFunction.addContraintCell(std::pair<size_t,size_t>(j,nbYear-i-j));
	//		}
	//}

	//costumize swaptions weights
	//UpperTriangularDoubleMatrix swpm_weight_matrix = pLmmCostFunction->get_SwaptionWeightMatrix();
	//swpm_weight_matrix(7,1)=1e-6;
	//swpm_weight_matrix(10,1)=1e-6;
	//swpm_weight_matrix(5,3)=0.;
	//pLmmCostFunction->reset_SwaptionWeightMatrix(swpm_weight_matrix);

	// Create Calibrator
	QuantLib::Array init_shift(gMatrix.size1(),0.01);
	



	LmmShiftCalibrator lmmShiftCalibrator							(	init_shift
																		, 200 //maxIter
																		, 1e-11   //x_epsilon
																		, 1e-11   //f_epsilon  
																		, lmmSkewCostFunction			
																	);


	//if(config.use_positive_constraint_)
	//	lmmShiftCalibrator.activate_PositiveConstraint();

	lmmShiftCalibrator.solve();

	std::ostringstream file_result_stream;file_result_stream<<base_name<<"_result.csv";
	std::string file_calibration_result(file_result_stream.str());
	lmmShiftCalibrator.printPlusPlus(file_calibration_result);

	std::ostringstream file_vol_stream; file_vol_stream<<base_name<<".csv";
	std::string file_calibrated_vol(file_vol_stream.str() );
	param_h_g->print(file_calibrated_vol);


	pLmmSwaptionMarketData->print("pLmmSwaptionMarketData.csv");

	//std::ostringstream file_result_stream;file_result_stream<<base_name<<penalty_info_str<<"_result.csv";
	//std::string file_calibration_result(file_result_stream.str());
	//lmmShiftCalibrator.printPlusPlus(file_calibration_result);


	//std::ostringstream file_vol_stream;file_vol_stream<<base_name<<penalty_info_str<<"_vol.csv";
	//std::string file_calibrated_vol(file_vol_stream.str() );
	//pShifted_HGVolatilityParam->print( file_calibrated_vol );


	//{
	//	std::string common_result_file_name = "calib_result_Shift_gGlobal.csv";

	//	std::string full_common_result_file = LMMPATH::get_Root_OutputPath() + common_result_file_name ;

	//	std::ofstream final_result ;
	//	final_result.open(full_common_result_file.c_str(), std::ios::app);

	//	final_result<<std::endl<<std::endl<< "============= Test At    "<<LMMPATH::get_TimeDateNow()
	//		<<",,,,,, Error LInf, "<<lmmShiftCalibrator.get_QuoteError_LInf() <<std::endl ;
	//	final_result<< lmmShiftCalibrator.get_BaseGeneral_Result_Info();

	//	final_result.close();	
	//}

	return pShifted_VolatilityFunction;
}
GMatrix_Vol_gMapping JB_marketData_LMM_Global_gCalibration( const LmmCalibrationConfig& config
															, LmmSwaptionMarketData_PTR pLmmSwaptionMarketData 
															, Shifted_HGVolatilityFunction_PTR shifted_HGVolatilityFunction
															, Correlation_PTR found_correlation_ptr  
															, GMatrixMapping_PTR init_gMapping
															)
{
	assert(!config.use_local_calib_);				//?
	size_t nbYear = pLmmSwaptionMarketData->get_nbYear();				//nbYear
	std::string base_file_name = pLmmSwaptionMarketData->get_MarketDataBaseFileName();			

	Tenor tenorfixedleg = Tenor::_1YR ;     
	Tenor tenorfloatleg = Tenor::_6M  ;
	size_t fixedfloatRatio = tenorfixedleg.ratioTo(tenorfloatleg);

	std::string base_name;
	base_name = base_file_name+"_gMatrixGlobalCalibration" ;

	Shifted_HGVolatilityParam_PTR shifted_HGVolatilityParam	=	shifted_HGVolatilityFunction->get_ShiftedHGVolatilityParam_PTR();

	//create LMM components
	LMMTenorStructure_PTR pLMMTenorStructure( new LMMTenorStructure(tenorfloatleg,nbYear) );

	const double a=shifted_HGVolatilityParam->get_ABCD().a_;
	const double b=shifted_HGVolatilityParam->get_ABCD().b_;
	const double c=shifted_HGVolatilityParam->get_ABCD().c_;
	const double d=shifted_HGVolatilityParam->get_ABCD().d_;

	QuantLib::Array shiftValues_QL = shifted_HGVolatilityParam->get_ArrayFrom_Shift();
	std::vector<double> shiftValues(shiftValues_QL.size());
	for(size_t i=0; i<shiftValues_QL.size(); i++)
		shiftValues[i]=shiftValues_QL[i];
	const Shifted_HGVolatilityParam::LowerTriangularMatrix pGMatrix(shifted_HGVolatilityParam->get_gMatrix());
	Shifted_HGVolatilityParam::ABCDParameter abcdParam(a,b,c,d);

	ConstShifted_HGVolatilityParam_PTR pShifted_HGVolatilityParam( new ConstShifted_HGVolatilityParam(
				pLMMTenorStructure, abcdParam, pGMatrix, shiftValues));

	Shifted_HGVolatilityFunction_PTR pVolatilityFunction (new ConstShifted_HGVolatilityFunction(pLMMTenorStructure,  found_correlation_ptr, pShifted_HGVolatilityParam)); 
	Dispersion dispersion(pVolatilityFunction);
	Lmm_PTR lmm_ptr(new Lmm(dispersion) );

	LmmVanillaSwaptionApproxPricer_Rebonato_PTR pLmmVanillaSwaptionApproxPricer_Rebonato(new LmmVanillaSwaptionApproxPricer_Rebonato(lmm_ptr));	

	// create gMatrixMapping
	size_t        g_matrix_size = GMatrixMapping::get_gSizeFromNbYear(nbYear,fixedfloatRatio );
	size_t delegate_matrix_size = GMatrixMapping::get_gDelegateSizeFromHorizon(pLMMTenorStructure->get_horizon() ,fixedfloatRatio );
	UpperTriangularDoubleMatrix empty_delegate_matrix(delegate_matrix_size,delegate_matrix_size);

	GMatrixMapping_PTR pGMatrixMapping;
	if(init_gMapping)
	{
		pGMatrixMapping = init_gMapping;
	}
	else
	{
		//initiate gMatrixMapping all gDelegate to 1
		pGMatrixMapping.reset( new GMatrixMapping(g_matrix_size, empty_delegate_matrix, pLmmSwaptionMarketData->get_SwaptionQuotes_ATM()->get_UpperTriangularIndexPairMatrix())  );
		QuantLib::Array g_delegate_vector =  pGMatrixMapping->get_DelegateArray();
		for(size_t i=0;i<g_delegate_vector.size();++i) g_delegate_vector[i] = 1.;
		pGMatrixMapping->reset_gDelegate(g_delegate_vector);
	}

	pShifted_HGVolatilityParam->reset_g_matrix( pGMatrixMapping->get_g_Ref() );
	pLmmVanillaSwaptionApproxPricer_Rebonato->update_VolatilityParam(pShifted_HGVolatilityParam);

	// Create const function
	LmmPenalty_PTR pLmmPenalty(new LmmPenalty(config.penalty_time_homogeneity_,config.penalty_libor_) );

	LmmBaseCostFunction_PTR pLmmCostFunction(new LmmGlobal_gCostFunction
		(
		pLmmVanillaSwaptionApproxPricer_Rebonato,
		pLmmSwaptionMarketData->get_LiborQuotes(),
		pLmmSwaptionMarketData->get_SwaptionQuotes_ATM(),
		pGMatrixMapping,
		pShifted_HGVolatilityParam,
		pLmmPenalty
		) );

	//costumize swaptions weights
	UpperTriangularDoubleMatrix swpm_weight_matrix = pLmmCostFunction->get_SwaptionWeightMatrix();
	//swpm_weight_matrix(7,1)=1e-6;
	//swpm_weight_matrix(10,1)=1e-6;
	//swpm_weight_matrix(5,3)=0.;
	pLmmCostFunction->reset_SwaptionWeightMatrix(swpm_weight_matrix);

	//std::ostringstream file_costfunc_stream;file_costfunc_stream<<base_name<<"Calibration_"<<nbYear<<"YR_pel_time"<<penalty_time_homogene<<"_pel_lib"<<penalty_libor <<"_LmmCostFunction.csv";
	//pLmmCostFunction->print( file_costfunc_stream.str() );

	// Create Calibrator
	LmmGlobal_gCalibrator lmmCalibrator
		(
		*pGMatrixMapping.get()
		, 200 //maxIter
		, 1e-11   //x_epsilon
		, 1e-11   //f_epsilon    
		, pLmmCostFunction
		);

	if(config.use_positive_constraint_)
		lmmCalibrator.activate_PositiveConstraint();

	lmmCalibrator.solve();

	std::string penalty_info_str;
	if( !pLmmPenalty->isEmpty() )
	{
		const double pT = config.penalty_time_homogeneity_;
		const double pL = config.penalty_libor_ ;
		std::ostringstream pel; pel<<"_pT_"<<pT<<"_pL_"<<pL;
		penalty_info_str = pel.str();
	}

	std::ostringstream file_result_stream;file_result_stream<<base_name<<penalty_info_str<<"_result.csv";
	std::string file_calibration_result(file_result_stream.str());
	lmmCalibrator.printPlusPlus(file_calibration_result);

	std::ostringstream file_gDelegate_stream;file_gDelegate_stream<<base_name<<penalty_info_str<<"_gDelegate.csv";
	std::string file_gDelegate_vol(file_gDelegate_stream.str() );
	pGMatrixMapping->print(file_gDelegate_vol);

	std::ostringstream file_vol_stream;file_vol_stream<<base_name<<penalty_info_str<<"_vol.csv";
	std::string file_calibrated_vol(file_vol_stream.str() );
	pShifted_HGVolatilityParam->print( file_calibrated_vol );


	config.result_quote_error_l2 = lmmCalibrator.get_QuoteError_L2();
	config.result_quote_error_l1  = lmmCalibrator.get_QuoteError_L1();
	config.result_quote_error_linf  = lmmCalibrator.get_QuoteError_LInf();

	if( !pLmmPenalty->isEmpty() )
	{
		config.result_pelTime_error_l2  = lmmCalibrator.get_PenaltyTimeHomogeneity_L2();
		config.result_pelTime_error_l1  = lmmCalibrator.get_PenaltyTimeHomogeneity_L1();
		config.result_pelTime_error_linf  = lmmCalibrator.get_PenaltyTimeHomogeneity_L_INF();
		config.result_pelLibor_error_l2  = lmmCalibrator.get_PenaltySmoothMaturity_L2();
		config.result_pelLibor_error_l1  = lmmCalibrator.get_PenaltySmoothMaturity_L1();
		config.result_pelLibor_error_linf  = lmmCalibrator.get_PenaltySmoothMaturity_L_INF();
	}

	{
		std::string common_result_file_name = "calib_result_gGlobal.csv";

		std::string full_common_result_file = LMMPATH::get_Root_OutputPath() + common_result_file_name ;

		std::ofstream final_result ;
		final_result.open(full_common_result_file.c_str(), std::ios::app);

		final_result<<std::endl<<std::endl<< "============= Test At    "<<LMMPATH::get_TimeDateNow()
			<<",,,,,, Error LInf, "<<lmmCalibrator.get_QuoteError_LInf() <<std::endl ;
		final_result<< lmmCalibrator.get_BaseGeneral_Result_Info();

		final_result.close();	
	}
	return GMatrix_Vol_gMapping(pVolatilityFunction,pGMatrixMapping);
}
Correlation_PTR JB_marketData_LMM_Correlation_calibration(const LmmCalibrationConfig& config, LmmSwaptionMarketData_PTR pLmmSwaptionMarketData , const QuantLib::Array& found_abcd)
{
	size_t nbYear = pLmmSwaptionMarketData->get_nbYear();                   
	std::string base_name = pLmmSwaptionMarketData->get_MarketDataBaseFileName() ;

	Tenor tenorfixedleg = Tenor::_1YR ;
	Tenor tenorfloatleg = Tenor::_6M  ;
	size_t fixedfloatRatio = tenorfixedleg.ratioTo(tenorfloatleg);

	//create LMM components
	LMMTenorStructure_PTR pLMMTenorStructure( new LMMTenorStructure(tenorfloatleg,nbYear) );

	const double a=found_abcd[0],b=found_abcd[1],c=found_abcd[2],d=found_abcd[3];

	Shifted_HGVolatilityParam::ABCDParameter abcdParam(a,b,c,d);
	ConstShifted_HGVolatilityParam_PTR pNoShifted_HGVolatilityParam( new ConstShifted_HGVolatilityParam(pLMMTenorStructure, abcdParam, 1., 0.));

	//! create correlation
	Correlation_PTR pCorrelation = JB_create_InitCorrelation(config);

	Shifted_HGVolatilityFunction_PTR pVolatilityFunction (new ConstShifted_HGVolatilityFunction(pLMMTenorStructure, pCorrelation, pNoShifted_HGVolatilityParam)); 
	Dispersion dispersion(pVolatilityFunction);
	Lmm_PTR lmm_ptr(new Lmm(dispersion) );

	//! Create Approximation Rebonato 
	LmmVanillaSwaptionApproxPricer_Rebonato_PTR pLmmVanillaSwaptionApproxPricer_Rebonato(new LmmVanillaSwaptionApproxPricer_Rebonato(lmm_ptr));	

	pLmmVanillaSwaptionApproxPricer_Rebonato->update_VolatilityParam(pNoShifted_HGVolatilityParam);

	LmmBaseCostFunction_PTR pLmmCorrelationCostFunction(new LmmCorrelationCostFunction
		(
		pLmmVanillaSwaptionApproxPricer_Rebonato
		, pLmmSwaptionMarketData->get_LiborQuotes()
		, pLmmSwaptionMarketData->get_SwaptionQuotes_ATM()
		, pCorrelation
		) );


	////// Correlation calibrator
	QuantLib::Array xy_correlation_init = pCorrelation->get_ArrayFrom_Correlation();
	QuantLib::Size maxIterations =1000;
	QuantLib::Size minStatIterations =100;
	QuantLib::Real rootEpsilon = 1e-8;
	QuantLib::Real functionEpsilon =  1e-8;


	LmmCorrelationCalibrator lmmCorrelationCalibrator
		(
		xy_correlation_init
		, maxIterations
		, rootEpsilon
		,functionEpsilon
		, pLmmCorrelationCostFunction
		);

	lmmCorrelationCalibrator.solve();

	std::string result_file =base_name + "_correlation_calibration_result.csv";
	lmmCorrelationCalibrator.printPlusPlus(result_file);

	std::string calibrated_correlation_file =base_name + "_correlation_calibrated.csv";
	Correlation_PTR calibrated_correl_ptr = lmmCorrelationCalibrator.get_Found_Correlation() ;
	calibrated_correl_ptr->print(calibrated_correlation_file);

	// print in a common file
	{
		std::string common_result_file_name = "calib_result_Correlation.csv";
		std::string full_common_result_file = LMMPATH::get_Root_OutputPath() + common_result_file_name ;

		std::ofstream final_result ;
		final_result.open(full_common_result_file.c_str(), std::ios::app);

		final_result<<std::endl<<std::endl<< "============= Test At    "<<LMMPATH::get_TimeDateNow()
			<<",,,,,, Error LInf, "<<lmmCorrelationCalibrator.get_QuoteError_LInf() <<std::endl ;
		final_result<< lmmCorrelationCalibrator.get_BaseGeneral_Result_Info();

		final_result.close();	
	}

	return calibrated_correl_ptr ;
}
void marketData_LMM_Local_gCalibration( const LmmCalibrationConfig& config
									   , LmmSwaptionMarketData_PTR pLmmSwaptionMarketData 
									   , const QuantLib::Array& abcd_param 
									   , Correlation_PTR found_correlation_ptr  
									   , GMatrixMapping_PTR init_gMapping 
									   )
{
	assert(config.use_local_calib_);
	size_t nbYear = pLmmSwaptionMarketData->get_nbYear();
	std::string base_file_name = pLmmSwaptionMarketData->get_MarketDataBaseFileName();

	Tenor tenorfixedleg = Tenor::_1YR ;
	Tenor tenorfloatleg = Tenor::_6M  ;
	size_t fixedfloatRatio = tenorfixedleg.ratioTo(tenorfloatleg);

	std::string base_name;
	base_name = base_file_name+"_gMatrixLocalCalibration" ;

	//create LMM components
	LMMTenorStructure_PTR pLMMTenorStructure( new LMMTenorStructure(tenorfloatleg,nbYear) );

	const double a=abcd_param[0];
	const double b=abcd_param[1];
	const double c=abcd_param[2];
	const double d=abcd_param[3];

	Shifted_HGVolatilityParam::ABCDParameter abcdParam(a,b,c,d);
	ConstShifted_HGVolatilityParam_PTR pNoShifted_HGVolatilityParam( new ConstShifted_HGVolatilityParam(pLMMTenorStructure, abcdParam, 1., 0.));

	Shifted_HGVolatilityFunction_PTR pVolatilityFunction (new ConstShifted_HGVolatilityFunction(pLMMTenorStructure, found_correlation_ptr , pNoShifted_HGVolatilityParam)); 
	Dispersion dispersion(pVolatilityFunction);
	Lmm_PTR lmm_ptr(new Lmm(dispersion) );

	LmmVanillaSwaptionApproxPricer_Rebonato_PTR pLmmVanillaSwaptionApproxPricer_Rebonato(new LmmVanillaSwaptionApproxPricer_Rebonato(lmm_ptr));	

	// create gMatrixMapping
	size_t        g_matrix_size = GMatrixMapping::get_gSizeFromNbYear(nbYear,fixedfloatRatio );
	size_t delegate_matrix_size = GMatrixMapping::get_gDelegateSizeFromHorizon(pLMMTenorStructure->get_horizon() ,fixedfloatRatio );
	UpperTriangularDoubleMatrix empty_delegate_matrix(delegate_matrix_size,delegate_matrix_size);

	GMatrixMapping_PTR pGMatrixMapping;
	if(init_gMapping)
	{
		pGMatrixMapping = init_gMapping;
	}
	else
	{
		//initiate gMatrixMapping all gDelegate to 1
		pGMatrixMapping.reset( new GMatrixMapping(g_matrix_size, empty_delegate_matrix, pLmmSwaptionMarketData->get_SwaptionQuotes_ATM()->get_UpperTriangularIndexPairMatrix())  );
		QuantLib::Array g_delegate_vector =  pGMatrixMapping->get_DelegateArray();
		for(size_t i=0;i<g_delegate_vector.size();++i) g_delegate_vector[i] = 1.;
		pGMatrixMapping->reset_gDelegate(g_delegate_vector);
	}

	pNoShifted_HGVolatilityParam->reset_g_matrix( pGMatrixMapping->get_g_Ref() );
	pLmmVanillaSwaptionApproxPricer_Rebonato->update_VolatilityParam(pNoShifted_HGVolatilityParam);

	LmmBaseCostFunction_PTR pLmmCostFunction(new LmmLocal_gCostFunction
		(
		pLmmVanillaSwaptionApproxPricer_Rebonato,
		pLmmSwaptionMarketData->get_LiborQuotes(),
		pLmmSwaptionMarketData->get_SwaptionQuotes_ATM(),
		pGMatrixMapping,
		pNoShifted_HGVolatilityParam
		) );

	//costumize swaptions weights
	UpperTriangularDoubleMatrix swpm_weight_matrix = pLmmCostFunction->get_SwaptionWeightMatrix();
	//swpm_weight_matrix(7,1)=1e-6;
	//swpm_weight_matrix(10,1)=1e-6;
	//swpm_weight_matrix(5,3)=0.;
	pLmmCostFunction->reset_SwaptionWeightMatrix(swpm_weight_matrix);

	// Create Calibrator
	LmmLocal_gCalibrator lmmCalibrator
		(
		*pGMatrixMapping.get()
		, 3000 //maxIter
		, 1e-11   //x_epsilon
		, 1e-11   //f_epsilon    
		, pLmmCostFunction
		);

	if(config.use_positive_constraint_)
		lmmCalibrator.activate_PositiveConstraint();

	lmmCalibrator.solve();

	std::ostringstream file_result_stream;file_result_stream<<base_name<<"_result.csv";
	std::string file_calibration_result(file_result_stream.str());
	lmmCalibrator.printPlusPlus(file_calibration_result);

	std::ostringstream file_gDelegate_stream;file_gDelegate_stream<<base_name<<"_gDelegate.csv";
	std::string file_gDelegate_vol(file_gDelegate_stream.str() );
	pGMatrixMapping->print(file_gDelegate_vol);

	std::ostringstream file_vol_stream;file_vol_stream<<base_name<<"_vol.csv";
	std::string file_calibrated_vol(file_vol_stream.str() );
	pNoShifted_HGVolatilityParam->print( file_calibrated_vol );


	{
		std::string common_result_file_name = "calib_result_gLocal.csv";

		std::string full_common_result_file = LMMPATH::get_Root_OutputPath() + common_result_file_name ;

		std::ofstream final_result ;
		final_result.open(full_common_result_file.c_str(), std::ios::app);

		final_result<<std::endl<<std::endl<< "============= Test At    "<<LMMPATH::get_TimeDateNow()
			<<",,,,,, Error LInf, "<<lmmCalibrator.get_QuoteError_LInf() <<std::endl ;
		final_result<< lmmCalibrator.get_BaseGeneral_Result_Info();

		final_result.close();	
	}
}
GMatrixMapping_PTR marketData_LMM_CascadeExact_calibration( const LmmCalibrationConfig& config
														   , LmmSwaptionMarketData_PTR pLmmSwaptionMarketData 
														   , const QuantLib::Array& abcd_param 
														   , Correlation_PTR found_correlation_ptr 
														   )
{
	size_t nbYear = pLmmSwaptionMarketData->get_nbYear();
	std::string base_file_name = pLmmSwaptionMarketData->get_MarketDataBaseFileName();

	Tenor tenorfixedleg = Tenor::_1YR ;
	Tenor tenorfloatleg = Tenor::_6M  ;
	size_t fixedfloatRatio = tenorfixedleg.ratioTo(tenorfloatleg);

	std::string base_name=base_file_name +"_gMatrixCascadeCalibration" ;

	std::ostringstream file_lmm_mkt_stream;file_lmm_mkt_stream<<base_name<<"_Quotation_"<<nbYear<<"YR_.csv";
	pLmmSwaptionMarketData->print(file_lmm_mkt_stream.str());

	//create LMM components
	LMMTenorStructure_PTR pLMMTenorStructure( new LMMTenorStructure(tenorfloatleg,nbYear) );

	const double a=abcd_param[0];
	const double b=abcd_param[1];
	const double c=abcd_param[2];
	const double d=abcd_param[3];

	//const double a=0.0438867,b=0.0179444,c=0.554972,d=0.121429;/// ATTENTION< TEMPORARY, TODELETE and uses abcd calibrator above

	Shifted_HGVolatilityParam::ABCDParameter abcdParam(a,b,c,d);
	ConstShifted_HGVolatilityParam_PTR pNoShifted_HGVolatilityParam( new ConstShifted_HGVolatilityParam(pLMMTenorStructure, abcdParam, 1., 0.));

	Shifted_HGVolatilityFunction_PTR pVolatilityFunction (new ConstShifted_HGVolatilityFunction(pLMMTenorStructure, found_correlation_ptr, pNoShifted_HGVolatilityParam)); 
	Dispersion dispersion(pVolatilityFunction);
	Lmm_PTR lmm_ptr(new Lmm(dispersion) );

	LmmVanillaSwaptionApproxPricer_Rebonato_PTR pLmmVanillaSwaptionApproxPricer_Rebonato(new LmmVanillaSwaptionApproxPricer_Rebonato(lmm_ptr));	

	// create gMatrixMapping
	size_t        g_matrix_size = GMatrixMapping::get_gSizeFromNbYear(nbYear,fixedfloatRatio );
	size_t delegate_matrix_size = GMatrixMapping::get_gDelegateSizeFromHorizon(pLMMTenorStructure->get_horizon() ,fixedfloatRatio );
	UpperTriangularDoubleMatrix empty_delegate_matrix(delegate_matrix_size,delegate_matrix_size);

	GMatrixMapping_PTR pGMatrixMapping( new GMatrixMapping(g_matrix_size, empty_delegate_matrix, pLmmSwaptionMarketData->get_SwaptionQuotes_ATM()->get_UpperTriangularIndexPairMatrix())  );

	//initiate gMatrixMapping all gDelegate to 1
	QuantLib::Array g_delegate_vector =  pGMatrixMapping->get_DelegateArray();
	for(size_t i=0;i<g_delegate_vector.size();++i) g_delegate_vector[i] = 1.;
	pGMatrixMapping->reset_gDelegate(g_delegate_vector);

	pNoShifted_HGVolatilityParam->reset_g_matrix( pGMatrixMapping->get_g_Ref() );
	pLmmVanillaSwaptionApproxPricer_Rebonato->update_VolatilityParam(pNoShifted_HGVolatilityParam);

	LmmBaseCostFunction_PTR pLmmCascadeCostFunction (
		new LmmCascade_gCostFunction
		(
		pLmmVanillaSwaptionApproxPricer_Rebonato
		,pLmmSwaptionMarketData->get_LiborQuotes()
		,pLmmSwaptionMarketData->get_SwaptionQuotes_ATM()
		,pGMatrixMapping
		,pNoShifted_HGVolatilityParam
		)
		);

	UpperTriangularDoubleMatrix copy_weight_matrix = pLmmCascadeCostFunction->get_SwaptionWeightMatrix();

	//copy_weight_matrix(2,1)=1000;

	pLmmCascadeCostFunction->reset_SwaptionWeightMatrix(copy_weight_matrix);

	LmmCascade_gCalibrator lmmCalibrator
		(
		*pGMatrixMapping.get()
		, 100000 // config.maxIter
		, 1e-12  // config.x_epsilon
		, 1e-10  // config.f_epsilon    
		, pLmmCascadeCostFunction
		);

	if(config.use_positive_constraint_)
		lmmCalibrator.activate_PositiveConstraint();

	lmmCalibrator.solve();

	std::ostringstream file_vol_stream;file_vol_stream<<base_name<<"_vol.csv";
	std::string file_calibrated_vol(file_vol_stream.str() );
	pNoShifted_HGVolatilityParam->print( file_calibrated_vol );

	std::ostringstream file_result_stream;file_result_stream<<base_name<<"_result.csv";
	std::string file_calibration_result(file_result_stream.str());
	lmmCalibrator.printPlusPlus(file_calibration_result);

	std::ostringstream file_gDelegate_stream;file_gDelegate_stream<<base_name<<"_gDelegate.csv";
	std::string file_gDelegate_vol(file_gDelegate_stream.str() );
	pGMatrixMapping->print(file_gDelegate_vol);

	// print in a common file
	{
		std::string common_result_file_name = "calib_result_gCascade.csv";
		std::string full_common_result_file = LMMPATH::get_Root_OutputPath() + common_result_file_name ;

		std::ofstream final_result ;
		final_result.open(full_common_result_file.c_str(), std::ios::app);

		final_result<<std::endl<<std::endl<< "============= Test At    "<<LMMPATH::get_TimeDateNow()
			<<",,,,,, Error LInf, "<<lmmCalibrator.get_QuoteError_LInf() <<std::endl ;
		final_result<< lmmCalibrator.get_BaseGeneral_Result_Info();

		final_result.close();	
	}

	return pGMatrixMapping;
}