forked from sanshar/Block
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fiedler.C
107 lines (94 loc) · 2.94 KB
/
fiedler.C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
Developed by Roberto Olivares-Amaya and Garnet K.-L. Chan, 2013
Copyright (c) 2013, Garnet K.-L. Chan
This program is integrated in Molpro with the permission of
Sandeep Sharma, Garnet K.-L. Chan and Roberto Olivares-Amaya
*/
#include <vector>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <newmat.h>
#include <newmatio.h>
#include <newmatap.h>
#include <sortutils.h>
#include "fiedler.h"
#ifdef UNITTEST
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE Fiedler
#include <boost/test/unit_test.hpp>
#include <boost/test/included/unit_test.hpp>
#endif
Matrix argpermute(const Matrix& m, const int* indices)
{
Matrix newm(m.Nrows(),m.Ncols());
newm=0.;
for (int i=0;i<m.Nrows();++i)
for (int j=0;j<m.Ncols();++j)
newm.element(i,j)=m.element(indices[i],indices[j]);
return newm;
}
Matrix permute(const Matrix& m, const int* indices)
{
Matrix newm(m.Nrows(),m.Ncols());
newm=0.;
for (int i=0;i<m.Nrows();++i){
for (int j=0;j<m.Ncols();++j){
newm.element(indices[i],indices[j])=m.element(i,j);
}
}
return newm;
}
std::vector<int> fiedler_reorder(const SymmetricMatrix& m)
{
SymmetricMatrix absm=m;
const int nrows=m.Nrows();
for (int i=0;i<nrows;++i) {
for (int j=0;j<=i;++j){
//absolute value
absm.element(i,j)=std::fabs(absm.element(i,j));
}
}
//laplacian
SymmetricMatrix lap(nrows);
lap=0.;
for (int i=0;i<nrows;++i)
lap.element(i,i)=absm.Row(i+1).Sum();
lap-=absm;
DiagonalMatrix eigs;
Matrix vecs;
EigenValues(lap,eigs,vecs);
ColumnVector fvec=vecs.Column(2);
std::vector<double> fvec_stl(nrows);
//copies over fvec to fvec_stl
std::copy(&fvec.element(0),&fvec.element(0)+nrows,fvec_stl.begin());
std::vector<int> findices;
//sorts the data by eigenvalue in ascending order
sort_data_to_indices(fvec_stl,findices);
return findices;
/* BLOCK works with findices*/
}
#ifdef UNITTEST
// General: Evaluates fiedler_reorder for a Huckel case
// Subroutines tested: permute, fiedler_reorder
BOOST_AUTO_TEST_CASE(Fiedler){
std::vector<int> reorderTest;
int vSize=8;
Matrix h(vSize,vSize);
SymmetricMatrix hsym;
h=0.;
for (int i=0;i<vSize;++i)
for (int j=0;j<vSize;++j)
if (abs(i-j)==1)
h.element(i,j)=-1.;
//Setting up a permutation of indices
int indices[]={1,0,5,7,4,2,3,6};
//Permuting
Matrix hper=permute(h,indices);
hsym << hper;
reorderTest = fiedler_reorder(hsym);
std::vector<int> expected(vSize);
for (int i=0;i<vSize;i++) expected.at(i)=indices[(vSize-1)-i];
// Running the test
BOOST_CHECK_EQUAL_COLLECTIONS(reorderTest.begin(), reorderTest.end(), expected.begin(), expected.end()); }
#endif