package graphtea.extensions.reports.spectralreports; import Jama.EigenvalueDecomposition; import Jama.Matrix; import graphtea.graph.graph.GraphModel; import graphtea.plugins.reports.extension.GraphReportExtension; import javax.swing.*; import java.util.ArrayList; import java.util.Arrays; /** * Description here. * * @author Hooman Mohajeri Moghaddam */ public class LaplacianOfGraph implements GraphReportExtension { boolean inDegree; /** * Round func * @param value The value * @param decimalPlace The decimal place * @return rounded value of the input to the number of decimalPlace */ private double round(double value, int decimalPlace) { double power_of_ten = 1; while (decimalPlace-- > 0) power_of_ten *= 10.0; return Math.round(value * power_of_ten) / power_of_ten; } /** * Undirected Laplacian. * @param A the Adjacency matrix of the graph * @return Laplacian of the graph */ private Matrix getLaplacian(Matrix A) { //double[][] res=new double[g.numOfVertices()][g.numOfVertices()]; int n=A.getArray().length; double[][] ATemp = A.getArray(); Matrix D = new Matrix(n,n); double[][] DTemp = D.getArray(); int sum; if(inDegree) { for(int i=0; i<n ; i++ ) { sum = 0 ; for(int j=0; j<n ; j++) { sum+=ATemp[j][i]; } DTemp[i][i]=sum; } } else { for(int i=0; i<n ; i++ ) { sum = 0 ; for(int j=0; j<n ; j++) { sum+=ATemp[i][j]; } DTemp[i][i]=sum; } } return D.minus(A); } // private ArrayList<String> ShowLaplacian(Matrix A) { ArrayList<String> result = new ArrayList<>(); double[][] Lap = getLaplacian(A).getArray(); result.add("Laplacian Matrix:"); for(double[] k : Lap) { result.add( Arrays.toString(k)); } return result; } /** * Gets the eigen values and vectors of the graph and returns them as an array of strings. * @param matrix the Adjacency matrix of the graph * @return Laplacian of the graph */ private ArrayList<String> getEigenValuesAndVectors(Matrix matrix) { ArrayList<String> result = new ArrayList<>(); result.add("Eigen Value Decomposition:"); EigenvalueDecomposition ed = getLaplacian(matrix).eig(); double rv[] = ed.getRealEigenvalues(); double iv[] = ed.getImagEigenvalues(); for (int i = 0; i < rv.length; i++) if (iv[i] != 0) result.add("" + round(rv[i], 3) + " + " + round(iv[i], 3) + "i"); else result.add("" + round(rv[i], 3)); result.add("Eigen Vectors:\n"); double[][] eigenVectors = ed.getV().getArray(); for (int k = 0; k < eigenVectors.length; k++) result.add(Arrays.toString(round(eigenVectors[k], 3))); return result; } private double[] round (double[] array, int prec) { double[] res=array; for(int i=0;i<array.length;i++) res[i]=round(res[i],prec); return res; } public String getName() { return "Spectrum of Laplacian"; } public String getDescription() { return "The Laplacian matrix associated with the graph"; } public Object calculate(GraphModel g) { try { if(g.isDirected()) { int a = JOptionPane.showOptionDialog(null, "Do you want to use in or out degrees for calculation of the Laplacian Matrix?", "Laplacian", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, new String[]{"In Degrees", "Out Degrees"}, "In Degrees"); if (a== -1) return null; else if(a==0) inDegree = true; else inDegree = false; } Matrix A = g.getWeightedAdjacencyMatrix(); ArrayList<String> calc = new ArrayList<>(ShowLaplacian(A)); calc.addAll(getEigenValuesAndVectors(A)); return(calc); } catch (Exception e) { // TODO Auto-generated catch block } return null; } @Override public String getCategory() { return "Spectral"; } }