fr., 03.09.2010 kl. 09.08 -0700, skrev klmn:
> Dear all,
>
> I am trying to implement various schemes for storing Gaunt
> coefficients (integrals of 3 spherical harmonics) calculated
> symbolically. Ondrej, I remember you offered me help for this, now I
> have to ask for it.
>
> It appears that at moderately big indices, already at l_max~30, the
> memory is all eaten up. I tried to force garbage collection, without
> success. Interestingly, if I repeatedly calculate just one Gaunt
> coefficient for a fixed set of indices, there is no memory problem
> (commented out in the script below)…
What do you mean by "force garbage collection"? Have you tried
>>> sympy.cache.clear_cache()
Øyvind
>
> There is no memory leak per se. When I exit from Python, the memory is
> fully recovered. It seems that the garbage is not collected during the
> calculations, even when asked, untill it occupies the whole memory.
>
> Below I attach a test module. Sorry for the long post: I don’t see a
> way how I could attach it as a file (I am using a web form).
>
> Can you recommend me a memory saving approach?
>
> Best regards,
> Konstantin
>
> ****************************************
> import numpy as np
> import sympy
> import tables
> #import gc
> import time
>
> factorials=[sympy.Integer(1)]
>
> def get_factorials(nn):
> """ Precalculated factorials """
> if nn >= len(factorials):
> for ii in range(len(factorials), nn + 1):
> factorials.append(factorials[ii - 1] * ii)
> return factorials[:(nn + 1)]
>
> def zero_gaunt_l(l_1, l_2, l_3):
> """
> Checks l indices for giving an even sum and fulfilling the
> triangle realtion.
> """
> if np.mod(l_1 + l_2 + l_3, 2) != 0: return True
> if l_1 + l_2 - l_3 < 0: return True
> if l_1 - l_2 + l_3 < 0: return True
> if -l_1 + l_2 + l_3 < 0: return True
> return False
>
> def zero_gaunt_m(l_1, l_2, l_3, m_1, m_2, m_3):
> """
> Checks m indices for giving 0 sum and being limited by l's
> """
> if (m_1 + m_2 + m_3) != 0: return True
> if (abs(m_1) > l_1) or (abs(m_2) > l_2) or (abs(m_3) > l_3):
> return True
> return False
>
> def gaunt(l_1, l_2, l_3, m_1, m_2, m_3, prec=None, include4Pi=True):
> """
> Check validity of the indices and calculate the Gaunt coefficient.
> """
> if type(l_1) != type(l_2) != type(l_3) != type(1):
> raise ValueError("l values must be integer")
> if type(m_1) != type(m_2) != type(m_3) != type(1):
> raise ValueError("m values must be integer")
>
> if zero_gaunt_l(l_1, l_2, l_3): return 0
> if zero_gaunt_m(l_1, l_2, l_3, m_1, m_2, m_3): return 0
>
> return calc_gaunt(l_1, l_2, l_3, m_1, m_2, m_3, prec, include4Pi)
>
> def calc_gaunt(l_1, l_2, l_3, m_1, m_2, m_3, prec=None,
> include4Pi=True):
> """
> Calculate the Gaunt coefficient.
> """
> a1 = l_1 + l_2 - l_3
> a2 = l_1 - l_2 + l_3
> a3 = -l_1 + l_2 + l_3
>
> bigL = (l_1 + l_2 + l_3) / 2
> a4 = -l_3 + l_1 + m_2
> a5 = -l_3 + l_2 - m_1
> imin = max(a4, a5, 0)
> a6 = l_2 + m_2
> a7 = l_1 - m_1
> imax = min(a6, a7, a1)
>
> maxFactorial = max(l_1 + l_2 + l_3, imax) + 1
> get_factorials(maxFactorial)
>
> trySeparate = True # test whether the factors under sqrt must be
> kept
> if trySeparate:
> prefac1 = sympy.sqrt(2 * l_1 + 1) *\
> sympy.sqrt(2 * l_2 + 1) *\
> sympy.sqrt(2 * l_3 + 1) *\
> sympy.sqrt(factorials[a7]) *\
> sympy.sqrt(factorials[l_1 + m_1]) *\
> sympy.sqrt(factorials[l_2 - m_2]) *\
> sympy.sqrt(factorials[a6]) *\
> sympy.sqrt(factorials[l_3 - m_3]) *\
> sympy.sqrt(factorials[l_3 + m_3])
> else:
> prefac1 = sympy.sqrt((2 * l_1 + 1) * (2 * l_2 + 1) * (2 * l_3
> + 1) *\
> factorials[a7] *\
> factorials[l_1 + m_1] *\
> factorials[l_2 - m_2] *\
> factorials[a6] *\
> factorials[l_3 - m_3] *\
> factorials[l_3 + m_3])
> if include4Pi:
> prefac1 /= (sympy.sqrt(sympy.pi) * sympy.Integer(2))
>
> prefac2 = factorials[bigL] * factorials[a1] * factorials[a2] *
> factorials[a3] /\
> (factorials[2 * bigL + 1] *\
> factorials[bigL - l_1] * factorials[bigL - l_2] *
> factorials[bigL - l_3])
>
> sumres = 0
> for ii in range(imin, imax + 1):
> den = factorials[ii] * factorials[a1 - ii] *\
> factorials[ii - a4] * factorials[ii - a5] *\
> factorials[a6 - ii] * factorials[a7 - ii]
> if np.mod(ii, 2) == 0:
> sumres += sympy.Integer(1) / den
> else:
> sumres -= sympy.Integer(1) / den
> res = prefac1 * prefac2 * sumres
> if np.mod((bigL + l_3 + m_1 - m_2), 2) != 0:
> res = -res
>
> if prec is not None:
> res = res.evalf(prec)
> return res
>
> def store_Rasch_Yu(fileName, l_max):
> filters = tables.Filters(complevel=1, complib='zlib')
> #complib='zlib'|'blosc'
> with tables.openFile(fileName, mode = "w") as fileh:
> vlarray0 = fileh.createVLArray(fileh.root, 'vlarray',
> tables.ObjectAtom(),
> "pickled Gaunt coeffs", filters=filters,
> expectedsizeinMB=(l_max*0.1)**4)
>
> zeroList = []
> indices = 0
> for l_1 in xrange(l_max + 1):
> for l_2 in xrange(l_1 + 1):
> for l_3 in xrange(l_2 + 1):
> if zero_gaunt_l(l_1, l_2, l_3):
> for m_3 in xrange(l_3 + 1):
> # vlarray0.append(zeroList)
> indices += 1
> continue
> print l_1, l_2, l_3
> for m_3 in xrange(l_3 + 1):
> m3list = []
> for m_2 in xrange(-l_2, min(l_1 - m_3, l_2) +
> 1):
> m_1 = -m_2 - m_3
> if zero_gaunt_m(l_1, l_2, l_3, m_1, m_2,
> m_3):
> curGaunt = sympy.Integer(0)
> else:
> curGaunt = calc_gaunt(l_1, l_2, l_3,
> m_1, m_2, m_3,
> include4Pi=False)
> # if I comment calc_gaunt above and uncomment the one below with a
> dummi
> # set of indices, there is no memory problem
> # curGaunt =
> calc_gaunt(29,29,34,10,-5,-5,
> # include4Pi=False)
> if type(curGaunt) in \
> [sympy.core.numbers.Integer,
> sympy.core.numbers.Zero,
> sympy.core.numbers.One,
> sympy.core.numbers.NegativeOne]:
> m2list = curGaunt
> elif type(curGaunt) ==
> sympy.core.numbers.Rational:
> m2list = [curGaunt.p, curGaunt.q]
> elif type(curGaunt) == sympy.core.mul.Mul:
> m2list = [0, 1, 0]
> for bas_arg in
> curGaunt.iter_basic_args():
> if type(bas_arg) ==
> sympy.core.numbers.Rational:
> m2list[0] = bas_arg.p
> m2list[1] = bas_arg.q
> elif type(bas_arg) ==
> sympy.core.power.Pow:
> if bas_arg.exp ==
> sympy.Integer(1)/2:
> m2list[2] = bas_arg.base
> else:
> raise ValueError('wrong type
> of Gaunt atoms')
> if (m2list[0] == 0) or (m2list[2] ==
> 0):
> raise ValueError('wrong value of
> Gaunt')
> else:
> print l_1, l_2, l_3, m_1, m_2, m_3
> print curGaunt, type(curGaunt)
> raise ValueError('wrong type of Gaunt
> result')
> m3list.append(m2list)
> # vlarray0.append(m3list)
> indices += 1
> # vlarray0.flush()
> # print 'collecting garbage...',
> # gc.collect()
> # print ' done'
>
> max_index_expected = (l_max + 1) * (l_max + 2) * (l_max + 3) *
> (l_max + 4) / 24
> print indices, max_index_expected
>
> if __name__ == '__main__':
> #!!!!!!!!!!!!!!!! VERY important !!!!!!!!!!!!!!!!
> #in sympy/core/numbers.py, line 1013:
> ## The following is an algorithm where we collect perfect roots
> ## from the factors of base
> #if b > 4294967296:
> # # Prevent from factorizing too big integers
> # return None
> # <------------------- comment it out!!!
> #end of !!!!!!!!!!!!!!!! VERY important !!!!!!!!!!!!!!!!
>
> tstart = time.time()
> store_Rasch_Yu('test_Rasch_Yu.h5', 30)
> tstop = time.time()
> print 'The calculation took {0:.1f} s'.format(tstop - tstart)
>
--
You received this message because you are subscribed to the Google Groups
"sympy" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sympy?hl=en.