413 long long rows = (*Matrix_).NumGlobalRows64();
414 long long cols = (*Matrix_).NumGlobalCols64();
415 int num_edges = ((*Matrix_).NumMyNonzeros() - (*Matrix_).NumMyDiagonals())/2;
416 std::cout <<
"global num rows " << rows << std::endl;
419 IFPACK_CHK_ERR((rows == cols));
421 if(rows > std::numeric_limits<int>::max())
423 std::cerr <<
"Ifpack_SupportGraph<T>::FindSupport: global num rows won't fit an int. " << rows << std::endl;
428 int num_verts = (int) rows;
431 E *edge_array =
new E[num_edges];
432 double *weights =
new double[num_edges];
435 int max_num_entries = (*Matrix_).MaxNumEntries();
436 double *values =
new double[max_num_entries];
437 int *indices =
new int[max_num_entries];
439 double * diagonal =
new double[num_verts];
442 for(
int i = 0; i < max_num_entries; i++)
450 for(
int i = 0; i < num_verts; i++)
452 (*Matrix_).ExtractMyRowCopy(i,max_num_entries,num_entries,values,indices);
454 for(
int j = 0; j < num_entries; j++)
459 diagonal[i] = values[j];
469 edge_array[k] = E(i,indices[j]);
470 weights[k] = values[j];
474 weights[k] *= (1.0 + 1e-8 * drand48());
483 Graph g(edge_array, edge_array + num_edges, weights, num_verts);
486 property_map < Graph, edge_weight_t >::type weight = get(edge_weight, g);
488 std::vector < Edge > spanning_tree;
491 kruskal_minimum_spanning_tree(g, std::back_inserter(spanning_tree));
494 std::vector<int> NumNz(num_verts,1);
497 for (std::vector < Edge >::iterator ei = spanning_tree.begin();
498 ei != spanning_tree.end(); ++ei)
500 NumNz[source(*ei,g)] = NumNz[source(*ei,g)] + 1;
501 NumNz[target(*ei,g)] = NumNz[target(*ei,g)] + 1;
506 std::vector< std::vector< int > > Indices(num_verts);
511 std::vector< std::vector< double > > Values(num_verts);
513 for(
int i = 0; i < num_verts; i++)
515 std::vector<int> temp(NumNz[i],0);
516 std::vector<double> temp2(NumNz[i],0);
521 int *l =
new int[num_verts];
522 for(
int i = 0; i < num_verts; i++)
534 spanning_tree.clear();
535 kruskal_minimum_spanning_tree(g,std::back_inserter(spanning_tree));
536 for(std::vector < Edge >::iterator ei = spanning_tree.begin();
537 ei != spanning_tree.end(); ++ei)
539 NumNz[source(*ei,g)] = NumNz[source(*ei,g)] + 1;
540 NumNz[target(*ei,g)] = NumNz[target(*ei,g)] + 1;
542 for(
int i = 0; i < num_verts; i++)
544 Indices[i].resize(NumNz[i]);
545 Values[i].resize(NumNz[i]);
549 for (std::vector < Edge >::iterator ei = spanning_tree.begin();
550 ei != spanning_tree.end(); ++ei)
554 Indices[source(*ei,g)][0] = source(*ei,g);
555 Values[source(*ei,g)][0] = Values[source(*ei,g)][0] - weight[*ei];
556 Indices[target(*ei,g)][0] = target(*ei,g);
557 Values[target(*ei,g)][0] = Values[target(*ei,g)][0] - weight[*ei];
559 Indices[source(*ei,g)][l[source(*ei,g)]] = target(*ei,g);
560 Values[source(*ei,g)][l[source(*ei,g)]] = weight[*ei];
561 l[source(*ei,g)] = l[source(*ei,g)] + 1;
563 Indices[target(*ei,g)][l[target(*ei,g)]] = source(*ei,g);
564 Values[target(*ei,g)][l[target(*ei,g)]] = weight[*ei];
565 l[target(*ei,g)] = l[target(*ei,g)] + 1;
582 Matrix_->Multiply(
false, ones, surplus);
584 for(
int i = 0; i < num_verts; i++)
586 Values[i][0] += surplus[i];
594#ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
595 if((*Matrix_).RowMatrixRowMap().GlobalIndicesLongLong())
598 for(
int i = 0; i < num_verts; i++)
600 std::vector<long long> IndicesLL(l[i]);
601 for(
int k = 0; k < l[i]; ++k)
602 IndicesLL[k] = Indices[i][k];
604 (*Support_).InsertGlobalValues(i,l[i],&Values[i][0],&IndicesLL[0]);
609#ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
610 if((*Matrix_).RowMatrixRowMap().GlobalIndicesInt())
613 for(
int i = 0; i < num_verts; i++)
615 (*Support_).InsertGlobalValues(i,l[i],&Values[i][0],&Indices[i][0]);
620 throw "Ifpack_SupportGraph::FindSupport: GlobalIndices unknown.";;
622 (*Support_).FillComplete();