<commit_before>
import os
import numpy as np

from seisflows.tools import unix


class NLCG:
    """ Nonlinear conjugate gradient method
    """

    def __init__(self, path, thresh, itercgmax):

        self.path = path
        unix.mkdir(self.path+'/'+'NLCG')

        self.load = load
        self.save = save

        self.itercgmax = itercgmax
        self.thresh = thresh

        try:
            self.itercg = loadtxt(self.path+'/'+'NLCG/itercg')
        except IOError:
            self.itercg = 0

    def compute(self):

        # utility functions

        def fletcher_reeves():
            # fletcher-reeves update
            top = np.dot(g_new, g_new)
            bot = np.dot(g_old, g_old)
            beta = top/bot
            return -g_new + beta*p_old

        def pollak_ribere():
            # pollack-riebere update
            top = np.dot(g_new, g_new-g_old)
            bot = np.dot(g_old, g_old)
            beta = top/bot
            return -g_new + beta*p_old

        def rho():
            return abs(np.dot(g_new, g_old) / np.dot(g_new, g_new))


        # algorithm starts here
        self.itercg += 1
        savetxt(self.path+'/'+'NLCG/itercg', self.itercg)

        unix.cd(self.path)
        g_new = self.load('g_new')

        if self.itercg == 1:
            return -g_new

        if self.itercg > self.itercgmax:
            print 'restarting NLCG... [periodic restart]'
            self.restart()
            return -g_new

        # compute NLCG direction
        g_old = self.load('g_old')
        p_old = self.load('p_old')
        p_new = pollak_ribere()

        # check restart conditions
        if rho() > self.thresh:
            print 'restarting NLCG... [loss of conjugacy]'
            self.restart()
            return -g_new

        elif np.dot(p_new, g_new) > 0:
            print 'restarting NLCG... [not a descent direction]'
            self.restart()
            return -g_new

        else:
            return p_new


    def restart(self):
        self.itercg = 1
        savetxt(self.path+'/'+'NLCG/itercg', self.itercg)



def loadtxt(filename):
    return int(np.loadtxt(filename))


def savetxt(filename, v):
    np.savetxt(filename, [v], '%d')


def load(filename):
    return np.load(filename)


def save(filename, v):
    np.save(filename, v)
    unix.mv(filename+'.npy', filename)
<commit_msg>refactored lib.NLCG<commit_after>
import os
import numpy as np

from seisflows.tools import unix

from seisflows.tools.array import loadnpy, savenpy
from seisflows.tools.code import loadtxt, savetxt



class NLCG:
    """ Nonlinear conjugate gradient method
    """

    def __init__(self, path, thresh, itermax):

        self.path = path
        unix.mkdir(self.path+'/'+'NLCG')

        self.itermax = itermax
        self.thresh = thresh

        try:
            self.iter = loadtxt(self.path+'/'+'NLCG/iter')
        except IOError:
            self.iter = 0


    def compute(self):
        """ Given gradient, returns NLCG search direction
        """
        self.iter += 1
        savetxt(self.path+'/'+'NLCG/iter', self.iter)

        unix.cd(self.path)
        g_new = loadnpy('g_new')

        if self.iter == 1:
            return -g_new

        elif self.iter > self.itermax:
            print 'restarting NLCG... [periodic restart]'
            self.restart()
            return -g_new

        # compute search direction
        g_old = loadnpy('g_old')
        p_old = loadnpy('p_old')
        beta = pollak_ribere(g_new, g_old)
        p_new = -g_new + beta*p_old

        # check restart conditions
        if check_conjugacy(g_new, g_old) > self.thresh:
            print 'restarting NLCG... [loss of conjugacy]'
            self.restart()
            return -g_new

        elif check_descent(p_new, g_new) > 0.:
            print 'restarting NLCG... [not a descent direction]'
            self.restart()
            return -g_new

        else:
            return p_new


    def restart(self):
        """ Restarts algorithm
        """
        self.iter = 1
        savetxt(self.path+'/'+'NLCG/iter', self.iter)



### utility functions

def fletcher_reeves(g_new, g_old):
    num = np.dot(g_new, g_new)
    den = np.dot(g_old, g_old)
    beta = num/den
    return beta

def pollak_ribere(g_new, g_old):
    num = np.dot(g_new, g_new-g_old)
    den = np.dot(g_old, g_old)
    beta = num/den
    return beta

def check_conjugacy(g_new, g_old):
    return abs(np.dot(g_new, g_old) / np.dot(g_new, g_new))

def check_descent(p_new, g_new):
    return np.dot(p_new, g_new) / np.dot(g_new, g_new)





{'fraction_non_alphanumeric': 0.11549357158422315, 'fraction_numerical': 0.0021791239921551534, 'mean_word_length': 1.8509316770186335, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6588588', 'n_tokens_mistral': 1635, 'n_tokens_neox': 1568, 'n_words': 351}