Mercurial > octave-nkf
view liboctave/UMFPACK/UMFPACK/OCTAVE/luflop.cc @ 5164:57077d0ddc8e
[project @ 2005-02-25 19:55:24 by jwe]
author | jwe |
---|---|
date | Fri, 25 Feb 2005 19:55:28 +0000 |
parents | |
children |
line wrap: on
line source
/* Copyright (C) 2004 David Bateman This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program 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. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. In addition to the terms of the GPL, you are permitted to link this program with any Open Source program, as defined by the Open Source Initiative (www.opensource.org) */ /* This is the Octave interface to the UMFPACK code, which bore the following copyright UMFPACK Version 4.3 (Jan. 16, 2004), Copyright (c) 2004 by Timothy A. Davis. All Rights Reserved. See ../README for License. email: davis@cise.ufl.edu CISE Department, Univ. of Florida. web: http://www.cise.ufl.edu/research/sparse/umfpack */ #include <cstdlib> #include <string> #include <octave/config.h> #include <octave/ov.h> #include <octave/defun-dld.h> #include <octave/pager.h> #include <octave/ov-re-mat.h> #include "ov-re-sparse.h" #include "ov-cx-sparse.h" DEFUN_DLD (luflop, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{f} =} luflup (@var{l}, @var{u})\n\ \n\ Given an LU factorization, compute how many flops took to compute it. This\n\ is the same as (assuming U has a zero-free diagonal):\n\ \n\ @example\n\ @group\n\ Lnz = full (sum (spones (L))) - 1 ;\n\ Unz = full (sum (spones (U')))' - 1 ;\n\ f = 2*Lnz*Unz + sum (Lnz) ;\n\ @end group\n\ @end example\n\ \n\ except that no extra workspace is allocated for spones (L) and spones (U).\n\ L and U must be sparse.\n\ \n\ Note: the above expression has a subtle undercount when exact numerical\n\ cancelation occurs. Try [L,U,P] = lu (sparse (ones (10))) and then\n\ luflop (L,U).\n\ @end deftypefn") { int nargin = args.length (); octave_value retval; // These are here only so that the C++ destructors don't prematurally // remove the underlying data we are interested in SparseMatrix Lmatrix, Umatrix; SparseComplexMatrix CLmatrix, CUmatrix; int *Lp, *Li, *Up, *Ui; int Lm, Ln, Um, Un; if (nargin != 2) { usage ("f = luflop (L, U)"); return retval; } if (args(0).class_name () == "sparse") { if (args(0).is_complex_type ()) { CLmatrix = (((const octave_sparse_complex_matrix&) args(0).get_rep ()) .sparse_complex_matrix_value ()); Lp = CLmatrix.cidx (); Li = CLmatrix.ridx (); Lm = CLmatrix.rows (); Ln = CLmatrix.cols (); } else { Lmatrix = (((const octave_sparse_matrix&) args(0).get_rep ()) .sparse_matrix_value ()); Lp = Lmatrix.cidx (); Li = Lmatrix.ridx (); Lm = Lmatrix.rows (); Ln = Lmatrix.cols (); } } else { if (args(0).is_complex_type ()) { CLmatrix = SparseComplexMatrix (args(0).complex_matrix_value ()); Lp = CLmatrix.cidx (); Li = CLmatrix.ridx (); Lm = CLmatrix.rows (); Ln = CLmatrix.cols (); } else { Lmatrix = SparseMatrix (args(0).matrix_value ()); Lp = Lmatrix.cidx (); Li = Lmatrix.ridx (); Lm = Lmatrix.rows (); Ln = Lmatrix.cols (); } } if (args(0).class_name () == "sparse") { if (args(1).is_complex_type ()) { CUmatrix = (((const octave_sparse_complex_matrix&) args(1).get_rep ()) .sparse_complex_matrix_value ()); Up = CUmatrix.cidx (); Ui = CUmatrix.ridx (); Um = CUmatrix.rows (); Un = CUmatrix.cols (); } else { Umatrix = (((const octave_sparse_matrix&) args(1).get_rep ()) .sparse_matrix_value ()); Up = Umatrix.cidx (); Ui = Umatrix.ridx (); Um = Umatrix.rows (); Un = Umatrix.cols (); } } else { if (args(1).is_complex_type ()) { CUmatrix = SparseComplexMatrix (args(1).complex_matrix_value ()); Up = CUmatrix.cidx (); Ui = CUmatrix.ridx (); Um = CUmatrix.rows (); Un = CUmatrix.cols (); } else { Umatrix = SparseMatrix (args(1).matrix_value ()); Up = Umatrix.cidx (); Ui = Umatrix.ridx (); Um = Umatrix.rows (); Un = Umatrix.cols (); } } if (error_state) return retval; int n = Lm; if (n != Ln || n != Um || n != Un) error ("luflop: L and U must be square"); else { OCTAVE_LOCAL_BUFFER (int, Unz, n); // count the nonzeros in each row of U for (int row = 0 ; row < n ; row++) Unz [row] = 0 ; for (int col = 0 ; col < n ; col++) { for (int p = Up [col] ; p < Up [col+1] ; p++) { int row = Ui [p] ; Unz [row]++ ; } } // count the flops double flop_count = 0.0 ; for (int k = 0 ; k < n ; k++) { /* off-diagonal nonzeros in column k of L: */ int Lnz_k = Lp [k+1] - Lp [k] - 1 ; int Unz_k = Unz [k] - 1 ; flop_count += (2 * Lnz_k * Unz_k) + Lnz_k ; } // return the result retval = flop_count; } return retval; } /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */