//*	A SHORT VERSION
int main(int argc, char ** argv)
{
    // s_InputFile = baseDir + <name of the input file>
    string s_InputFile; //path of the input file
    s_InputFile = baseDir;
    s_InputFile += DIR_SEPARATOR;
    s_InputFile += "Graphs";
    s_InputFile += DIR_SEPARATOR;
    s_InputFile += "column-compress.mtx";

    //Generate and color the bipartite graph
    BipartiteGraphPartialColoringInterface *g = new BipartiteGraphPartialColoringInterface(SRC_FILE, s_InputFile.c_str(), "AUTO_DETECTED");

    //Do Partial-Distance-Two-Coloring the bipartite graph with the specified ordering
    g->PartialDistanceTwoColoring("SMALLEST_LAST", "ROW_PARTIAL_DISTANCE_TWO");

    /*Done with coloring. Below are possible things that you may
    want to do after coloring:
    //*/

    /* 1. Check Partial Distance Two Coloring result
    cout<<"Check Partial Distance Two coloring result ... "<<endl;
    if(g->CheckPartialDistanceTwoColoring() == _FALSE) cout<<" FAILED"<<endl;
    else cout<<" SUCCEEDED"<<endl;
    Pause();
    //*/

    //* 2. Print coloring results
    g->PrintPartialColoringMetrics();
    Pause();
    //*/

    //* 3. Get the list of colorID of colored vertices (in this case, the left side of the bipartite graph)
    vector<int> vi_VertexPartialColors;
    g->GetVertexPartialColors(vi_VertexPartialColors);

    //Print Partial Colors
    g->PrintPartialColors();
    Pause();
    //*/

    /* 4. Get seed matrix
    int i_SeedRowCount = 0;
    int i_SeedColumnCount = 0;
    double** Seed = g->GetSeedMatrix(&i_SeedRowCount, &i_SeedColumnCount);

    //Display Seed
    printf("Seed matrix %d x %d \n", i_SeedRowCount, i_SeedColumnCount);
    displayMatrix(Seed, i_SeedRowCount, i_SeedColumnCount, 1);
    Pause();
    //*/

    delete g;
    return 0;
}
int main()
{
	double*** dp3_Seed = new double**;
	int *ip1_SeedRowCount = new int;
	int *ip1_SeedColumnCount = new int;
	int i_RowCount, i_ColumnCount, i_MaxNonZerosInRows;

	//populate the Jacobian. Uncomment one of the 2 matrices below
	/* 1x1 matrix
	i_RowCount = 1;
	i_ColumnCount = 1;
	i_MaxNonZerosInRows = 1;
	unsigned int **uip2_JacobianSparsityPattern = new unsigned int *[i_RowCount];//[1][1]
	for(int i=0;i<i_RowCount;i++) uip2_JacobianSparsityPattern[i] = new unsigned int[i_MaxNonZerosInRows + 1];
	uip2_JacobianSparsityPattern[0][0] = 1;		uip2_JacobianSparsityPattern[0][1] = 0;
	//*/

	//* 32x9 matrix
	i_RowCount = 32;
	i_ColumnCount = 9;
	i_MaxNonZerosInRows = 3;
	unsigned int **uip2_JacobianSparsityPattern = new unsigned int *[i_RowCount];//[32][9]
	for(int i=0;i<i_RowCount;i++) uip2_JacobianSparsityPattern[i] = new unsigned int[i_MaxNonZerosInRows + 1];
	uip2_JacobianSparsityPattern[0][0] = 0;
	uip2_JacobianSparsityPattern[1][0] = 1;		uip2_JacobianSparsityPattern[1][1] = 0;
	uip2_JacobianSparsityPattern[2][0] = 1;		uip2_JacobianSparsityPattern[2][1] = 1;
	uip2_JacobianSparsityPattern[3][0] = 1;		uip2_JacobianSparsityPattern[3][1] = 2;
	uip2_JacobianSparsityPattern[4][0] = 1;		uip2_JacobianSparsityPattern[4][1] = 0;
	uip2_JacobianSparsityPattern[5][0] = 3;		uip2_JacobianSparsityPattern[5][1] = 0;		uip2_JacobianSparsityPattern[5][2] = 1;		uip2_JacobianSparsityPattern[5][3] = 3;
	uip2_JacobianSparsityPattern[6][0] = 3;		uip2_JacobianSparsityPattern[6][1] = 1;		uip2_JacobianSparsityPattern[6][2] = 2;		uip2_JacobianSparsityPattern[6][3] = 4;
	uip2_JacobianSparsityPattern[7][0] = 2;		uip2_JacobianSparsityPattern[7][1] = 2;		uip2_JacobianSparsityPattern[7][2] = 5;
	uip2_JacobianSparsityPattern[8][0] = 1;		uip2_JacobianSparsityPattern[8][1] = 3;
	uip2_JacobianSparsityPattern[9][0] = 3;		uip2_JacobianSparsityPattern[9][1] = 3;		uip2_JacobianSparsityPattern[9][2] = 4;		uip2_JacobianSparsityPattern[9][3] = 6;
	uip2_JacobianSparsityPattern[10][0] = 3;	uip2_JacobianSparsityPattern[10][1] = 4;		uip2_JacobianSparsityPattern[10][2] = 5;		uip2_JacobianSparsityPattern[10][3] = 7;
	uip2_JacobianSparsityPattern[11][0] = 2;	uip2_JacobianSparsityPattern[11][1] = 5;		uip2_JacobianSparsityPattern[11][2] = 8;
	uip2_JacobianSparsityPattern[12][0] = 1;	uip2_JacobianSparsityPattern[12][1] = 6;
	uip2_JacobianSparsityPattern[13][0] = 2;	uip2_JacobianSparsityPattern[13][1] = 6;		uip2_JacobianSparsityPattern[13][2] = 7;
	uip2_JacobianSparsityPattern[14][0] = 2;	uip2_JacobianSparsityPattern[14][1] = 7;		uip2_JacobianSparsityPattern[14][2] = 8;
	uip2_JacobianSparsityPattern[15][0] = 1;	uip2_JacobianSparsityPattern[15][1] = 8;
	uip2_JacobianSparsityPattern[16][0] = 1;	uip2_JacobianSparsityPattern[16][1] = 0;
	uip2_JacobianSparsityPattern[17][0] = 2;	uip2_JacobianSparsityPattern[17][1] = 0;		uip2_JacobianSparsityPattern[17][2] = 1;
	uip2_JacobianSparsityPattern[18][0] = 2;	uip2_JacobianSparsityPattern[18][1] = 1;		uip2_JacobianSparsityPattern[18][2] = 2;
	uip2_JacobianSparsityPattern[19][0] = 1;	uip2_JacobianSparsityPattern[19][1] = 2;
	uip2_JacobianSparsityPattern[20][0] = 2;	uip2_JacobianSparsityPattern[20][1] = 0;		uip2_JacobianSparsityPattern[20][2] = 3;
	uip2_JacobianSparsityPattern[21][0] = 3;	uip2_JacobianSparsityPattern[21][1] = 1;		uip2_JacobianSparsityPattern[21][2] = 3;		uip2_JacobianSparsityPattern[21][3] = 4;
	uip2_JacobianSparsityPattern[22][0] = 3;	uip2_JacobianSparsityPattern[22][1] = 2;		uip2_JacobianSparsityPattern[22][2] = 4;		uip2_JacobianSparsityPattern[22][3] = 5;
	uip2_JacobianSparsityPattern[23][0] = 1;	uip2_JacobianSparsityPattern[23][1] = 5;
	uip2_JacobianSparsityPattern[24][0] = 2;	uip2_JacobianSparsityPattern[24][1] = 3;		uip2_JacobianSparsityPattern[24][2] = 6;
	uip2_JacobianSparsityPattern[25][0] = 3;	uip2_JacobianSparsityPattern[25][1] = 4;		uip2_JacobianSparsityPattern[25][2] = 6;		uip2_JacobianSparsityPattern[25][3] = 7;
	uip2_JacobianSparsityPattern[26][0] = 3;	uip2_JacobianSparsityPattern[26][1] = 5;		uip2_JacobianSparsityPattern[26][2] = 7;		uip2_JacobianSparsityPattern[26][3] = 8;
	uip2_JacobianSparsityPattern[27][0] = 1;	uip2_JacobianSparsityPattern[27][1] = 8;
	uip2_JacobianSparsityPattern[28][0] = 1;	uip2_JacobianSparsityPattern[28][1] = 6;
	uip2_JacobianSparsityPattern[29][0] = 1;	uip2_JacobianSparsityPattern[29][1] = 7;
	uip2_JacobianSparsityPattern[30][0] = 1;	uip2_JacobianSparsityPattern[30][1] = 8;
	uip2_JacobianSparsityPattern[31][0] = 0;
	//*/

	//Step 1: Read the sparsity pattern of the given Jacobian matrix (compressed sparse rows format)
	//and create the corresponding bipartite graph
	BipartiteGraphPartialColoringInterface * g = new BipartiteGraphPartialColoringInterface(SRC_MEM_ADOLC, uip2_JacobianSparsityPattern, i_RowCount, i_ColumnCount);

	//Step 2: Do Partial-Distance-Two-Coloring the bipartite graph with the specified ordering
	g->PartialDistanceTwoColoring( "SMALLEST_LAST", "COLUMN_PARTIAL_DISTANCE_TWO");

	//Step 3: From the coloring information, create and return the seed matrix
	(*dp3_Seed) = g->GetSeedMatrix(ip1_SeedRowCount, ip1_SeedColumnCount);
	/* Notes:
	In stead of doing step 1-3, you can just call the bellow function:
		g->GenerateSeedJacobian(uip2_JacobianSparsityPattern, i_RowCount,i_ColumnCount, dp3_Seed, ip1_SeedRowCount, ip1_SeedColumnCount, "COLUMN_PARTIAL_DISTANCE_TWO", "SMALLEST_LAST"); // compress columns. This function is inside BipartiteGraphPartialColoringInterface class
	*/
	cout<<"Finish GenerateSeed()"<<endl;

	//this SECTION is just for displaying the result
	g->PrintBipartiteGraph();
	g->PrintColumnPartialColors();
	g->PrintColumnPartialColoringMetrics();
	double **RSeed = *dp3_Seed;
	int rows = g->GetColumnVertexCount();
	int cols = g->GetRightVertexColorCount();
	cout<<"Right Seed matrix: ("<<rows<<","<<cols<<")"<<endl;
	for(int i=0; i<rows; i++) {
		for(int j=0; j<cols; j++) {
			cout<<setw(6)<<RSeed[i][j];
		}
		cout<<endl;
	}
	//END SECTION


	Pause();

	//GraphColoringInterface * g = new GraphColoringInterface();
	delete g;
	g = NULL;

	//double*** dp3_Seed = new double**;
	delete dp3_Seed;
	dp3_Seed = NULL;
	RSeed = NULL;

	//int *ip1_SeedRowCount = new int;
	delete ip1_SeedRowCount;
	ip1_SeedRowCount = NULL;

	//int *ip1_SeedColumnCount = new int;
	delete ip1_SeedColumnCount;
	ip1_SeedColumnCount = NULL;

	//unsigned int **uip2_HessianSparsityPattern = new unsigned int *[i_RowCount];//[5][5]
	free_2DMatrix(uip2_JacobianSparsityPattern, i_RowCount);
	uip2_JacobianSparsityPattern = NULL;

	return 0;
}
int main()
{
	// s_InputFile = baseDir + <name of the input file>
	string s_InputFile; //path of the input file
	s_InputFile = baseDir;
	s_InputFile += DIR_SEPARATOR; s_InputFile += "Graphs"; s_InputFile += DIR_SEPARATOR; s_InputFile += "column-compress.mtx";

	// Step 1: Determine sparsity structure of the Jacobian.
	// This step is done by an AD tool. For the purpose of illustration here, we read the structure from a file,
	// and store the structure in a Compressed Row Format.
	unsigned int *** uip3_SparsityPattern = new unsigned int **;	//uip3_ means triple pointers of type unsigned int
	double*** dp3_Value = new double**;	//dp3_ means triple pointers of type double. Other prefixes follow the same notation
	int rowCount, columnCount;
	ConvertMatrixMarketFormat2RowCompressedFormat(s_InputFile, uip3_SparsityPattern, dp3_Value,rowCount, columnCount);

	cout<<"just for debugging purpose, display the 2 matrices: the matrix with SparsityPattern only and the matrix with Value"<<endl;
	cout<<fixed<<showpoint<<setprecision(2); //formatting output
	cout<<"(*uip3_SparsityPattern)"<<endl;
	displayCompressedRowMatrix((*uip3_SparsityPattern),rowCount);
	cout<<"(*dp3_Value)"<<endl;
	displayCompressedRowMatrix((*dp3_Value),rowCount);
	cout<<"Finish ConvertMatrixMarketFormat2RowCompressedFormat()"<<endl;
	Pause();

	//Step 2: Obtain the seed matrix via coloring.
	double*** dp3_Seed = new double**;
	int *ip1_SeedRowCount = new int;
	int *ip1_SeedColumnCount = new int;
	int *ip1_ColorCount = new int; //The number of distinct colors used to color the graph

	//Step 2.1: Read the sparsity pattern of the given Jacobian matrix (compressed sparse rows format)
	//and create the corresponding bipartite graph
	BipartiteGraphPartialColoringInterface *g = new BipartiteGraphPartialColoringInterface(SRC_MEM_ADOLC, *uip3_SparsityPattern, rowCount, columnCount);

	//Step 2.2: Do Partial-Distance-Two-Coloring the bipartite graph with the specified ordering
	g->PartialDistanceTwoColoring("SMALLEST_LAST", "COLUMN_PARTIAL_DISTANCE_TWO");

	//Step 2.3 (Option 1): From the coloring information, create and return the seed matrix
	(*dp3_Seed) = g->GetSeedMatrix(ip1_SeedRowCount, ip1_SeedColumnCount);
	/* Notes:
	Step 2.3 (Option 2): From the coloring information, you can also get the vector of colorIDs of left or right vertices  (depend on the s_ColoringVariant that you choose)
		vector<int> vi_VertexPartialColors;
		g->GetVertexPartialColors(vi_VertexPartialColors);
	*/
	cout<<"Finish GenerateSeed()"<<endl;
	*ip1_ColorCount = *ip1_SeedColumnCount;

	//Display results of step 2
	printf(" dp3_Seed %d x %d \n", *ip1_SeedRowCount, *ip1_SeedColumnCount);
	displayMatrix(*dp3_Seed, *ip1_SeedRowCount, *ip1_SeedColumnCount);
	Pause();

	// Step 3: Obtain the Jacobian-seed matrix product.
	// This step will also be done by an AD tool. For the purpose of illustration here, the orginial matrix V
	// (for Values) is multiplied with the seed matrix S. The resulting matrix is stored in dp3_CompressedMatrix.
	double*** dp3_CompressedMatrix = new double**;
	cout<<"Start MatrixMultiplication()"<<endl;
	MatrixMultiplication_VxS(*uip3_SparsityPattern, *dp3_Value, rowCount, columnCount, *dp3_Seed, *ip1_ColorCount, dp3_CompressedMatrix);
	cout<<"Finish MatrixMultiplication()"<<endl;

	displayMatrix(*dp3_CompressedMatrix,rowCount,*ip1_ColorCount);
	Pause();

	//Step 4: Recover the numerical values of the original matrix from the compressed representation.
	// The new values are store in "dp3_NewValue"
	double*** dp3_NewValue = new double**;
	JacobianRecovery1D* jr1d = new JacobianRecovery1D;
	int rowCount_for_dp3_NewValue = jr1d->RecoverD2Cln_RowCompressedFormat_unmanaged(g, *dp3_CompressedMatrix, *uip3_SparsityPattern, dp3_NewValue);
	/* RecoverD2Cln_RowCompressedFormat_unmanaged is called instead of RecoverD2Cln_RowCompressedFormat so that
	we could manage the memory deallocation for dp3_NewValue by ourselves.
	This way, we can reuse (*dp3_NewValue) to store new values if RecoverD2Cln_RowCompressedFormat...() need to be called again.
	//*/

	cout<<"Finish Recover()"<<endl;

	displayCompressedRowMatrix(*dp3_NewValue,rowCount);
	Pause();

	//Check for consistency, make sure the values in the 2 matrices are the same.
	if (CompressedRowMatricesAreEqual(*dp3_Value, *dp3_NewValue, rowCount,0)) cout<< "*dp3_Value == dp3_NewValue"<<endl;
	else cout<< "*dp3_Value != dp3_NewValue"<<endl;

	Pause();

	/* Let say that we have new matrices with the same sparsity structure (only the values changed),
	 We can take advantage of the memory already allocated to (*dp3_NewValue) and use (*dp3_NewValue) to stored the new values
	 by calling RecoverD2Cln_RowCompressedFormat_usermem recovery function.
	 This function works in the same way as RecoverD2Cln_RowCompressedFormat_unmanaged except that the memory for (*dp3_NewValue)
	 is reused and therefore, takes less time than the _unmanaged counterpart.
	 //*/
	for(int i=0; i<3;i++) {
	  jr1d->RecoverD2Cln_RowCompressedFormat_usermem(g, *dp3_CompressedMatrix, *uip3_SparsityPattern, dp3_NewValue);
	}

	//Deallocate memory for 2-dimensional array (*dp3_NewValue)
	for(int i=0; i<rowCount_for_dp3_NewValue;i++) {
	  free((*dp3_NewValue)[i]);
	}
	free(*dp3_NewValue);

	//Deallocate memory using functions in Utilities/MatrixDeallocation.h

	free_2DMatrix(uip3_SparsityPattern, rowCount);
	uip3_SparsityPattern=NULL;

	free_2DMatrix(dp3_Value, rowCount);
	dp3_Value=NULL;

	delete dp3_Seed;
	dp3_Seed = NULL;

	delete ip1_SeedRowCount;
	ip1_SeedRowCount=NULL;

	delete ip1_SeedColumnCount;
	ip1_SeedColumnCount = NULL;

	free_2DMatrix(dp3_CompressedMatrix, rowCount);
	dp3_CompressedMatrix = NULL;

	delete ip1_ColorCount;
	ip1_ColorCount = NULL;

	delete jr1d;
	jr1d = NULL;

	delete dp3_NewValue;
	dp3_NewValue=NULL;

	delete g;
	g=NULL;

	return 0;
}
Ejemplo n.º 4
0
int main()
{
  int i, j, k, l, sum, n, m, nnz, direct = 1, found;
  double f;
  double *x, *c;
  adouble fad, *xad, *cad;
  //double** Zpp;
  //double** Zppf;
  double** J;
  //double* s;
  //int p_H_dir, p_H_indir;
  size_t tape_stats[11];
  int num;
  FILE *fp_JP;

  double **Seed_J;
  double **Jc;
  int p_J;

  int recover = 1;
  int jac_vec = 1;
  int compute_full = 1;
  int output_sparsity_pattern_J = 0;
  //int output_sparsity_pattern_H = 1;
  //int use_direct_method = 1;
  //int output_direct = 0;
  //int use_indirect_method = 1;
  //int output_indirect = 0;

  double t_f_1, t_f_2, div_f=0, div_c=0, div_JP=0, div_JP2=0, div_Seed=0, div_Seed_C=0, div_Jc=0, div_Jc_C=0, div_rec=0, div_rec_C=0, div_J=0;
  //double test;
  unsigned int *rind;
  unsigned int *cind;
  double *values;

  //tring s_InputFile = "test_mat.mtx";
  //string s_InputFile = "jac_pat.mtx";


//------------------------------------------------------------------------------------
// problem definition + evaluation

  init_dim(&n,&m); // initialize n and m

  printf(" n = %d m = %d\n",n,m);

  x =   (double*)  malloc(n*sizeof(double)); // x: vector input for function evaluation
  c =   (double*)  malloc(m*sizeof(double)); // c: constraint vector
  cad = new adouble[m];

  init_startpoint(x,n);

  t_f_1 = k_getTime();
  for(i=0;i<repnum;i++)
    f = feval(x,n);
  t_f_2 = k_getTime();
  div_f = (t_f_2 - t_f_1)*1.0/repnum;
  printf("XXX The time needed for function evaluation:  %10.6f \n \n", div_f);


  t_f_1 = k_getTime();
  for(i=0;i<repnum;i++)
    ceval(x,c,n);
  t_f_2 = k_getTime();
  div_c = (t_f_2 - t_f_1)*1.0/repnum;
  printf("XXX The time needed for constraint evaluation:  %10.6f \n \n", div_c);


  trace_on(tag_f);

    fad = feval_ad(x, n); // feval_ad: derivative of feval

    fad >>= f;

  trace_off();

  trace_on(tag_c);

    ceval_ad(x, cad, n); //ceval_ad: derivative of ceval

    for(i=0;i<m;i++)
      cad[i] >>= f;

  trace_off();
  //return 1;

  tapestats(tag_c,tape_stats);              // reading of tape statistics
  printf("\n    independents   %ld\n",(long)tape_stats[0]);
  printf("    dependents     %ld\n",(long)tape_stats[1]);
  printf("    operations     %ld\n",(long)tape_stats[5]);
  printf("    buffer size    %ld\n",(long)tape_stats[4]);
  printf("    maxlive        %ld\n",(long)tape_stats[2]);
  printf("    valstack size  %ld\n\n",(long)tape_stats[3]);


//------------------------------------------------------------------------------------
// full Jacobian:

  div_J = -1;

  if(compute_full == 1)
    {
      J =  myalloc2(m,n);

      t_f_1 = k_getTime();
      jacobian(tag_c,m,n,x,J);
      t_f_2 = k_getTime();
      div_J = (t_f_2 - t_f_1);

      printf("XXX The time needed for full Jacobian:  %10.6f \n \n", div_J);
      printf("XXX runtime ratio:  %10.6f \n \n", div_J/div_c);

      //save the matrix into a file (non-zero entries only)

	fp_JP = fopen("jac_full.mtx","w");

	fprintf(fp_JP,"%d %d\n",m,n);

	for (i=0;i<m;i++)
	  {
	    for (j=0;j<n;j++)
	      if(J[i][j]!=0.0) fprintf(fp_JP,"%d %d %10.6f\n",i,j,J[i][j] );
	  }
	fclose(fp_JP);
    }

//------------------------------------------------------------------------------------
  printf("XXX THE 4 STEP TO COMPUTE SPARSE MATRICES USING ColPack \n \n");
// STEP 1: Determination of sparsity pattern of Jacobian JP:

  unsigned int  *rb=NULL;          /* dependent variables          */
  unsigned int  *cb=NULL;          /* independent variables        */
  unsigned int  **JP=NULL;         /* compressed block row storage */
  int ctrl[2];

  JP = (unsigned int **) malloc(m*sizeof(unsigned int*));
  ctrl[0] = 0; ctrl[1] = 0;


  t_f_1 = k_getTime();
  jac_pat(tag_c, m, n, x, JP, ctrl);	//ADOL-C calculate the sparsity pattern
  t_f_2 = k_getTime();
  div_JP = (t_f_2 - t_f_1);

  printf("XXX STEP 1: The time needed for Jacobian pattern:  %10.6f \n \n", div_JP);
  printf("XXX STEP 1: runtime ratio:  %10.6f \n \n", div_JP/div_c);


  nnz = 0;
  for (i=0;i<m;i++)
    nnz += JP[i][0];

  printf(" nnz %d \n",nnz);
  printf(" hier 1a\n");


//------------------------------------------------------------------------------------
// STEP 2: Determination of Seed matrix:

  double tg_C;
  int dummy;

  t_f_1 = k_getTime();

  BipartiteGraphPartialColoringInterface * gGraph = new BipartiteGraphPartialColoringInterface(SRC_MEM_ADOLC, JP, m, n);
  //gGraph->PrintBipartiteGraph();
  t_f_2 = k_getTime();

  printf("XXX STEP 2: The time needed for Graph construction:  %10.6f \n \n", (t_f_2-t_f_1) );
  printf("XXX STEP 2: runtime ratio:  %10.6f \n \n", (t_f_2-t_f_1)/div_c);

  t_f_1 = k_getTime();
  //gGraph->GenerateSeedJacobian(&Seed_J, &dummy, &p_J,
  //                          "NATURAL", "COLUMN_PARTIAL_DISTANCE_TWO");
  gGraph->PartialDistanceTwoColoring("NATURAL", "COLUMN_PARTIAL_DISTANCE_TWO");
  t_f_2 = k_getTime();

  printf("XXX STEP 2: The time needed for Coloring:  %10.6f \n \n", (t_f_2-t_f_1));
  printf("XXX STEP 2: runtime ratio:  %10.6f \n \n", (t_f_2-t_f_1)/div_c);

  t_f_1 = k_getTime();
  Seed_J = gGraph->GetSeedMatrix(&dummy, &p_J);
  t_f_2 = k_getTime();
  tg_C = t_f_2 - t_f_1;


  printf("XXX STEP 2: The time needed for Seed generation:  %10.6f \n \n", tg_C);
  printf("XXX STEP 2: runtime ratio:  %10.6f \n \n", tg_C/div_c);

  //*/

//------------------------------------------------------------------------------------
// STEP 3: Jacobian-matrix product:

// ADOL-C:
//*
  if (jac_vec == 1)
    {

      Jc = myalloc2(m,p_J);
      t_f_1 = k_getTime();
      printf(" hier 1\n");
      fov_forward(tag_c,m,n,p_J,x,Seed_J,c,Jc);
      printf(" hier 2\n");
      t_f_2 = k_getTime();
      div_Jc = (t_f_2 - t_f_1);

      printf("XXX STEP 3: The time needed for Jacobian-matrix product:  %10.6f \n \n", div_Jc);
      printf("XXX STEP 3: runtime ratio:  %10.6f \n \n", div_Jc/div_c);


    }

//------------------------------------------------------------------------------------
// STEP 4: computed Jacobians/ recovery


  if (recover == 1)
    {


      JacobianRecovery1D jr1d;

      printf("m = %d, n = %d, p_J = %d \n",m,n,p_J);
      //printmatint_c("JP Jacobian Pattern",m,JP);
      //printmat("Jc Jacobian compressed",m,p_J,Jc);

      t_f_1 = k_getTime();
      jr1d.RecoverD2Cln_CoordinateFormat (gGraph, Jc, JP, &rind, &cind, &values);
      t_f_2 = k_getTime();
      div_rec_C = (t_f_2 - t_f_1);

      printf("XXX STEP 4: The time needed for Recovery:  %10.6f \n \n", div_rec_C);
      printf("XXX STEP 4: runtime ratio:  %10.6f \n \n", div_rec_C/div_c);

      //save recovered matrix into file

	fp_JP = fopen("jac_recovered.mtx","w");

	fprintf(fp_JP,"%d %d %d\n",m,n,nnz);

	for (i=0;i<nnz;i++)
	  {
	      fprintf(fp_JP,"%d %d %10.6f\n",rind[i],cind[i],values[i] );
	  }
	fclose(fp_JP);

    }

    /*By this time, if you compare the 2 output files: jac_full.mtx and jac_recovered.mtx
    You should be able to see that the non-zero entries are identical
    */


  free(JP);
  delete[] cad;
  free(c);
  free(x);
  delete gGraph;
  if(jac_vec == 1) {
    myfree2(Jc);
  }
  if(compute_full == 1)
    {
      myfree2(J);
    }

  return 0;

}
int main()
{
	// s_InputFile = baseDir + <name of the input file>
	string s_InputFile; //path of the input file
	s_InputFile = baseDir;
	s_InputFile += DIR_SEPARATOR; s_InputFile += "Graphs"; s_InputFile += DIR_SEPARATOR; s_InputFile += "column-compress.mtx";
	//s_InputFile += DIR_SEPARATOR; s_InputFile += "Graphs"; s_InputFile += DIR_SEPARATOR; s_InputFile += "hess_pat.mtx";

	// Step 1: Determine sparsity structure of the Jacobian.
	// This step is done by an AD tool. For the purpose of illustration here, we read the structure from a file,
	// and store the structure in a Compressed Row Format and then ADIC format.
	unsigned int *** uip3_SparsityPattern = new unsigned int **;	//uip3_ means triple pointers of type unsigned int
	double*** dp3_Value = new double**;	//dp3_ means triple pointers of type double. Other prefixes follow the same notation
	int rowCount, columnCount;
	ConvertMatrixMarketFormat2RowCompressedFormat(s_InputFile, uip3_SparsityPattern, dp3_Value,rowCount, columnCount);

	cout<<"just for debugging purpose, display the 2 matrices: the matrix with SparsityPattern only and the matrix with Value"<<endl;
	cout<<"Matrix rowCount = "<<rowCount<<"; columnCount = "<<columnCount<<endl;
	cout<<fixed<<showpoint<<setprecision(2); //formatting output
	cout<<"(*uip3_SparsityPattern)"<<endl;
	displayCompressedRowMatrix((*uip3_SparsityPattern),rowCount, true);
	cout<<"(*dp3_Value)"<<endl;
	displayCompressedRowMatrix((*dp3_Value),rowCount);
	cout<<"Finish ConvertMatrixMarketFormat2RowCompressedFormat()"<<endl;
	Pause();

	std::list<std::set<int> > lsi_SparsityPattern;
	std::list<std::vector<double> > lvd_Value;
	ConvertRowCompressedFormat2ADIC( (*uip3_SparsityPattern) , rowCount, (*dp3_Value), lsi_SparsityPattern, lvd_Value);

	cout<<"just for debugging purpose, display the matrix in ADIC format rowCount = "<<rowCount<<endl;
	cout<<"Display lsi_SparsityPattern"<<endl;
	DisplayADICFormat_Sparsity(lsi_SparsityPattern);
	cout<<"Display lvd_Value"<<endl;
	DisplayADICFormat_Value(lvd_Value);
	cout<<"Finish ConvertRowCompressedFormat2CSR()"<<endl;
	Pause();

	//Step 2: Coloring.
	int *ip1_ColorCount = new int; //The number of distinct colors used to color the graph

	//Step 2.1: Read the sparsity pattern of the given Jacobian matrix (ADIC format)
	//and create the corresponding bipartite graph
	BipartiteGraphPartialColoringInterface *g = new BipartiteGraphPartialColoringInterface(SRC_MEM_ADIC, &lsi_SparsityPattern, columnCount);

	//Step 2.2: Do Partial-Distance-Two-Coloring the bipartite graph with the specified ordering
	g->PartialDistanceTwoColoring("SMALLEST_LAST", "COLUMN_PARTIAL_DISTANCE_TWO");

	//Step 2.3: From the coloring information, you can  get the vector of colorIDs of left or right vertices  (depend on the s_ColoringVariant that you choose)
	vector<int> vi_VertexPartialColors;
	g->GetVertexPartialColors(vi_VertexPartialColors);
	*ip1_ColorCount = g->GetRightVertexColorCount();
	cout<<"Finish GetVertexPartialColors()"<<endl;

	//Display results of step 2
	printf(" Display vi_VertexPartialColors  *ip1_ColorCount=%d \n",*ip1_ColorCount);
	displayVector(vi_VertexPartialColors);
	Pause();

	// Step 3: Obtain the Jacobian-seed matrix product.
	// This step will also be done by an AD tool. For the purpose of illustration here, the orginial matrix V
	// (for Values) is multiplied with the seed matrix S (represented as a vector of colors vi_VertexPartialColors).
	// The resulting matrix is stored in dp3_CompressedMatrix.
	double*** dp3_CompressedMatrix = new double**;
	cout<<"Start MatrixMultiplication()"<<endl;
	MatrixMultiplication_VxS__usingVertexPartialColors(lsi_SparsityPattern, lvd_Value, columnCount, vi_VertexPartialColors, *ip1_ColorCount, dp3_CompressedMatrix);
	cout<<"Finish MatrixMultiplication()"<<endl;

	displayMatrix(*dp3_CompressedMatrix,rowCount,*ip1_ColorCount);
	Pause();

	//Step 4: Recover the numerical values of the original matrix from the compressed representation.
	// The new values are store in "lvd_NewValue"
	std::list<std::vector<double> > lvd_NewValue;
	JacobianRecovery1D* jr1d = new JacobianRecovery1D;
	jr1d->RecoverD2Cln_ADICFormat(g, *dp3_CompressedMatrix, lsi_SparsityPattern, lvd_NewValue);
	cout<<"Finish Recover()"<<endl;

	DisplayADICFormat_Value(lvd_NewValue);
	Pause();

	//Check for consistency, make sure the values in the 2 matrices are the same.
	if (ADICMatricesAreEqual(lvd_Value, lvd_NewValue,0)) cout<< "lvd_Value == lvd_NewValue"<<endl;
	else cout<< "lvd_Value != lvd_NewValue"<<endl;

	Pause();

	//Deallocate memory using functions in Utilities/MatrixDeallocation.h

	free_2DMatrix(uip3_SparsityPattern, rowCount);
	uip3_SparsityPattern=NULL;

	free_2DMatrix(dp3_Value, rowCount);
	dp3_Value=NULL;

	free_2DMatrix(dp3_CompressedMatrix, rowCount);
	dp3_CompressedMatrix = NULL;

	delete ip1_ColorCount;
	ip1_ColorCount = NULL;

	delete jr1d;
	jr1d = NULL;

	delete g;
	g=NULL;

	return 0;
}
int main()
{
	// s_InputFile = baseDir + <name of the input file>
	string s_InputFile; //path of the input file
	s_InputFile = baseDir;
	s_InputFile += DIR_SEPARATOR; s_InputFile += "Graphs"; s_InputFile += DIR_SEPARATOR; s_InputFile += "column-compress.mtx";

	// Step 1: Determine sparsity structure of the Jacobian.
	// This step is done by an AD tool. For the purpose of illustration here, we read the structure from a file,
	// and store the structure in a Compressed Row Format.
	unsigned int *** uip3_SparsityPattern = new unsigned int **;	//uip3_ means triple pointers of type unsigned int
	double*** dp3_Value = new double**;	//dp3_ means triple pointers of type double. Other prefixes follow the same notation
	int rowCount, columnCount;
	ConvertMatrixMarketFormat2RowCompressedFormat(s_InputFile, uip3_SparsityPattern, dp3_Value,rowCount, columnCount);

	cout<<"just for debugging purpose, display the 2 matrices: the matrix with SparsityPattern only and the matrix with Value"<<endl;
	cout<<fixed<<showpoint<<setprecision(2); //formatting output
	cout<<"(*uip3_SparsityPattern)"<<endl;
	displayCompressedRowMatrix((*uip3_SparsityPattern),rowCount);
	cout<<"(*dp3_Value)"<<endl;
	displayCompressedRowMatrix((*dp3_Value),rowCount);
	cout<<"Finish ConvertMatrixMarketFormat2RowCompressedFormat()"<<endl;
	Pause();

	//Step 2: Obtain the seed matrix via coloring.
	double*** dp3_Seed = new double**;
	int *ip1_SeedRowCount = new int;
	int *ip1_SeedColumnCount = new int;
	int *ip1_ColorCount = new int; //The number of distinct colors used to color the graph

	//Step 2.1: Read the sparsity pattern of the given Jacobian matrix (compressed sparse rows format)
	//and create the corresponding bipartite graph
	BipartiteGraphPartialColoringInterface *g = new BipartiteGraphPartialColoringInterface(SRC_MEM_ADOLC, *uip3_SparsityPattern, rowCount, columnCount);

	//Step 2.2: Do Partial-Distance-Two-Coloring the bipartite graph with the specified ordering
	g->PartialDistanceTwoColoring( "SMALLEST_LAST", "COLUMN_PARTIAL_DISTANCE_TWO");

	//Step 2.3 (Option 1): From the coloring information, create and return the seed matrix
	(*dp3_Seed) = g->GetSeedMatrix(ip1_SeedRowCount, ip1_SeedColumnCount);
	/* Notes:
	Step 2.3 (Option 2): From the coloring information, you can also get the vector of colorIDs of left or right vertices  (depend on the s_ColoringVariant that you choose)
		vector<int> vi_VertexPartialColors;
		g->GetVertexPartialColors(vi_VertexPartialColors);
	*/
	cout<<"Finish GenerateSeed()"<<endl;
	*ip1_ColorCount = *ip1_SeedColumnCount;

	//Display results of step 2
	printf(" dp3_Seed %d x %d \n", *ip1_SeedRowCount, *ip1_SeedColumnCount);
	displayMatrix(*dp3_Seed, *ip1_SeedRowCount, *ip1_SeedColumnCount);
	Pause();

	// Step 3: Obtain the Jacobian-seed matrix product.
	// This step will also be done by an AD tool. For the purpose of illustration here, the orginial matrix V
	// (for Values) is multiplied with the seed matrix S. The resulting matrix is stored in dp3_CompressedMatrix.
	double*** dp3_CompressedMatrix = new double**;
	cout<<"Start MatrixMultiplication()"<<endl;
	MatrixMultiplication_VxS(*uip3_SparsityPattern, *dp3_Value, rowCount, columnCount, *dp3_Seed, *ip1_ColorCount, dp3_CompressedMatrix);
	cout<<"Finish MatrixMultiplication()"<<endl;

	displayMatrix(*dp3_CompressedMatrix,rowCount,*ip1_ColorCount);
	Pause();

	//Step 4: Recover the numerical values of the original matrix from the compressed representation.
	// The new values are store in "dp2_JacobianValue"
	unsigned int** ip2_RowIndex = new unsigned int*;
	unsigned int** ip2_ColumnIndex = new unsigned int*;
	double** dp2_JacobianValue = new double*;
	JacobianRecovery1D* jr1d = new JacobianRecovery1D;
	jr1d->RecoverD2Cln_SparseSolversFormat(g, *dp3_CompressedMatrix, *uip3_SparsityPattern, ip2_RowIndex, ip2_ColumnIndex, dp2_JacobianValue);
	cout<<"Finish Recover()"<<endl;

	cout<<endl<<"Display result, the structure and values should be similar to the original one"<<endl;
	cout<<"Display *ip2_RowIndex"<<endl;
	displayVector(*ip2_RowIndex,g->GetRowVertexCount()+1);
	cout<<"Display *ip2_ColumnIndex"<<endl;
	displayVector(*ip2_ColumnIndex, (*ip2_RowIndex)[g->GetRowVertexCount()]-1);
	cout<<"Display *dp2_JacobianValue"<<endl;
	displayVector(*dp2_JacobianValue, (*ip2_RowIndex)[g->GetRowVertexCount()]-1);
	Pause();

	//Deallocate memory using functions in Utilities/MatrixDeallocation.h

	free_2DMatrix(uip3_SparsityPattern, rowCount);
	uip3_SparsityPattern=NULL;

	free_2DMatrix(dp3_Value, rowCount);
	dp3_Value=NULL;

	delete dp3_Seed;
	dp3_Seed = NULL;

	delete ip1_SeedRowCount;
	ip1_SeedRowCount=NULL;

	delete ip1_SeedColumnCount;
	ip1_SeedColumnCount = NULL;

	free_2DMatrix(dp3_CompressedMatrix, rowCount);
	dp3_CompressedMatrix = NULL;

	delete ip1_ColorCount;
	ip1_ColorCount = NULL;

	delete jr1d;
	jr1d = NULL;

	delete ip2_RowIndex;
	delete ip2_ColumnIndex;
	delete dp2_JacobianValue;
	ip2_RowIndex=NULL;
	ip2_ColumnIndex=NULL;
	dp2_JacobianValue=NULL;

	delete g;
	g=NULL;

	return 0;
}