[SciPy-User] GMRES iteration number
Pascal Bugnion
pascal at bugnion.org
Tue Jun 10 05:46:19 EDT 2014
The lightest way to make a callback that keeps track of the number of
times it is called is probably to use a closure:
def make_callback():
closure_variables = dict(counter=0) # initialize variables in this
# dict. The callback function
# has access to this data.
def callback(residuals):
closure_variables["counter"] += 1
print closure_variables["counter"]
return callback
Then, generate the callback function using
callback = make_callback()
callback() # prints 1
callback() # prints 2
callback() # prints 3
To give a full example using "gmres":
# -----------------------------------------------------------
import numpy as np
from scipy.sparse.linalg import gmres
# Generate random input data
A = 5*np.eye(10) + np.random.random(size=(10,10))
b = np.random.random(size=(10,))
# Callback generator
def make_callback():
closure_variables = dict(counter=0, residuals=[])
def callback(residuals):
closure_variables["counter"] += 1
closure_variables["residuals"].append(residuals)
print closure_variables["counter"], residuals
return callback
gmres(A,b,callback=make_callback())
# -----------------------------------------------------------
See also:
"http://eev.ee/blog/2011/04/24/gotcha-python-scoping-closures/#the-other-problem-mutating-outer-variables"
for other ways to use closures to implement a counter.
Pascal
On Mon, 09 Jun 2014 15:34:57 -0500
Eric Hermes <ehermes at chem.wisc.edu> wrote:
> Would it be possible to make the callback function an append
> operation on a list? e.g. create some list "residuals = []" and do
> "callback=residuals.append". Then the length of the list would tell
> you how many calls were made, and you would know what the residuals
> were along the way. Alternatively, I imagine you could do something
> like this:
>
> class Counter(object):
> def __init__(self):
> self.i = 0
> def __str__(self):
> return str(self.i)
> def addone(self, OPTIONAL_IGNORED_INPUT=None):
> self.i += 1
>
> blah = Counter()
>
> gmres(..., callback=blah.addone)
>
> print blah
>
> Eric
>
> On 6/9/2014 3:18 PM, Jonathan Tu wrote:
> > Hi,
> >
> > Using a callback makes sense to me conceptually, but I have never
> > implemented something like this. Is there a standard way to do
> > such a thing? I would like something lightweight, obviously. I
> > can imagine defining a small class containing a counter attribute
> > and a parens function that updates this value. This seems better
> > than doing something like defining a global variable that
> > callback() can modify. Since the callback function will be called
> > as callback(rk), where rk is the residual, I don't know how else to
> > have it update a value whose scope needs to lie outside the
> > callback function itself.
> >
> >
> >
> > Jonathan Tu
> >
> >
> > On May 30, 2014, at 1:47 AM, Ralf Gommers <ralf.gommers at gmail.com
> > <mailto:ralf.gommers at gmail.com>> wrote:
> >
> >>
> >>
> >>
> >> On Fri, May 30, 2014 at 10:37 AM, Arun Gokule
> >> <arun.gokule at gmail.com <mailto:arun.gokule at gmail.com>> wrote:
> >>
> >> AFAICT no.
> >>
> >>
> >> On Thu, May 29, 2014 at 1:20 PM, Jonathan Tu
> >> <jonathantu at gmail.com <mailto:jonathantu at gmail.com>> wrote:
> >>
> >> Hi,
> >>
> >> Is there any way to access the number of iterations it
> >> takes to complete a GMRES computation? I've checked the
> >> documentation at
> >> http://docs.scipy.org/doc/scipy-0.13.0/reference/generated/scipy.sparse.linalg.gmres.html
> >> and it doesn't appear so. I am doing some testing with passing
> >> in initial guesses x0, and I am interested to know whether
> >> or not this significantly reduces the required number of
> >> iterations.
> >>
> >>
> >> There's no return value that tells you tells (and we can't add one
> >> in nice a backwards-compatible way), but you can use a callback
> >> function to do this. Just provide a callback that increments some
> >> counter each time it is called.
> >>
> >> Ralf
> >>
> >>
> >>
> >>
> >>
> >> Thanks,
> >> Jonathan Tu
> >>
> >> _______________________________________________
> >> SciPy-User mailing list
> >> SciPy-User at scipy.org <mailto:SciPy-User at scipy.org>
> >> http://mail.scipy.org/mailman/listinfo/scipy-user
> >>
> >>
> >>
> >> _______________________________________________
> >> SciPy-User mailing list
> >> SciPy-User at scipy.org <mailto:SciPy-User at scipy.org>
> >> http://mail.scipy.org/mailman/listinfo/scipy-user
> >>
> >>
> >> _______________________________________________
> >> SciPy-User mailing list
> >> SciPy-User at scipy.org <mailto:SciPy-User at scipy.org>
> >> http://mail.scipy.org/mailman/listinfo/scipy-user
> >
> >
> >
> > _______________________________________________
> > SciPy-User mailing list
> > SciPy-User at scipy.org
> > http://mail.scipy.org/mailman/listinfo/scipy-user
>
More information about the SciPy-User
mailing list