From fd733201b82f39655488a286c89142f321ef9dc9 Mon Sep 17 00:00:00 2001 From: Sylvain Chiron Date: Sat, 1 Jul 2017 13:36:41 +0200 Subject: Updated libs from the Adaptagrams project: libavoid, libcola and libvspc; changed the code to match the new API Signed-off-by: Sylvain Chiron --- src/libcola/conjugate_gradient.cpp | 124 ++++++++++++++++++++++--------------- 1 file changed, 73 insertions(+), 51 deletions(-) (limited to 'src/libcola/conjugate_gradient.cpp') diff --git a/src/libcola/conjugate_gradient.cpp b/src/libcola/conjugate_gradient.cpp index 67d15d6a0..adb7fa67f 100644 --- a/src/libcola/conjugate_gradient.cpp +++ b/src/libcola/conjugate_gradient.cpp @@ -1,32 +1,60 @@ -#include -#include -#include -#include -#include "conjugate_gradient.h" - /* -* Authors: -* Nathan Hurst -* Tim Dwyer -* -* Copyright (C) 2006 Authors -* -* Released under GNU LGPL. + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libcola - A library providing force-directed network layout using the + * stress-majorization method subject to separation constraints. + * + * Copyright (C) 2006 Nathan Hurst + * Copyright (C) 2006-2008 Monash University + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * See the file LICENSE.LGPL distributed with the library. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Author(s): Nathan Hurst + * Tim Dwyer + * */ + +#include +#include +#include +#include + +#include "libvpsc/assertions.h" +#include "libcola/commondefs.h" +#include "libcola/conjugate_gradient.h" + /* lifted wholely from wikipedia. Well, apart from the bug in the wikipedia version. */ using std::valarray; static void matrix_times_vector(valarray const &matrix, /* m * n */ - valarray const &vec, /* n */ - valarray &result) /* m */ + valarray const &vec, /* n */ + valarray &result) /* m */ { unsigned n = vec.size(); unsigned m = result.size(); - assert(m*n == matrix.size()); + COLA_ASSERT(m*n == matrix.size()); +# if defined(_MSC_VER) + // magmy: The following lines show how operator[] is defined for valarray under MSVC + // _Ty valarray<_Ty>::operator[](size_t _Off) const; + // _Ty &valarray<_Ty>::operator[](size_t _Off); + // As a consequence, it is not possible to take the address of a constant valarray[n]. + // This looks like a bug in the Microsoft's file. + // Below is a workaround + double const *mp = &const_cast &>(matrix)[0]; +# else const double* mp = &matrix[0]; +# endif for (unsigned i = 0; i < m; i++) { double res = 0; for (unsigned j = 0; j < n; j++) @@ -50,66 +78,60 @@ inner(valarray const &x, return total;// (x*y).sum(); <- this is more concise, but ineff } -void -conjugate_gradient(double **A, - double *x, - double *b, - unsigned n, - double tol, - unsigned max_iterations) { - valarray vA(n*n); - valarray vx(n); - valarray vb(n); - for(unsigned i=0;i const &A, + valarray const &b, + valarray const &x, + const unsigned n) { + // computes cost = 2 b x - x A x + double cost = 2. * inner(b,x); + valarray Ax(n); + for (unsigned i=0; i const &A, - valarray &x, - valarray const &b, - unsigned n, double tol, - unsigned max_iterations) { + valarray &x, + valarray const &b, + unsigned const n, double const tol, + unsigned const max_iterations) { + //printf("Conjugate Gradient...\n"); valarray Ap(n), p(n), r(n); matrix_times_vector(A,x,Ap); r=b-Ap; double r_r = inner(r,r); unsigned k = 0; - tol *= tol; - while(k < max_iterations && r_r > tol) { + double tol_squared = tol*tol; +#ifdef EXAMINE_COST + double previousCost=compute_cost(A,b,x,n),cost; +#endif + while(k < max_iterations && r_r > tol_squared) { k++; double r_r_new = r_r; if(k == 1) p = r; else { r_r_new = inner(r,r); + if(r_r_new