<gh_stars>100-1000
"""
Script with classes and functions for nucleosome calling.

@author: <NAME>, Greenleaf Lab, Stanford University
"""

import numpy as np
from scipy import optimize, signal
from copy import copy
from bisect import bisect_left
import pyximport; pyximport.install(setup_args={"include_dirs":np.get_include()})
from nucleoatac.multinomial_cov import calculateCov
from nucleoatac.Occupancy import OccupancyTrack
from pyatac.tracks import Track, CoverageTrack
from pyatac.chunk import Chunk
from pyatac.utils import call_peaks, reduce_peaks, read_chrom_sizes_from_bam
from pyatac.chunkmat2d import FragmentMat2D, BiasMat2D
from pyatac.bias import InsertionBiasTrack, PWM

#import warnings
#warnings.filterwarnings('error')

class SignalTrack(Track):
    """Class for getting V-plot signal"""
    def __init__(self, chrom, start, end):
        Track.__init__(self, chrom, start, end, "signal")
    def calculateSignal(self, mat, vmat):
        offset=self.start-mat.start-vmat.w
        if offset<0:
            raise Exception("Insufficient flanking region on \
                    mat to calculate signal")
        self.vals = signal.correlate(mat.get(vmat.lower,vmat.upper,
                                              mat.start + offset, mat.end - offset),
                                       vmat.mat,mode = 'valid')[0]

class NormSignalTrack(Track):
    """Class for storing normalized signal track"""
    def __init__(self, chrom, start, end):
        Track.__init__(self, chrom, start, end, "normalized signal")
    def calculateNormSignal(self, raw, bias):
        self.vals = raw.get(self.start, self.end) - bias.get(self.start,self.end)

class BiasTrack(Track):
    """Class for getting Bias Signal Track-- Background model"""
    def __init__(self, chrom, start, end):
        Track.__init__(self, chrom, start, end, "bias")
    def calculateBackgroundSignal(self, mat, vmat, nuc_cov):
        offset=self.start-mat.start-vmat.w
        if offset<0:
            raise Exception("Insufficient flanking region on \
                    mat to calculate signal")
        self.vmat = vmat
        self.bias_mat = mat
        self.cov = CoverageTrack(self.chrom, self.start, self.end)
        self.cov.calculateCoverage(self.bias_mat, vmat.lower,
                                   vmat.upper, vmat.w*2+1)
        self.nuc_cov = nuc_cov.vals
        self.vals = signal.correlate(self.bias_mat.get(vmat.lower,vmat.upper,
                                                         self.bias_mat.start + offset,
                                                         self.bias_mat.end - offset),
                                       vmat.mat,mode = 'valid')[0]
        self.vals = self.vals * self.nuc_cov/ self.cov.vals

class SignalDistribution:
    """Class for determining distribution of signal"""
    def __init__(self, position, vmat, bias_mat, reads):
        self.position = position
        self.reads = reads
        self.vmat = vmat
        bias_mat = bias_mat.get(vmat.lower,vmat.upper,position - vmat.w,position  + vmat.w + 1)
        self.prob_mat = bias_mat / np.sum(bias_mat)
        self.probs = self.prob_mat.flatten()
    def simulateReads(self):
        sim_vect = np.random.multinomial(self.reads,self.probs)
        sim_mat = np.reshape(sim_vect, self.vmat.mat.shape)
        return sim_mat
    def simulateDist(self, numiters = 1000):
        self.scores = map(lambda x: np.sum(self.simulateReads() * self.vmat.mat),range(numiters))
    def analStd(self):
        flatv = np.ravel(self.vmat.mat)
        var = calculateCov(self.probs, flatv, self.reads)
        return np.sqrt(var)
    def analMean(self):
        return np.sum(self.prob_mat * self.vmat.mat * self.reads)

def norm(x, v, w, mean):
    """compute values of normal pdf with given mean and sd at values in x"""
    norm = (1.0/(np.sqrt(2*np.pi*v)) *
        np.exp(-(x - mean)**2/(2*v)))
    norm = norm * (w/max(norm))
    return norm

class Nucleosome(Chunk):
    """Class for storing information about a single nucleosome"""
    def __init__(self, pos,nuctrack):
        self.chrom = nuctrack.chrom
        self.start = pos
        self.end = pos + 1
        self.nfr_cov = nuctrack.nfr_cov.get(pos = pos)
        self.nuc_cov = nuctrack.nuc_cov.get(pos = pos)
        self.nuc_signal = nuctrack.nuc_signal.get(pos = pos)
        self.norm_signal = nuctrack.norm_signal.get(pos = pos)
        self.smoothed = nuctrack.smoothed.get(pos= pos)
    def getLR(self,nuctrack):
        mat = nuctrack.mat.get(nuctrack.params.lower,nuctrack.params.upper,
                                self.start - nuctrack.params.vmat.w, self.start + nuctrack.params.vmat.w +1)
        null_mat = nuctrack.bias_mat.get(nuctrack.params.lower,nuctrack.params.upper,
                                self.start - nuctrack.params.vmat.w, self.start + nuctrack.params.vmat.w +1)
        bias_mat =nuctrack.bias_mat_prenorm.get(nuctrack.params.lower,nuctrack.params.upper,
                                self.start - nuctrack.params.vmat.w, self.start + nuctrack.params.vmat.w +1)
        nuc_model = nuctrack.params.vmat.mat * bias_mat
        nuc_model = nuc_model / np.sum(nuc_model)
        null_model = null_mat / np.sum(null_mat)
        nuc_lik = np.sum(np.log(nuc_model) * mat)
        null_lik = np.sum(np.log(null_model) * mat)
        self.lr = nuc_lik - null_lik
    def getZScore(self, nuctrack):
        s = SignalDistribution(self.start, nuctrack.params.vmat, nuctrack.bias_mat,
                                self.nuc_cov)
        std = s.analStd()
        self.z = self.norm_signal / std
    def getOcc(self, nuctrack):
        try:
            self.occ = nuctrack.occ.get(pos = self.start)
            self.occ_lower = nuctrack.occ_lower.get(pos = self.start)
            self.occ_upper = nuctrack.occ_upper.get(pos = self.start)
        except:
            self.occ = np.nan
            self.occ_lower = np.nan
            self.occ_upper = np.nan
    def getFuzz(self, nuctrack):
        def addNorms(x,params):
            """Add several normal distributions together"""
            l = len(x)
            fit = np.zeros(l)
            i = len(params)/3
            for j in range(i):
                fit += norm(x,params[j*3],params[3*j+1],params[3*j+2])
            return fit
        def err_func(pars,y):
            """error function for normal fit; to be used for fitNorm"""
            x = np.linspace(0,len(y)-1,len(y))
            return sum((addNorms(x, pars) - y)**2)
        def fitNorm(guess, bound, sig):
            """Fit a normal to the signal with lower and upperbounds to sd"""
            a = (sig,)
            res = optimize.minimize(err_func,guess,args = a, bounds=bound,method="L-BFGS-B")
            return res
        index = self.start - nuctrack.start
        allnucs = nuctrack.sorted_nuc_keys
        x = bisect_left(allnucs,index)
        if x == 0:
            left = index - nuctrack.params.nonredundant_sep/3
            means = (nuctrack.params.nonredundant_sep/3,)
        elif index - allnucs[x-1] < nuctrack.params.nonredundant_sep:
            left = allnucs[x-1]
            means = (index - allnucs[x-1],0)
        else:
            left = index - nuctrack.params.nonredundant_sep/3
            means = (nuctrack.params.nonredundant_sep/3,)
        if x == len(allnucs)-1:
            right = index + nuctrack.params.nonredundant_sep/3 + 1
        elif allnucs[x+1] - index < nuctrack.params.nonredundant_sep:
            right = allnucs[x+1]
            means += (allnucs[x+1] - left,)
        else:
            right = index + nuctrack.params.nonredundant_sep/3 +1
        sig = nuctrack.smoothed.vals[left:right]
        sig[sig<0] = 0
        if len(means)==1:
            bounds = ((2**2,50**2),(0.001,max(sig)*1.1),(means[0]-10,means[0]+10))
            guesses = (nuctrack.params.smooth_sd ** 2,max(sig)*0.9,means[0])
        elif len(means)==2:
            bounds = ((2**2,50**2),(0.001,max(sig)*1.1),(means[0]-10,means[0]+10),
                        (2**2,50**2),(0.001,max(sig)*1.1),(means[1]-10,means[1]+10))
            guesses = (nuctrack.params.smooth_sd ** 2,max(sig)*0.9,means[0],
                    nuctrack.params.smooth_sd ** 2,max(sig)*0.9,means[1])
        elif len(means)==3:
            bounds = ((2**2,50**2),(0.001,max(sig)*1.1),(means[0]-10,means[0]+10),
                        (2**2,50**2),(0.001,max(sig)*1.1),(means[1]-10,means[1]+10),
                        (2**2,50**2),(0.001,max(sig)*1.1),(means[2]-10,means[2]+10))
            guesses = (nuctrack.params.smooth_sd ** 2,max(sig)*0.9,means[0],
                    nuctrack.params.smooth_sd ** 2,max(sig)*0.9,means[1],
                    nuctrack.params.smooth_sd ** 2,max(sig)*0.9,means[2])
        res= fitNorm(guesses, bounds, sig)
        self.fuzz= np.sqrt(res['x'][0])
        self.weight = res['x'][1]
        self.fit_pos = res['x'][2]+left
    def asBed(self):
        out = "\t".join(map(str,[self.chrom, self.start, self.end, self.z, self.occ, self.occ_lower, self.occ_upper, self.lr,
               self.norm_signal, self.nuc_signal, self.nuc_cov, self.nfr_cov,
                self.fuzz]))
        return out
    def write(self, handle):
       handle.write(self.asBed() + "\n")

class NucParameters:
    """Class for storing parameters related to nucleosome calling"""
    def __init__(self, vmat, fragmentsizes, bam, fasta, pwm,
                 occ_track = None, atac = True,
                 sd = 25, nonredundant_sep = 120, redundant_sep = 25,
                 min_z = 3, min_lr = 0, min_reads = 1):
        self.atac = atac
        self.vmat = vmat
        self.lower = vmat.lower
        self.upper= vmat.upper
        self.window = vmat.mat.shape[1]
        self.fragmentsizes= fragmentsizes
        self.min_reads = min_reads
        self.min_z = min_z
        self.min_lr = min_lr
        self.smooth_sd = sd
        self.redundant_sep = redundant_sep
        self.nonredundant_sep = nonredundant_sep
        self.fasta = fasta
        self.pwm = PWM.open(pwm)
        self.chrs = read_chrom_sizes_from_bam(bam)
        self.bam = bam
        self.occ_track = occ_track

class NucChunk(Chunk):
    """Class for storing and determining collection of nucleosome positions
    """
    def __init__(self, chunk):
        self.start = chunk.start
        self.end = chunk.end
        self.chrom = chunk.chrom
    def initialize(self, parameters):
        self.params = parameters
    def getFragmentMat(self):
        self.mat = FragmentMat2D(self.chrom, self.start - max(self.params.window,self.params.upper/2+1),
                                 self.end + max(self.params.window,self.params.upper/2+1), 0, self.params.upper, atac = self.params.atac)
        self.mat.makeFragmentMat(self.params.bam)
    def makeBiasMat(self):
        self.bias_mat = BiasMat2D(self.chrom, self.start - self.params.window,
                                 self.end + self.params.window, 0, self.params.upper)
        bias_track = InsertionBiasTrack(self.chrom, self.start - self.params.window - self.params.upper/2,
                                  self.end + self.params.window + self.params.upper/2 + 1, log = True)
        if self.params.fasta is not None:
            bias_track.computeBias(self.params.fasta, self.params.chrs, self.params.pwm)
            self.bias_mat.makeBiasMat(bias_track)
        self.bias_mat_prenorm = BiasMat2D(self.chrom, self.start - self.params.window,
                                 self.end + self.params.window, 0, self.params.upper)
        self.bias_mat_prenorm.mat = copy(self.bias_mat.mat)
        self.bias_mat.normByInsertDist(self.params.fragmentsizes)
    def getNucSignal(self):
        """Gets Nucleosome Signal Track"""
        self.nuc_cov = CoverageTrack(self.chrom, self.start,
                                     self.end)
        self.nuc_cov.calculateCoverage(self.mat, self.params.lower, self.params.upper,
                                        self.params.window)
        self.bias = BiasTrack(self.chrom, self.start,
                                     self.end)
        self.bias.calculateBackgroundSignal(self.bias_mat, self.params.vmat, self.nuc_cov)
        self.nuc_signal = SignalTrack(self.chrom, self.start,
                                     self.end)
        self.nuc_signal.calculateSignal(self.mat, self.params.vmat)
        self.norm_signal = NormSignalTrack(self.chrom, self.start, self.end)
        self.norm_signal.calculateNormSignal(self.nuc_signal,self.bias)
    def getNFR(self):
        """get number of reads of sub-nucleosomal length"""
        self.nfr_cov = CoverageTrack(self.chrom, self.start, self.end)
        self.nfr_cov.calculateCoverage(self.mat, 0, self.params.lower,
                                                        self.params.window)
    def smoothSignal(self):
        """Smooth thenormalized signal track"""
        window_len = 6 * self.params.smooth_sd + 1
        self.smoothed = Track(self.chrom,self.start,self.end, "Smooth Signal")
        tmp = copy(self.norm_signal.vals)
        self.smoothed.assign_track(tmp)
        self.smoothed.vals[ self.smoothed.vals < 0] = 0
        self.smoothed.smooth_track(window_len, window = "gaussian",
                             sd = self.params.smooth_sd, mode = 'same',
                             norm = True)
    def getOcc(self):
        """gets occupancy track-- either reads in from bw handle given, or makes new"""
        self.occ = Track(self.chrom,self.start,self.end,"Occupancy")
        self.occ.read_track(self.params.occ_track)
        lower_file = self.params.occ_track[:-11] + 'lower_bound.bedgraph.gz'
        self.occ_lower = Track(self.chrom,self.start,self.end,"Occupancy")
        self.occ_lower.read_track(lower_file)
        upper_file = self.params.occ_track[:-11] + 'upper_bound.bedgraph.gz'
        self.occ_upper = Track(self.chrom,self.start,self.end,"Occupancy")
        self.occ_upper.read_track(upper_file)
    def findAllNucs(self):
        """Find peaks in data"""
        self.nuc_collection = {}
        combined = self.norm_signal.vals + self.smoothed.vals
        #find peaks in normalized sigal
        cands1 = call_peaks(combined, min_signal = 0,
                                sep = self.params.redundant_sep,
                                boundary = self.params.nonredundant_sep/2, order = self.params.redundant_sep/2)
        for i in cands1:
            nuc = Nucleosome(i + self.start, self)
            if nuc.nuc_cov > self.params.min_reads:
                nuc.getLR(self)
                if nuc.lr > self.params.min_lr:
                    nuc.getZScore(self)
                    if nuc.z >= self.params.min_z:
                        nuc.getOcc(self)
                        self.nuc_collection[i] = nuc
        self.sorted_nuc_keys = np.array(sorted(self.nuc_collection.keys()))
        self.nonredundant = reduce_peaks( self.sorted_nuc_keys,
                                            map(lambda x: self.nuc_collection[x].z, self.sorted_nuc_keys),
                                                self.params.nonredundant_sep)
        self.redundant = np.setdiff1d(self.sorted_nuc_keys, self.nonredundant)
    def fit(self):
        x = np.linspace(0,self.length() -1, self.length())
        fit = np.zeros(self.length())
        for nuc in self.sorted_nuc_keys:
            self.nuc_collection[nuc].getFuzz(self)
            fit += norm(x,self.nuc_collection[nuc].fuzz**2, self.nuc_collection[nuc].weight, self.nuc_collection[nuc].fit_pos)
        self.fitted = Track(self.chrom, self.start, self.end,
                            "Fitted Nucleosome Signal")
        self.fitted.assign_track(fit)
    def makeInsertionTrack(self):
        """make insertion track for chunk"""
        self.ins = self.mat.getIns()
    def process(self, params):
        """wrapper to carry out all methods needed to call nucleosomes and nfrs"""
        self.initialize(params)
        self.getFragmentMat()
        self.makeBiasMat()
        self.getNucSignal()
        self.getNFR()
        self.smoothSignal()
        if params.occ_track is not None:
            self.getOcc()
        self.findAllNucs()
        self.fit()
        self.makeInsertionTrack()
    def removeData(self):
        """remove data from chunk-- deletes all attributes"""
        names = self.__dict__.keys()
        for name in names:
            delattr(self,name)


import numpy as np

# for interactive drawing
import tkanvas
import pykalman
import scipy.stats

def kf_loglik(C, mean, cov, obs):
    pred_obs_mean = np.dot(C, mean)
    pred_obs_cov = np.dot(C, np.dot(cov, C.T))
    obs_arr = np.array(obs)
    # likelihood of this sample
    return scipy.stats.multivariate_normal.logpdf(
        obs_arr, mean=pred_obs_mean, cov=pred_obs_cov
    )

class KFDisplay(object):
    def __init__(self, A, C, sigma_a, sigma_c, mu_0, sigma_0, path, frame_time=2000, reject_lik=None):
        self.track = True
        self.A = A
        self.C = C
        self.reject_lik = reject_lik
        self.sigma_c = sigma_c

        self.path = iter(path)
        self.kalman_filter = pykalman.KalmanFilter(
            transition_matrices=A,
            observation_matrices=C,
            transition_covariance=sigma_a,
            observation_covariance=sigma_c,
            initial_state_mean=mu_0,
            initial_state_covariance=sigma_0,
        )
        self.obs_path = []
        self.track_path = []
        self.obs = next(self.path)
        self.src = tkanvas.TKanvas(
            draw_fn=self.kalman_draw,
            frame_time=frame_time,
            w=800,
            h=800,
            bgcolor="black",
        )
        self.mean, self.cov = mu_0, sigma_0
        self.new_mean, self.new_cov = self.kalman_filter.filter_update(
            self.mean, self.cov, observation=self.obs
        )
        self.lik = kf_loglik(self.C, self.new_mean, self.cov, self.obs)

        self.kalman_iter = self.draw_kalman_filter()

    # Draw each step of the Kalman filter onto a TKinter canvas
    def draw_kalman_filter(self):

        self.src.clear()
        font = ("Arial", 24)
        for p in self.obs_path:
            self.src.circle(p[0], p[1], 2, fill="white")
        for p in self.track_path:
            self.src.circle(p[0], p[1], 2, fill="blue")
        if self.obs is not None:
            self.obs_path.append(self.obs)
        self.track_path.append(self.new_mean[:2])
        # don't bother drawing circles when at speed

        # draw the prior
        self.src.normal(self.mean[:2], self.cov[:2, :2], outline="#0000ff")
        loglik = self.src.text(
            20, 40, text="%.0f"%self.lik, anchor="w", fill="gray", font=("Arial", 10)
        )
        if self.src.frame_time < 50:
            return
        text = self.src.text(
            20, 20, text="Prior P(X_t)", anchor="w", fill="gray", font=font
        )
        self.src.to_front(text)
        yield 0  # this is a trick to allow to "return" here but resume later
        ax = np.dot(self.A, self.mean)
        acov = np.dot(np.dot(self.A, self.cov), self.A.T)
        # prediction after linear dynamics
        self.src.normal(ax[:2], acov[:2, :2], outline="#00ff00", dash=(2, 4))
        self.src.modify(text, text="Prediction f(x_(t-1)) -> x_t")
        self.src.to_front(text)
        yield 0
        # prediction after linear dynamics
        self.src.normal(ax[:2], acov[:2, :2], outline="#dd00ff", dash=(2, 2))
        self.src.modify(text, text="Expected observation y_t g(x_t) -> y'_t")
        self.src.to_front(text)
        yield 0
        if self.obs is not None:
            # observation (if there is one)
            self.src.circle(self.obs[0], self.obs[1], 5, fill="#ffffff")
            # src.modify(text, text="Observation y_t")
            # uncertainty of observation
            self.src.normal(
                self.obs, self.sigma_c[:2, :2], outline="#6600ff", dash=(2, 2)
            )
            self.src.modify(text, text="Observation w/uncertainty")
            self.src.to_front(text)
            yield 0
            yield 0
        # posterior
        self.src.normal(self.new_mean[:2], self.new_cov[:2, :2], outline="#8899ff")
        self.src.modify(text, text="Posterior P(Xt|Yt)")
        self.src.to_front(text)
        yield 0

    # draw the Kalman filter updates interactively

    def kalman_draw(self, src):

        if self.src.frame_time > 20:
            # slowly speed up over time
            self.src.frame_time = src.frame_time * 0.95
        try:
            next(self.kalman_iter)
        # we've drawn all the steps, so make another update
        except StopIteration:
            self.mean, self.cov = self.new_mean, self.new_cov
            try:
                self.obs = next(self.path)
            except StopIteration:
                src.quit(None)
                return

            self.lik = kf_loglik(self.C, self.mean, self.cov, self.obs)
            if self.reject_lik is None or self.lik>self.reject_lik:
                self.new_mean, self.new_cov = self.kalman_filter.filter_update(
                    self.mean, self.cov, observation=self.obs
                )

            self.kalman_iter = self.draw_kalman_filter()
            return


from IPython.display import Image
from IPython.core.display import HTML
import numpy as np
import sympy as sp
import random as r
import time
import matplotlib.pyplot as plt
import ipyturtle as turtle

from scipy.ndimage.filters import gaussian_filter1d
from scipy.signal import savgol_filter


<filename>src/S_optic.py
## Calculation of optic mode contributions to entropy (S)

import math
import numpy as np
from scipy.integrate import quad

#import params.py for all input parameters
from params import *

##########################################################################

S_o = []

for i in ATEMP:
    x_L = wc_L*CONV/i #define lower bound of optic box integral

    x_U = wc_U*CONV/i #define upper bound of optic box integral

    def optic_1(x1):
        return x1/(math.exp(x1)-1.)

    optic_quad_1, error = quad(optic_1, x_L, x_U)

    optic_S_1 = 3.*AVO*BOLTZ*(1.0-1./(Natoms*Z)-q_c)*optic_quad_1

    # Set up second function

    def optic_2(x2):
        return math.log(1. - math.exp(-x2))

    optic_quad_2, error = quad(optic_2, x_L, x_U)

    optic_S_2 = 3.*AVO*BOLTZ*(1.0-1./(Natoms*Z)-q_c)*optic_quad_2

    S_o.append(optic_S_1 - optic_S_2)


################################################################################
#                                                                              #
# Advection in 2D of a Passive Scalar                                          #
#                                                                              #
################################################################################

from __future__ import print_function, division
import os
import sys; sys.dont_write_bytecode = True
sys.path.insert(0, '../script/')
sys.path.insert(0, '../script/analysis')
from subprocess import call
from shutil import copyfile
import glob
import numpy as np
import scipy as sp
from scipy import optimize
import hdf5_to_dict as io
import util
from bhlight import bcall
import multiprocessing

TMP_DIR = 'TMP'
TMP_BUILD = 'build_tmp.py'
util.safe_remove(TMP_DIR)

PROBLEM = 'advection2d'
AUTO = '-auto' in sys.argv
MPI = '-mpi' in sys.argv
MOVIE = '-movie' in sys.argv
RES = [64,128,256]
if AUTO:
    import pickle
else:
    import matplotlib as mpl; mpl.use('Agg')
    from matplotlib import animation, rc
    from matplotlib import pyplot as plt
    rc('font',size=18)

kwave = 2*np.pi
amp = 1.0
nspace = 2.0
ddiag = np.sqrt(nspace)
cadv = 0.5*ddiag
csqr = cadv**2
gamma = np.sqrt(1./(1. - csqr))
qsqr = gamma**2 - 1.0
u1d = np.sqrt(qsqr/nspace)
c1d = cadv / ddiag

def phi_true(t,x,y):
    phi_x = np.cos(kwave*(x - c1d*t))
    phi_y = np.cos(kwave*(y - c1d*t))
    return amp*phi_x*phi_y

util.make_dir(TMP_DIR)
os.chdir('../prob/' + PROBLEM)
copyfile('build.py', TMP_BUILD)

# Since this test is designed to run on a single machine (no batch scripts)
# set openmpi to only use a few threads. Let MPI handle the rest.
if MPI:
    num_mpi = 4
    num_cpus = multiprocessing.cpu_count()
    os.environ['OMP_NUM_THREADS'] = str(int(np.max([2,num_cpus/num_mpi])))

# COMPILE CODE AT MULTIPLE RESOLUTIONS USING SEPARATE BUILD FILE
for n,res in enumerate(RES):
    for d in [1,2]:
        util.change_cparm('N{}TOT'.format(d), res, TMP_BUILD)
    if MPI:
        for d in [1,2]:
            util.change_cparm('N{}CPU'.format(d), 2, TMP_BUILD)
    call([sys.executable, TMP_BUILD, '-dir', TMP_DIR])
    parm_src = os.path.join(os.getcwd(), TMP_DIR, 'param_template.dat')
    parm_dest = '../../test/' +  TMP_DIR + '/param.dat'
    call(['cp', os.path.join(os.getcwd(), TMP_DIR, 'bhlight'),
          '../../test/' + TMP_DIR + '/bhlight_' + str(res)])
    copyfile(parm_src,parm_dest)
util.safe_remove(TMP_BUILD)
util.safe_remove(TMP_DIR)
os.chdir('../../test/')
os.chdir(TMP_DIR)

# and convergence plot
print("Convergence test...")
errs = [None for res in RES]
for n,res in enumerate(RES):
    print("Res = {}".format(res))
    call_string = ['./bhlight_' + str(res), '-p', 'param.dat']
    if MPI:
        bcall(call_string,int(num_mpi))
    else:
        bcall(call_string)
    dfiles = sorted(glob.glob('dumps/dump*.h5'))
    hdr = io.load_hdr(dfiles[-1])
    geom = io.load_geom(hdr, recalc=True)
    dump = io.load_dump(dfiles[-1],geom)
    N1,N2 = [hdr['N{}'.format(d)] for d in [1,2]]
    mshape = (N1,N2)
    t = dump['t']
    x,y = [geom[d].reshape(mshape) for d in ['x','y']]
    phi = dump['var0'].reshape(mshape)
    error = phi - phi_true(t,x,y)
    max_error = np.max(np.abs(error))
    errs[n] = max_error

print("Richardson extrapolating...")
errf = lambda h, alpha, p: alpha*(h**p)
p0 = 2.0
h0 = 1.0/RES[0]
err0 = errs[0]
alpha0 = err0*h0*h0
hs = 1.0/np.array(RES)
(alpha,p),pcov = optimize.curve_fit(errf,hs,errs,p0=(alpha0,p0))
print("Convergence data:\nalpha = {}, p = {}\npcov = {}\n".format(
    alpha,p,pcov))

if AUTO:
    os.chdir("../")
    data = {}
    data['SOL'] = [np.array([0.0]), np.array([2.0])]
    data['CODE'] = [np.array([0.0]), np.array([p])]
    data['THRESHOLD'] = 0.03
    pickle.dump(data, open('data.p', 'wb'))
    util.safe_remove(TMP_DIR)
    sys.exit()

print("Plotting convergence...")
plt.loglog(RES,errf(hs,alpha,p),lw=2,ls='--',
           label=(r'$%.2f h^{%.2f}$' % (alpha,p)))
plt.loglog(RES,errs,'ro',ms=12,label='measured')
plt.xlabel('Resolution')
plt.ylabel(r'$\left| \phi^h - \phi_{true} \right|_\infty$')
plt.legend()
plt.savefig('../{}.png'.format(PROBLEM),bbox_inches='tight')
plt.clf()

if MOVIE:
    print("Making movie")
    dfiles = sorted(glob.glob('dumps/dump*.h5'))
    hdr = io.load_hdr(dfiles[0])
    geom = io.load_geom(hdr)
    N1,N2 = [hdr['N{}'.format(d)] for d in [1,2]]
    mshape = (N1,N2)
    x,y = [geom[d].reshape(mshape) for d in ['x','y']]
    def get_phi(i):
        dump = io.load_dump(dfiles[i],geom)
        phi = dump['var0'].reshape(mshape)
        return phi
    phi0 = get_phi(0)
    fig, ax = plt.subplots()
    ax.set_xlim((0,1))
    ax.set_ylim((0,1))
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    pc = ax.pcolormesh(x,y,phi0,
                       cmap='viridis',
                       shading='gouraud')
    cbar = fig.colorbar(pc)
    cbar.set_clim(-1.1,1.1)
    cbar.set_label(r'$\phi$')

    def init():
        pc.set_array(phi0.ravel())
        return pc
    def animate(i):
        phi = get_phi(i)
        pc.set_array(phi.ravel())
        return pc

    anim = mpl.animation.FuncAnimation(fig,animate,
                                       init_func=init,
                                       frames=101,
                                       interval=20,blit=False)

    anim.save("../{}.mp4".format(PROBLEM),
              writer='ffmpeg',
              extra_args=['-loglevel','verbose'])

print("Done.")
util.safe_remove(TMP_DIR)


<reponame>asantentata/Stats-project
#!/usr/bin/env python
# Function which takes as inputs a hidden satate x_i and a pixel intensity y_i and then gives the
#probability that the observed intensity of pixel i is y_i and does not consider information from
#neigbouring particles

from scipy import stats
import numpy as np
import matplotlib.pyplot as plt
#import cv as cv2
from PIL import Image

#importing image and turning into greyscale (each pixel an array of values from 0-255)
import Image
image = Image.open("noisy_logo.png")
gray = np.asarray(image.convert('L'))

#defining the outputs of function
def likelihood(y_i,x_i):
	if x_i == 1 and y_i <127:
			probability = 0.15
	if x_i == 1 and y_i >=127:
			probability = 0.85
	if x_i == 0 and y_i <127:
			probability = 0.85
	if x_i == 0 and y_i >=127:
			probability = 0.15
	return probability

#Testing function by making plot#
x_i = 1			#value of hidden state x_i
probability = []		#array of probabilities
for y_i in range(0,255):
	probability.append(likelihood(y_i,x_i))
plt.plot(range(0,255),probability)
plt.show()


<filename>components/outlier-detection/mahalanobis/CoreMahalanobis.py
import logging
import numpy as np
from scipy.linalg import eigh

logger = logging.getLogger(__name__)

class CoreMahalanobis(object):
    """ Outlier detection using the Mahalanobis distance.

    Parameters
    ----------
        threshold (float) : Mahalanobis distance threshold used to classify outliers
        n_components (int) : number of principal components used
        n_stdev (float) : stdev used for feature-wise clipping of observations
        start_clip (int) : number of observations before clipping is applied
        max_n (int) : algorithm behaves as if it has seen at most max_n points

    Functions
    ----------
        predict : detect and return outliers
        transform_input : detect outliers and return input features
        send_feedback : add target labels as part of the feedback loop
        tags : add metadata for input transformer
        metrics : return custom metrics
    """
    def __init__(self,threshold=25,n_components=3,n_stdev=3,start_clip=50,max_n=-1):

        logger.info("Initializing model")
        self.threshold = threshold
        self.n_components = n_components
        self.max_n = max_n
        self.n_stdev = n_stdev
        self.start_clip = start_clip

        self.clip = None
        self.mean = 0
        self.C = 0
        self.n = 0
        self.nb_outliers = 0

    def predict(self, X, feature_names):
        """ Return outlier predictions.

        Parameters
        ----------
        X : array-like
        feature_names : array of feature names (optional)
        """
        logger.info("Using component as a model")
        return self._get_preds(X)

    def transform_input(self, X, feature_names):
        """ Transform the input.
        Used when the outlier detector sits on top of another model.

        Parameters
        ----------
        X : array-like
        feature_names : array of feature names (optional)
        """
        logger.info("Using component as an outlier-detector transformer")
        self.prediction_meta = self._get_preds(X)
        return X

    def _get_preds(self,X):
        """ Detect outliers using the Mahalanobis distance threshold.

        Parameters
        ----------
        X : array-like
        """

        nb = X.shape[0] # batch size
        p = X.shape[1] # number of features
        n_components = min(self.n_components,p)
        if self.max_n>0:
            n = min(self.n,self.max_n) # n can never be above max_n
        else:
            n = self.n

        # Clip X
        if self.n > self.start_clip:
            Xclip = np.clip(X,self.clip[0],self.clip[1])
        else:
            Xclip = X

        # Tracking the mean and covariance matrix
        roll_partial_means = Xclip.cumsum(axis=0)/(np.arange(nb)+1).reshape((nb,1))
        coefs = (np.arange(nb)+1.)/(np.arange(nb)+n+1.)
        new_means = self.mean + coefs.reshape((nb,1))*(roll_partial_means-self.mean)
        new_means_offset = np.empty_like(new_means)
        new_means_offset[0] = self.mean
        new_means_offset[1:] = new_means[:-1]

        coefs = ((n+np.arange(nb))/(n+np.arange(nb)+1.)).reshape((nb,1,1))
        B = coefs*np.matmul((Xclip - new_means_offset)[:,:,None],(Xclip - new_means_offset)[:,None,:])
        cov_batch = (n-1.)/(n+max(1,nb-1.))*self.C + 1./(n+max(1,nb-1.))*B.sum(axis=0)

        # PCA
        eigvals, eigvects = eigh(cov_batch,eigvals=(p-n_components,p-1))

        # Projections
        proj_x = np.matmul(X,eigvects)
        proj_x_clip = np.matmul(Xclip,eigvects)
        proj_means = np.matmul(new_means_offset,eigvects)
        if type(self.C) == int and self.C == 0:
            proj_cov = np.diag(np.zeros(n_components))
        else:
            proj_cov = np.matmul(eigvects.transpose(),np.matmul(self.C,eigvects))

        # Outlier detection in the PC subspace
        coefs = (1./(n+np.arange(nb)+1.)).reshape((nb,1,1))
        B = coefs*np.matmul((proj_x_clip - proj_means)[:,:,None],(proj_x_clip - proj_means)[:,None,:])

        all_C_inv = np.zeros_like(B)
        c_inv = None
        _EPSILON = 1e-8

        for i, b in enumerate(B):
            if c_inv is None:
                if abs(np.linalg.det(proj_cov)) > _EPSILON:
                    c_inv = np.linalg.inv(proj_cov)
                    all_C_inv[i] = c_inv
                    continue
                else:
                    if n + i == 0:
                        continue
                    proj_cov = (n + i -1. )/(n + i)*proj_cov + b
                    continue
            else:
                c_inv = (n + i - 1.)/float(n + i - 2.)*all_C_inv[i-1]
            BC1 = np.matmul(B[i-1],c_inv)
            all_C_inv[i] = c_inv - 1./(1.+np.trace(BC1))*np.matmul(c_inv,BC1)

        # Updates
        self.mean = new_means[-1]
        self.C = cov_batch
        stdev = np.sqrt(np.diag(cov_batch))
        self.n += nb
        if self.n > self.start_clip:
            self.clip = [self.mean-self.n_stdev*stdev,self.mean+self.n_stdev*stdev]

        # Outlier scores and predictions
        x_diff = proj_x-proj_means
        self.score = np.matmul(x_diff[:,None,:],np.matmul(all_C_inv,x_diff[:,:,None])).reshape(nb)
        self.prediction = np.array([1 if s > self.threshold else 0 for s in self.score]).astype(int)

        return self.prediction

    def send_feedback(self,X,feature_names,reward,truth):
        """ Return additional data as part of the feedback loop.

        Parameters
        ----------
            X : array of the features sent in the original predict request
            feature_names : array of feature names. May be None if not available.
            reward (float): the reward
            truth : array with correct value (optional)
        """
        logger.info("Send feedback called")
        return []

    def tags(self):
        """
        Use predictions made within transform to add these as metadata
        to the response. Tags will only be collected if the component is
        used as an input-transformer.
        """
        try:
            return {"outlier-predictions": self.prediction_meta.tolist()}
        except AttributeError:
            logger.info("No metadata about outliers")

    def metrics(self):
        """ Return custom metrics averaged over the prediction batch.
        """
        self.nb_outliers += np.sum(self.prediction)

        is_outlier = {"type":"GAUGE","key":"is_outlier","value":np.mean(self.prediction)}
        outlier_score = {"type":"GAUGE","key":"outlier_score","value":np.mean(self.score)}
        nb_outliers = {"type":"GAUGE","key":"nb_outliers","value":int(self.nb_outliers)}
        fraction_outliers = {"type":"GAUGE","key":"fraction_outliers","value":int(self.nb_outliers)/self.n}
        obs = {"type":"GAUGE","key":"observation","value":self.n}
        threshold = {"type":"GAUGE","key":"threshold","value":self.threshold}

        return [is_outlier,outlier_score,nb_outliers,fraction_outliers,obs,threshold]


<gh_stars>0
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import absolute_import
import math
from scipy.special import gamma
from abc import ABCMeta, abstractmethod
from utils.utils import *

class Distribution(metaclass=ABCMeta):
    @abstractmethod
    def __init__(self):
        pass
class ReparametrizedGaussian(Distribution):
    """
    Diagonal ReparametrizedGaussian distribution with parameters mu (mean) and rho. The standard
    deviation is parametrized as sigma = log(1 + exp(rho))
    A sample from the distribution can be obtained by sampling from a unit Gaussian,
    shifting the samples by the mean and scaling by the standard deviation:
    w = mu + log(1 + exp(rho)) * epsilon
    """
    def __init__(self, mu, rho):
        self.mean = mu
        self.rho = rho
        self.normal = torch.distributions.Normal(0, 1)
        self.point_estimate = self.mean

    @property
    def std_dev(self):
        return torch.log1p(torch.exp(self.rho))

#     def sample(self, n_samples=1):
#         epsilon = torch.distributions.Normal(0, 1).sample(sample_shape=(n_samples, *self.mean.size()))
#         return self.mean + self.std_dev * epsilon

    def sample(self):
        epsilon = torch.distributions.Normal(0, 1).sample(self.mean.size())
        return self.mean + self.std_dev * epsilon

    def logprob(self, target):
        return (-math.log(math.sqrt(2 * math.pi))
                    - torch.log(self.std_dev)
                    - ((target - self.mean) ** 2) / (2 * self.std_dev ** 2)).sum()

    def entropy(self):
        """
        Computes the entropy of the Diagonal Gaussian distribution.
        Details on the computation can be found in the 'diagonal_gaussian_entropy' notes in the repo
        """
        if self.mean.dim() > 1:
            n_inputs, n_outputs = self.mean.shape
        else:
            n_inputs = len(self.mean)
            n_outputs = 1

        part1 = (n_inputs * n_outputs) / 2 * (torch.log(torch.tensor([2 * math.pi])) + 1)
        part2 = torch.sum(torch.log(self.std_dev))

        return part1 + part2

class Gamma(Distribution):
    """ Gamma distribution """
    def __init__(self, shape, rate):
        """
        Class constructor, sets parameters
        Args:
            shape: float, shape parameter of the distribution
            rate: float, rate parameter of the distribution
        Raises:
            TypeError: if given rate or shape are not floats
            ValueError: if given rate or shape are not positive
        """
        if not isinstance(shape, float) or not isinstance(rate, float):
            raise TypeError("Shape and rate should be floats!")

        if shape < 0 or rate < 0:
            raise ValueError("Shape and rate must be positive!")

        self.shape = shape
        self.rate = rate
        self.mean = self.shape / self.rate
        self.variance = self.shape / self.rate**2
        self.point_estimate = self.mean

    def update(self, shape, rate):
        """
        Updates mean and variance automatically when a and b get updated
        Args:
            shape: float, shape parameter of the distribution
            rate: float, rate parameter of the distribution
        Raises:
            TypeError: if given rate or shape are not floats
            ValueError: if given rate or shape are not positive
        """
        if not isinstance(shape, float) or not isinstance(rate, float):
            raise TypeError("Shape and rate should be floats!")

        if shape < 0 or rate < 0:
            raise ValueError("Shape and rate must be positive!")

        self.shape = shape
        self.rate = rate
        self.mean = shape / rate
        self.variance = shape / rate ** 2

class InverseGamma(Distribution):
    """ Inverse Gamma distribution """
    def __init__(self, shape, rate):
        """
        Class constructor, sets parameters of the distribution.
        Args:
            shape: torch tensor of floats, shape parameters of the distribution
            rate: torch tensor of floats, rate parameters of the distribution
        """
        self.shape = shape
        self.rate = rate

    def exp_inverse(self):
        """
        Calculates the expectation E[1/x], where x follows
        the inverse gamma distribution
        """
        return self.shape / self.rate

    def exp_log(self):
        """
        Calculates the expectation E[log(x)], where x follows
        the inverse gamma distribution
        """
        exp_log = torch.log(self.rate) - torch.digamma(self.shape)
        return exp_log

    def entropy(self):
        """
        Calculates the entropy of the inverse gamma distribution
        """
        entropy =  self.shape + torch.log(self.rate) + torch.lgamma(self.shape) \
                     - (1 + self.shape) * torch.digamma(self.shape)
        return torch.sum(entropy)

    def logprob(self, target):
        """
        Computes the value of the predictive log likelihood at the target value
        Args:
            target: Torch tensor of floats, point(s) to evaluate the logprob
        Returns:
            loglike: float, the log likelihood
        """
        part1 = (self.rate**self.shape) / gamma(self.shape)
        part2 = target**(-self.shape - 1)
        part3 = torch.exp(-self.rate / target)

        return torch.log(part1 * part2 * part3)

    def update(self, shape, rate):
        """
        Updates shape and rate of the distribution
        Args:
            shape: float, shape parameter of the distribution
            rate: float, rate parameter of the distribution
        """
        self.shape = shape
        self.rate = rate

class Discrete_Flatten_Laplace(Distribution):
    """
    Flatten Laplace Distribution with mode interval [mu_dowm, mu_up], and precision parameter tau.
    """
    def __init__(self, mu_down, mu_up, tau, D):
        self.mu_up = torch.tensor(mu_up)
        self.mu_down = torch.tensor(mu_down)
        self.tau = tau
        self.domain = torch.tensor(np.linspace(0, D, D + 1)).float()

    @property
    def constant(self):
        return torch.sum(torch.exp(- self.tau * torch.sqrt(self.flatten(self.domain) ** 2)))

    def pmf(self):
        return torch.exp(- self.tau * torch.sqrt(self.flatten(self.domain) ** 2)) / self.constant

    def sample(self):
        return torch.multinomial(self.pmf(), 1, replacement=False)

    def flatten(self, x):
        return torch.max(
            torch.max(torch.max(self.mu_down - x, torch.zeros(1)), torch.max(-self.mu_up + x, torch.zeros(1))),
            torch.zeros(1))


from scipy.stats._discrete_distns import zipf_gen
import requests
import threading
import json
import codecs
import time
import os
import urllib
import errno
import zipfile
from wsd.database import MySQLDatabase
from conf import *

#MEDIAWIKI_API_ENDPOINT = 'https://en.wikipedia.org/w/api.php?action=parse&format=json&prop=text&oldid=' #see:
#MEDIAWIKI_API_ENDPOINT = 'https://en.wikipedia.org/w/index.php?oldid='#alternative for getting the html
MEDIAWIKI_API_ENDPOINT = 'https://en.wikipedia.org/api/rest_v1/page/html/'# see: https://en.wikipedia.org/api/rest_v1/?doc

# Limit the number of threads.
pool = threading.BoundedSemaphore(20)

def worker(u, article, iteration_number):
    headers = {'user-agent': EMAIL}
    # Request passed URL.
    r = requests.get(u, headers=headers, stream=True)
    directory = STATIC_HTML_DUMP_ARTICLES_DIR+str(iteration_number)
    try:
        os.mkdir(directory)
    except OSError, e:
        if e.errno == errno.EEXIST and os.path.isdir(directory):
            # File exists, and it's a directory,
            # another process beat us to creating this dir, that's OK.
            pass
        else:
            # Our target dir exists as a file, or different error,
            # reraise the error!
            raise
    error_directory = STATIC_HTML_DUMP_ERRORS_DIR+str(iteration_number)
    try:
        os.mkdir(error_directory)
    except OSError, e:
        if e.errno == errno.EEXIST and os.path.isdir(error_directory):
            # File exists, and it's a directory,
            # another process beat us to creating this dir, that's OK.
            pass
        else:
            # Our target dir exists as a file, or different error,
            # reraise the error!
            raise
    if not os.path.exists(error_directory):
        os.makedirs(error_directory)
    if r.status_code == 200:
        html_article_filename = STATIC_HTML_DUMP_ARTICLES_DIR+str(iteration_number)+'/article_'+str(article['id'])+'_' +\
                           str(article['rev_id'])+'.html'
        zip_article_filename = STATIC_HTML_DUMP_ARTICLES_DIR+str(iteration_number)+'/article_'+str(article['id'])+'_' +\
                                   str(article['rev_id'])+'.zip'
        handle_response(r, html_article_filename, zip_article_filename)
    else:
        html_article_filename = STATIC_HTML_DUMP_ERRORS_DIR+str(iteration_number)+'/article_'+str(article['id'])+'_' +\
                                   str(article['rev_id'])+'.html'
        zip_article_filename = STATIC_HTML_DUMP_ERRORS_DIR+str(iteration_number)+'/article_'+str(article['id'])+'_' +\
                                   str(article['rev_id'])+'.zip'
        handle_response(r, html_article_filename, zip_article_filename)

    # Release lock for other threads.
    pool.release()
    # Show the number of active threads.
    #print threading.active_count()

def req():
    # Get URLs from a text file, remove white space.
    db = MySQLDatabase(DATABASE_HOST, DATABASE_USER, DATABASE_PASSWORD, DATABASE_NAME)
    db_worker_view = db.get_work_view()
    articles = db_worker_view.retrieve_all_articles()
    #articles = db_worker_view.retrieve_all_articles_questionmark()
    # measure time
    start = time.clock()
    start_time_iteration = start
    iteration_number = 483
    for i, article in enumerate(articles):
        # print some progress
        if i % 10000 == 0:
            #print time for the iteration
            seconds = time.clock() - start_time_iteration
            m, s = divmod(seconds, 60)
            h, m = divmod(m, 60)
            print "Number of crawled articles: %d. Total time for last iteration of 10000 articles: %d:%02d:%02d" % (i, h, m, s)
            start_time_iteration = time.clock()
            iteration_number += 1

        # Thread pool.
        # Blocks other threads (more than the set limit).
        pool.acquire(blocking=True)
        # Create a new thread.
        # Pass each URL (i.e. u parameter) to the worker function.
        t = threading.Thread(target=worker, args=(MEDIAWIKI_API_ENDPOINT+urllib.quote(article['title'])+'/'+str(article['rev_id']), article, iteration_number))

        # Start the newly create thread.
        t.start()
    seconds = time.clock() - start
    m, s = divmod(seconds, 60)
    h, m = divmod(m, 60)
    print "Total time: %d:%02d:%02d" % (h, m, s)

def handle_response(r, html_article_filename, zip_article_filename):
    with open(html_article_filename, 'wb') as outfile:
        for chunk in r.iter_content(1024):
            outfile.write(chunk)
        outfile.flush()
        outfile.close()
    zf = zipfile.ZipFile(zip_article_filename, mode='w', compression=zipfile.ZIP_DEFLATED)
    try:
        zf.write(html_article_filename, os.path.basename(html_article_filename))
        os.remove(html_article_filename)
    finally:
        zf.close()

req()


<reponame>cliu3/pf_geolocation
from __future__ import print_function
import numpy as np
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
import scipy.io
import scipy.stats
from astropy.time import Time
import pandas as pd
from my_project import *
import os.path
#from config import *
import sys

#tagid = 7
# try:
tagid = int(sys.argv[1])
#tagid = 12
# except:

# load tag file
path_to_tags = '/home/cliu3/pf_geolocation/data/tag_files'
tag=scipy.io.loadmat(path_to_tags+'/'+str(tagid)+'_raw.mat',squeeze_me =False,struct_as_record=True)
tag=tag['tag'][0,0]
release_lon = tag['release_lon'][0,0]
release_lat = tag['release_lat'][0,0]
[release_x, release_y] = my_project(release_lon, release_lat, 'forward')
recapture_lon = tag['recapture_lon'][0,0]
recapture_lat = tag['recapture_lat'][0,0]
[recapture_x, recapture_y] = my_project(recapture_lon, recapture_lat, 'forward')

tagname = str(tagid)+'_'+tag['tag_id'][0]

# load result file
result = scipy.io.loadmat('result'+tagname+'.mat',squeeze_me =False,struct_as_record=True)
particles = result['particles']
mpt_idx =  result['mpt_idx']
# determine most probable track
mpt_x = particles[:,mpt_idx,0].flatten()
mpt_y = particles[:,mpt_idx,1].flatten()
(mpt_lon, mpt_lat) = my_project(mpt_x, mpt_y, 'reverse')

day_dnum = np.array(range(int(tag['dnum'][0]), int(tag['dnum'][-1])+1))
date = Time(day_dnum-678942,format='mjd',scale='utc').datetime
MPT = pd.DataFrame({'date':date, 'lon':mpt_lon, 'lat':mpt_lat, 'X':mpt_x, 'Y':mpt_y})
MPT['date'] = pd.to_datetime(MPT['date'])
MPT = MPT[['date', 'X', 'Y', 'lat', 'lon']]
MPT.to_csv('mpt_'+tagname+'.csv')
#-- calculate cumulative probability distribution
# construct daily distrubution using kernel density estimation
xmin = particles[:,:,0].min()
xmax = particles[:,:,0].max()
ymin = particles[:,:,1].min()
ymax = particles[:,:,1].max()
X, Y = np.meshgrid(np.linspace(xmin,xmax,50), np.linspace(ymin,ymax,50))
positions = np.vstack([X.ravel(), Y.ravel()])

ndays = len(particles)
udist = np.zeros_like(X)

# for i in range(ndays):
#     print("Processing kde for Day "+str(i+1)+"/"+str(ndays)+"...")
#     values = particles[i].T
#     kernel = scipy.stats.gaussian_kde(values)
#     Z = np.reshape(kernel(positions).T, X.shape)
#     Z = Z/Z.max()
#     udist += Z
print("Processing kde...")
values = np.vstack([particles[:,:,0].flatten(), particles[:,:,1].flatten()])
kernel = scipy.stats.gaussian_kde(values)
udist = np.reshape(kernel(positions).T, X.shape)
udist = udist/udist.max()

scipy.io.savemat('UD_'+tagname+'.mat',{'X':X, 'Y':Y, 'udist':udist})

# create basemap
print('Generating plot...')
latStart = 41.15
latEnd   = 43.15
lonStart =-71
lonEnd   =-68

map = Basemap(projection='merc', lat_0 = 42, lon_0 = -70,resolution = 'h', area_thresh = 0.1,llcrnrlon=lonStart, llcrnrlat=latStart,
    urcrnrlon=lonEnd, urcrnrlat=latEnd)
map.fillcontinents(color = 'green')

#-- plot mpt
mptlon, mptlat = my_project(mpt_x, mpt_y, 'inverse')
mptx, mpty = map(mptlon, mptlat)
map.plot(mptx,mpty,'b-')
#plot release and recapture location

map.plot(mptx[0],mpty[0],'kx',label="Release")
recap_x, recap_y = map(recapture_lon, recapture_lat)
map.plot(recap_x, recap_y,'k^',markeredgecolor='k',label="Reported Recapture")
map.plot(mptx[-1],mpty[-1],'bv',markeredgecolor='b',label="Simulated Recapture")

#-- plot uncertainty distribution
lon_g, lat_g = my_project(X, Y, 'inverse')
map.pcolormesh(lon_g, lat_g,udist,cmap=plt.cm.cubehelix_r,latlon=True,shading='gouraud')

plt.legend(numpoints=1,prop={'size':16},loc='lower right')
plt.title(tagname+' gpu')

plt.savefig('track'+tagname+'_gpu.pdf', dpi=300, bbox_inches='tight')


<gh_stars>0
import time

from typing import Tuple
import math

from vendor.nfb.pynfb.protocols.ssd.topomap_selector_ica import ICADialog

import numpy as np
import mne
from numpy.linalg import svd
from scipy.optimize import linprog
from sklearn.preprocessing import normalize
from mne.preprocessing import find_outliers
from mne.minimum_norm import apply_inverse_raw  # , make_inverse_operator
from mne.minimum_norm import make_inverse_operator as mne_make_inverse_operator
from mne.beamformer import apply_lcmv_raw
from ..helpers.make_lcmv import make_lcmv

from .node import ProcessorNode
from ..helpers.matrix_functions import (make_time_dimension_second,
                                        put_time_dimension_back_from_second,
                                        last_sample)
from ..helpers.inverse_model import (get_default_forward_file,
                                     get_clean_forward,
                                     make_inverse_operator,
                                     matrix_from_inverse_operator)

from ..helpers.pynfb import (pynfb_ndarray_function_wrapper,
                             ExponentialMatrixSmoother)
from ..helpers.channels import channel_labels_saver
from ..helpers.aux_tools import nostdout
from .. import TIME_AXIS
from vendor.nfb.pynfb.signal_processing import filters

class Preprocessing(ProcessorNode):
    CHANGES_IN_THESE_REQUIRE_RESET = ('collect_for_x_seconds', )
    UPSTREAM_CHANGES_IN_THESE_REQUIRE_REINITIALIZATION = ('mne_info', )
    SAVERS_FOR_UPSTREAM_MUTABLE_OBJECTS = {'mne_info': channel_labels_saver}

    def __init__(self, collect_for_x_seconds: int=60):
        super().__init__()
        self.collect_for_x_seconds = collect_for_x_seconds  # type: int

        self._samples_collected = None  # type: int
        self._samples_to_be_collected = None  # type: int
        self._enough_collected = None  # type: bool
        self._means = None  # type: np.ndarray
        self._mean_sums_of_squares = None  # type: np.ndarray
        self._bad_channel_indices = None  # type: List[int]
        self._interpolation_matrix = None  # type: np.ndarray

        self._reset_statistics()

    def _initialize(self):
        self.mne_info = self.traverse_back_and_find('mne_info')
        frequency = self.mne_info['sfreq']
        self._samples_to_be_collected = int(math.ceil(
            self.collect_for_x_seconds * frequency))

    def _update(self):
        # Have we collected enough samples without the new input?
        enough_collected = self._samples_collected >=\
                self._samples_to_be_collected
        if not enough_collected:
            if self.input_node.output is not None and\
                    self.input_node.output.shape[TIME_AXIS] > 0:
                self._update_statistics()

        elif not self._enough_collected:  # We just got enough samples
            self._enough_collected = True
            standard_deviations = self._calculate_standard_deviations()
            self._bad_channel_indices = find_outliers(standard_deviations)
            if any(self._bad_channel_indices):
                # message = Message(there_has_been_a_change=True,
                #                   output_history_is_no_longer_valid=True)
                # self._deliver_a_message_to_receivers(message)
                # self.mne_info['bads'].append(self._bad_channel_indices)
                # self.mne_info['bads'] = self._bad_channel_indices

                # TODO: handle emergent bad channels on the go
                pass

        self.output = self.input_node.output

    def _reset(self) -> bool:
        self._reset_statistics()
        self._input_history_is_no_longer_valid = True
        return self._input_history_is_no_longer_valid

    def _reset_statistics(self):
        self._samples_collected = 0
        self._enough_collected = False
        self._means = 0
        self._mean_sums_of_squares = 0
        self._bad_channel_indices = []

    def _update_statistics(self):
        input_array = self.input_node.output.astype(np.dtype('float64'))
        # Using float64 is necessary because otherwise rounding error
        # in recursive formula accumulate
        n = self._samples_collected
        m = input_array.shape[TIME_AXIS]  # number of new samples
        self._samples_collected += m

        self._means = (
            self._means * n + np.sum(input_array, axis=TIME_AXIS)) / (n + m)
        self._mean_sums_of_squares = (
            self._mean_sums_of_squares * n +
            np.sum(input_array ** 2, axis=TIME_AXIS)) / (n + m)

    def _calculate_standard_deviations(self):
        n = self._samples_collected
        return np.sqrt(
            n / (n - 1) * (self._mean_sums_of_squares - self._means ** 2))

    def _on_input_history_invalidation(self):
        self._reset_statistics()

    def _check_value(self, key, value):
        pass

class InverseModel(ProcessorNode):
    SUPPORTED_METHODS = ['MNE', 'dSPM', 'sLORETA']
    UPSTREAM_CHANGES_IN_THESE_REQUIRE_REINITIALIZATION = ('mne_info', )
    CHANGES_IN_THESE_REQUIRE_RESET = ('mne_inverse_model_file_path',
                                      'mne_forward_model_file_path',
                                      'snr', 'method')
    SAVERS_FOR_UPSTREAM_MUTABLE_OBJECTS = {'mne_info': channel_labels_saver}

    def __init__(self, forward_model_path=None, snr=1.0, method='MNE'):
        super().__init__()

        self.snr = snr
        self._user_provided_forward_model_file_path = forward_model_path
        self._default_forward_model_file_path = None
        self.mne_info = None
        self.fwd = None

        self._inverse_model_matrix = None
        self.method = method

    def _initialize(self):
        mne_info = self.traverse_back_and_find('mne_info')
        self._bad_channels = mne_info['bads']

        if self._user_provided_forward_model_file_path is None:
            self._default_forward_model_file_path =\
                get_default_forward_file(mne_info)

        self.fwd, missing_ch_names = get_clean_forward(
            self.mne_forward_model_file_path, mne_info)
        mne_info['bads'] = list(set(mne_info['bads'] + missing_ch_names))

        inverse_operator = make_inverse_operator(self.fwd, mne_info)
        self._inverse_model_matrix = matrix_from_inverse_operator(
            inverse_operator=inverse_operator, mne_info=mne_info,
            snr=self.snr, method=self.method)

        frequency = mne_info['sfreq']
        # channel_count = self._inverse_model_matrix.shape[0]
        channel_count = self.fwd['nsource']
        channel_labels = ['vertex #{}'.format(i + 1)
                          for i in range(channel_count)]
        self.mne_info = mne.create_info(channel_labels, frequency)

    def _update(self):
        mne_info = self.traverse_back_and_find('mne_info')
        bads = mne_info['bads']
        if bads != self._bad_channels:
            inverse_operator = make_inverse_operator(self.fwd, mne_info)
            self._inverse_model_matrix = matrix_from_inverse_operator(
                inverse_operator=inverse_operator, mne_info=mne_info,
                snr=self.snr, method=self.method)
            self._bad_channels = bads

        input_array = self.input_node.output
        raw_array = mne.io.RawArray(input_array, mne_info, verbose='ERROR')
        raw_array.pick_types(eeg=True, meg=False, stim=False, exclude='bads')
        data = raw_array.get_data()
        self.output = self._apply_inverse_model_matrix(data)

    def _on_input_history_invalidation(self):
        # The methods implemented in this node do not rely on past inputs
        pass

    def _check_value(self, key, value):
        if key == 'method':
            if value not in self.SUPPORTED_METHODS:
                raise ValueError(
                    'Method {} is not supported.'.format(value) +
                    ' Use one of: {}'.format(self.SUPPORTED_METHODS))

        if key == 'snr':
            if value <= 0:
                raise ValueError(
                    'snr (signal-to-noise ratio) must be a positive number.')

    def _reset(self):
        self._should_reinitialize = True
        self.initialize()
        output_history_is_no_longer_valid = True
        return output_history_is_no_longer_valid

    @property
    def mne_forward_model_file_path(self):
        return self._user_provided_forward_model_file_path or\
                self._default_forward_model_file_path

    @mne_forward_model_file_path.setter
    def mne_forward_model_file_path(self, value):
        # This setter is for public use, hence the "user_provided"
        self._user_provided_forward_model_file_path = value

    def _apply_inverse_model_matrix(self, input_array: np.ndarray):
        W = self._inverse_model_matrix  # VERTICES x CHANNELS
        output_array = W.dot(make_time_dimension_second(input_array))
        return put_time_dimension_back_from_second(output_array)

class LinearFilter(ProcessorNode):
    UPSTREAM_CHANGES_IN_THESE_REQUIRE_REINITIALIZATION = ('mne_info', )
    CHANGES_IN_THESE_REQUIRE_RESET = ('lower_cutoff', 'upper_cutoff')
    SAVERS_FOR_UPSTREAM_MUTABLE_OBJECTS = {'mne_info':
                                           lambda info: (info['nchan'], )}

    def __init__(self, lower_cutoff, upper_cutoff):
        super().__init__()
        self.lower_cutoff = lower_cutoff
        self.upper_cutoff = upper_cutoff
        self._linear_filter = None  # type: filters.ButterFilter

    def _initialize(self):
        mne_info = self.traverse_back_and_find('mne_info')
        frequency = mne_info['sfreq']
        channel_count = mne_info['nchan']
        if not (self.lower_cutoff is None and self.upper_cutoff is None):
            band = (self.lower_cutoff, self.upper_cutoff)

            self._linear_filter = filters.ButterFilter(
                band, fs=frequency, n_channels=channel_count)

            self._linear_filter.apply = pynfb_ndarray_function_wrapper(
                self._linear_filter.apply)
        else:
            self._linear_filter = None

    def _update(self):
        input = self.input_node.output
        if self._linear_filter is not None:
            self.output = self._linear_filter.apply(input)
        else:
            self.output = input

    def _check_value(self, key, value):
        if value is None:
            pass

        elif key == 'lower_cutoff':
            if (hasattr(self, 'upper_cutoff') and
                    self.upper_cutoff is not None and
                    value > self.upper_cutoff):
                raise ValueError(
                    'Lower cutoff can`t be set higher that the upper cutoff')
            if value < 0:
                raise ValueError('Lower cutoff must be a positive number')

        elif key == 'upper_cutoff':
            if (hasattr(self, 'upper_cutoff') and
                    self.lower_cutoff is not None and
                    value < self.lower_cutoff):
                raise ValueError(
                    'Upper cutoff can`t be set lower that the lower cutoff')
            if value < 0:
                raise ValueError('Upper cutoff must be a positive number')

    def _on_input_history_invalidation(self):
        if self._linear_filter is not None:
            self._linear_filter.reset()

    def _reset(self):
        self._should_reinitialize = True
        self.initialize()
        output_history_is_no_longer_valid = True
        return output_history_is_no_longer_valid

class EnvelopeExtractor(ProcessorNode):
    def __init__(self, factor=0.9):
        super().__init__()
        self.method = 'Exponential smoothing'
        self.factor = factor
        self._envelope_extractor = None  # type: ExponentialMatrixSmoother

    def _initialize(self):
        channel_count = self.traverse_back_and_find('mne_info')['nchan']
        self._envelope_extractor = ExponentialMatrixSmoother(
            factor=self.factor, column_count=channel_count)
        self._envelope_extractor.apply = pynfb_ndarray_function_wrapper(
            self._envelope_extractor.apply)

    def _update(self):
        input = self.input_node.output
        self.output = self._envelope_extractor.apply(np.abs(input))

    def _check_value(self, key, value):
        if key == 'factor':
            if value <= 0 or value >= 1:
                raise ValueError('Factor must be a number between 0 and 1')

        if key == 'method':
            if value not in self.SUPPORTED_METHODS:
                raise ValueError(
                    'Method {} is not supported.' +
                    ' Use one of: {}'.format(value, self.SUPPORTED_METHODS))

    def _reset(self):
        self._should_reinitialize = True
        self.initialize()
        output_history_is_no_longer_valid = True
        return output_history_is_no_longer_valid

    def _on_input_history_invalidation(self):
        self._envelope_extractor.reset()

    UPSTREAM_CHANGES_IN_THESE_REQUIRE_REINITIALIZATION = ('mne_info', )
    CHANGES_IN_THESE_REQUIRE_RESET = ('method', 'factor')
    SUPPORTED_METHODS = ('Exponential smoothing', )
    SAVERS_FOR_UPSTREAM_MUTABLE_OBJECTS = {'mne_info':
                                           lambda info: (info['nchan'],)}

class Beamformer(ProcessorNode):

    SUPPORTED_OUTPUT_TYPES = ('power', 'activation')
    UPSTREAM_CHANGES_IN_THESE_REQUIRE_REINITIALIZATION = ('mne_info',)
    CHANGES_IN_THESE_REQUIRE_RESET = ('snr', 'output_type', 'is_adaptive',
                                      'fixed_orientation',
                                      'mne_forward_model_file_path')

    SAVERS_FOR_UPSTREAM_MUTABLE_OBJECTS = {'mne_info': channel_labels_saver}

    def __init__(self, snr: float=1.0, output_type: str='power',
                 is_adaptive: bool=False, fixed_orientation: bool=True,
                 forward_model_path: str=None,
                 forgetting_factor_per_second: float=0.99):
        super().__init__()

        self.snr = snr  # type: float
        self._user_provided_forward_model_file_path = forward_model_path
        self._default_forward_model_file_path = None  # type: str
        self.mne_info = None  # type: mne.Info

        self.output_type = output_type  # type: np.dtype
        self.is_adaptive = is_adaptive  # type: bool
        self._initialized_as_adaptive = None  # type: bool
        self.fixed_orientation = fixed_orientation  # type: bool
        self._initialized_as_fixed = None  # type: bool

        self._channel_indices = None  # type: list
        self._gain_matrix = None  # type: np.ndarray
        self._Rxx = None  # type: np.ndarray
        self.forgetting_factor_per_second = forgetting_factor_per_second
        self._forgetting_factor_per_sample = None  # type: float

    def _initialize(self):
        mne_info = self.traverse_back_and_find('mne_info')

        if self._user_provided_forward_model_file_path is None:
            self._default_forward_model_file_path = get_default_forward_file(
                    mne_info)

        try:
            fwd, missing_ch_names = get_clean_forward(
                self.mne_forward_model_file_path, mne_info)
        except ValueError:
            raise Exception('BAD FORWARD + DATA COMBINATION!')

        mne_info['bads'] = list(set(mne_info['bads'] + missing_ch_names))
        self._gain_matrix = fwd['sol']['data']
        G = self._gain_matrix
        if self.is_adaptive is False:
            Rxx = G.dot(G.T)
        elif self.is_adaptive is True:
            Rxx = np.zeros([G.shape[0], G.shape[0]])  # G.dot(G.T)

        goods = mne.pick_types(mne_info, eeg=True, meg=False, exclude='bads')
        ch_names = [mne_info['ch_names'][i] for i in goods]

        self._Rxx = mne.Covariance(Rxx, ch_names, mne_info['bads'],
                                   mne_info['projs'], nfree=1)

        self._mne_info = mne_info

        frequency = mne_info['sfreq']
        self._forgetting_factor_per_sample = np.power(
                self.forgetting_factor_per_second, 1 / frequency)

        n_vert = fwd['nsource']
        channel_labels = ['vertex #{}'.format(i + 1) for i in range(n_vert)]
        self.mne_info = mne.create_info(channel_labels, frequency)
        self._initialized_as_adaptive = self.is_adaptive
        self._initialized_as_fixed = self.fixed_orientation

        self.fwd_surf = mne.convert_forward_solution(
                    fwd, surf_ori=True, force_fixed=False)
        if not self.is_adaptive:
            self._filters = make_lcmv(
                    info=self._mne_info, forward=self.fwd_surf,
                    data_cov=self._Rxx, reg=0.05, pick_ori='max-power',
                    weight_norm='unit-noise-gain', reduce_rank=False)
        else:
            self._filters = None

    def _update(self):
        t1 = time.time()
        input_array = self.input_node.output
        raw_array = mne.io.RawArray(
            input_array, self._mne_info, verbose='ERROR')

        raw_array.pick_types(eeg=True, meg=False, stim=False, exclude='bads')
        raw_array.set_eeg_reference(ref_channels='average', projection=True)
        t2 = time.time()
        self.logger.debug('Prepare arrays in {:.1f} ms'.format(
                    (t2 - t1) * 1000))

        if self.is_adaptive:
            self._update_covariance_matrix(input_array)
            t1 = time.time()
            self._filters = make_lcmv(info=self._mne_info,
                                      forward=self.fwd_surf,
                                      data_cov=self._Rxx, reg=0.5,
                                      pick_ori='max-power',
                                      weight_norm='unit-noise-gain',
                                      reduce_rank=False)
            t2 = time.time()
            self.logger.debug('Assembled lcmv instance in {:.1f} ms'.format(
                        (t2 - t1) * 1000))

        self._filters['source_nn'] = []
        t1 = time.time()
        stc = apply_lcmv_raw(raw=raw_array, filters=self._filters,
                             max_ori_out='signed')
        t2 = time.time()
        self.logger.debug('Applied lcmv inverse in {:.1f} ms'.format(
                    (t2 - t1) * 1000))

        output = stc.data
        t1 = time.time()
        if self.fixed_orientation is True:
            if self.output_type == 'power':
                output = output ** 2
        else:
            vertex_count = self.fwd_surf['nsource']
            output = np.sum(
                np.power(output, 2).reshape((vertex_count, 3, -1)), axis=1)
            if self.output_type == 'activation':
                output = np.sqrt(output)

        self.output = output
        t2 = time.time()
        self.logger.debug(
                'Finalized in {:.1f} ms'.format(
                    (t2 - t1) * 1000))

    @property
    def mne_forward_model_file_path(self):
        # TODO: fix this
        return (self._user_provided_forward_model_file_path or
                self._default_forward_model_file_path)

    @mne_forward_model_file_path.setter
    def mne_forward_model_file_path(self, value):
        # This setter is for public use, hence the "user_provided"
        self._user_provided_forward_model_file_path = value

    def _reset(self) -> bool:

        # Only change adaptiveness or fixed_orientation requires reinit
        # if (self._initialized_as_adaptive is not self.is_adaptive
        #         or self._initialized_as_fixed is not self.fixed_orientation):
        self._should_reinitialize = True
        self.initialize()

        output_history_is_no_longer_valid = True
        return output_history_is_no_longer_valid

    def _on_input_history_invalidation(self):
        # Only adaptive version relies on history
        if self._initialized_as_adaptive is True:
            self._should_reinitialize = True
            self.initialize()

    def _check_value(self, key, value):
        if key == 'output_type':
            if value not in self.SUPPORTED_OUTPUT_TYPES:
                raise ValueError(
                    'Method {} is not supported.' +
                    ' Use one of: {}'.format(
                        value, self.SUPPORTED_OUTPUT_TYPES))

        if key == 'snr':
            if value <= 0:
                raise ValueError(
                    'snr (signal-to-noise ratio) must be a positive number')

        if key == 'is_adaptive':
            if not isinstance(value, bool):
                raise ValueError(
                    'Beamformer type (adaptive vs nonadaptive) is not set')

    def _update_covariance_matrix(self, input_array):
        t1 = time.time()
        alpha = self._forgetting_factor_per_sample
        sample_count = input_array.shape[TIME_AXIS]
        self.logger.debug('Number of samples: {}'.format(sample_count))
        new_Rxx_data = self._Rxx.data

        raw_array = mne.io.RawArray(
            input_array, self._mne_info, verbose='ERROR')
        raw_array.pick_types(eeg=True, meg=False, stim=False, exclude='bads')
        raw_array.set_eeg_reference(ref_channels='average', projection=True)
        input_array_nobads = raw_array.get_data()

        t2 = time.time()
        self.logger.debug(
            'Prepared covariance update in {:.2f} ms'.format((t2 - t1) * 1000))
        samples = make_time_dimension_second(input_array_nobads).T
        new_Rxx_data = (alpha * new_Rxx_data +
                        (1 - alpha) * samples.T.dot(samples))
        t3 = time.time()
        self.logger.debug(
            'Updated matrix data in {:.2f} ms'.format((t3 - t2) * 1000))

        self._Rxx = mne.Covariance(new_Rxx_data, self._Rxx.ch_names,
                                   raw_array.info['bads'],
                                   raw_array.info['projs'], nfree=1)
        t4 = time.time()
        self.logger.debug('Created instance of covariance' +
                          ' in {:.2f} ms'.format((t4 - t4) * 1000))

# TODO: implement this function
def pynfb_filter_based_processor_class(pynfb_filter_class):
    """
    Returns a ProcessorNode subclass with the functionality of
    pynfb_filter_class

    pynfb_filter_class: subclass of pynfb.signal_processing.filters.BaseFilter

    Sample usage 1:

    LinearFilter = pynfb_filter_based_processor_class(filters.ButterFilter)
    linear_filter = LinearFilter(band, fs, n_channels, order)

    Sample usage 2
    (this would correspond to a different implementation of this function):

    LinearFilter = pynfb_filter_based_processor_class(filters.ButterFilter)
    linear_filter = LinearFilter(band, order)

    In this case LinearFilter should provide
    fs and n_channels parameters to filters.ButterFilter automatically

    """
    class PynfbFilterBasedProcessorClass(ProcessorNode):
        def _on_input_history_invalidation(self):
            pass

        def _check_value(self, key, value):
            pass

        @property
        def CHANGES_IN_THESE_REQUIRE_RESET(self) -> Tuple[str]:
            pass

        @property
        def UPSTREAM_CHANGES_IN_THESE_REQUIRE_REINITIALIZATION(self) -> Tuple[str]:
            pass

        def _reset(self):
            pass

        def __init__(self):
            pass

        def _initialize(self):
            pass

        def _update(self):
            pass
    return PynfbFilterBasedProcessorClass

class MCE(ProcessorNode):
    input = []
    output = []

    UPSTREAM_CHANGES_IN_THESE_REQUIRE_REINITIALIZATION = ()
    CHANGES_IN_THESE_REQUIRE_RESET = ('mne_forward_model_file_path', 'snr')

    def __init__(self, snr=1.0, forward_model_path=None, n_comp=40):
        super().__init__()
        self.snr = snr
        self.mne_forward_model_file_path = forward_model_path
        self.n_comp = n_comp
        self.mne_info = None
        # pass

    def _initialize(self):
        print('INITIALIZING MCE NODE ...')
        mne_info = self.traverse_back_and_find('mne_info')
        # mne_info['custom_ref_applied'] = True
        # -------- truncated svd for fwd_opr operator -------- #
        fwd, missing_ch_names = get_clean_forward(
            self.mne_forward_model_file_path, mne_info)
        mne_info['bads'] = list(set(mne_info['bads'] + missing_ch_names))
        fwd_fix = mne.convert_forward_solution(
                fwd, surf_ori=True, force_fixed=False)

        self._gain_matrix = fwd_fix['sol']['data']

        print('MCE: COMPUTING SVD OF THE FORWARD OPERATOR')
        U, S, V = svd(self._gain_matrix)

        Sn = np.zeros([self.n_comp, V.shape[0]])
        Sn[:self.n_comp, :self.n_comp] = np.diag(S[:self.n_comp])

        self.Un = U[:, :self.n_comp]
        self.A_non_ori = Sn @ V
        # ---------------------------------------------------- #

        # -------- leadfield dims -------- #
        N_SEN = self._gain_matrix.shape[0]
        # -------------------------------- #

        # ------------------------ noise-covariance ------------------------ #
        cov_data = np.identity(N_SEN)
        ch_names = np.array(mne_info['ch_names'])[mne.pick_types(mne_info,
                                                                 eeg=True,
                                                                 meg=False)]
        ch_names = list(ch_names)
        noise_cov = mne.Covariance(
                cov_data, ch_names, mne_info['bads'],
                mne_info['projs'], nfree=1)
        # ------------------------------------------------------------------ #

        self.mne_inv = mne_make_inverse_operator(
                mne_info, fwd_fix, noise_cov, depth=0.8,
                loose=1, fixed=False, verbose='ERROR')
        self.mne_info = mne_info
        self.Sn = Sn
        self.V = V

    def _update(self):
        input_array = self.input_node.output
        last_slice = last_sample(input_array)
        n_src = self.mne_inv['nsource']
        n_times = input_array.shape[1]
        output_mce = np.empty([n_src, n_times])

        raw_slice = mne.io.RawArray(np.expand_dims(last_slice, axis=1),
                                    self.mne_info, verbose='ERROR')
        raw_slice.pick_types(eeg=True, meg=False, stim=False, exclude='bads')
        raw_slice.set_eeg_reference(ref_channels='average', projection=True)

        # ------------------- get dipole orientations --------------------- #
        stc_slice = apply_inverse_raw(raw_slice, self.mne_inv,
                                      pick_ori='vector',
                                      method='MNE', lambda2=1, verbose='ERROR')
        Q = normalize(stc_slice.data[:, :, 0])  # dipole orientations
        # ----------------------------------------------------------------- #

        # -------- setup linprog params -------- #
        n_sen = self.A_non_ori.shape[0]
        A_eq = np.empty([n_sen, n_src])
        for i in range(n_src):
            A_eq[:, i] = self.A_non_ori[:, i * 3: (i + 1) * 3] @ Q[i, :].T
        data_slice = raw_slice.get_data()[:, 0]
        b_eq = self.Un.T @ data_slice
        c = np.ones(A_eq.shape[1])
        # -------------------------------------- #

        with nostdout():
            sol = linprog(c, A_eq=A_eq, b_eq=b_eq,
                          method='interior-point', bounds=(0, None),
                          options={'disp': False})
        output_mce[:, :] = sol.x[:, np.newaxis]

        self.output = output_mce
        self.sol = sol
        return Q, A_eq, data_slice, b_eq, c

    def _on_input_history_invalidation(self):
        # The methods implemented in this node do not rely on past inputs
        pass

    def _reset(self):
        self._should_reinitialize = True
        self.initialize()
        output_history_is_no_longer_valid = True
        return output_history_is_no_longer_valid

    def _check_value(self, key, value):
        if key == 'snr':
            if value <= 0:
                raise ValueError(
                    'snr (signal-to-noise ratio) must be a positive number.')

class ICARejection(ProcessorNode):

    def __init__(self, collect_for_x_seconds: int=60):
        super().__init__()
        self.collect_for_x_seconds = collect_for_x_seconds  # type: int

        self._samples_collected = None  # type: int
        self._samples_to_be_collected = None  # type: int
        self._enough_collected = None  # type: bool

        self._reset_statistics()
        self._ica_rejector = None

    def _on_input_history_invalidation(self):
        self._reset_statistics()

    def _check_value(self, key, value):
        pass

    CHANGES_IN_THESE_REQUIRE_RESET = ('collect_for_x_seconds', )

    def _initialize(self):
        self._mne_info = self.traverse_back_and_find('mne_info')
        self._frequency = self._mne_info['sfreq']
        self._good_ch_inds = mne.pick_types(self._mne_info, eeg=True,
                                            meg=False, stim=False,
                                            exclude='bads')

        channels = self._mne_info['chs']
        self._ch_locs = np.array([ch['loc'] for ch in channels])

        n_ch = len(self._good_ch_inds)
        self._samples_to_be_collected = int(math.ceil(
            self.collect_for_x_seconds * self._frequency))
        self._collected_timeseries = np.zeros(
                [n_ch, self._samples_to_be_collected])
        self._linear_filter = filters.ButterFilter(
                [1, 200], fs=self._frequency,
                n_channels=len(self._good_ch_inds))
        self._linear_filter.apply = pynfb_ndarray_function_wrapper(
                self._linear_filter.apply)

    def _reset(self) -> bool:
        self._reset_statistics()
        self._input_history_is_no_longer_valid = True
        return self._input_history_is_no_longer_valid

    def _reset_statistics(self):
        self._samples_collected = 0
        self._enough_collected = False

    def _update(self):
        # Have we collected enough samples without the new input?
        self.output = self.input_node.output

        enough_collected = self._samples_collected >=\
            self._samples_to_be_collected
        if not enough_collected:
            if self.input_node.output is not None and\
                    self.input_node.output.shape[TIME_AXIS] > 0:
                self._update_statistics()

        elif not self._enough_collected:  # We just got enough samples
            self._enough_collected = True
            print('COLLECTED ENOUGH SAMPLES')
            ica = ICADialog(
                self._collected_timeseries.T,
                list(np.array(self._mne_info['ch_names'])[self._good_ch_inds]),
                self._ch_locs[self._good_ch_inds, :], self._frequency)

            ica.exec_()
            self._ica_rejector = ica.rejection.val.T
        else:
            self.output[self._good_ch_inds, :] = np.dot(
                    self._ica_rejector,
                    self.input_node.output[self._good_ch_inds, :])

    def _update_statistics(self):
        input_array = self.input_node.output.astype(np.dtype('float64'))
        n = self._samples_collected
        m = input_array.shape[TIME_AXIS]  # number of new samples
        self._samples_collected += m
        self._collected_timeseries[:, n:n + m] = self._linear_filter.apply(
                input_array[self._good_ch_inds, :])
        # Using float64 is necessary because otherwise rounding error
        # in recursive formula accumulate
        pass

    UPSTREAM_CHANGES_IN_THESE_REQUIRE_REINITIALIZATION = ('mne_info', )
    SAVERS_FOR_UPSTREAM_MUTABLE_OBJECTS = {'mne_info': channel_labels_saver}


import numpy as np
from scipy import optimize
import matplotlib.pyplot as plt

class Neural_Network(object):
    def __init__(self):
        # Define Hyperparameters
        # self.inputLayerSize = 2
        # self.outputLayerSize = 1
        # self.hiddenLayerSize = 3
        self.inputLayerSize = 784
        self.outputLayerSize = 1
        self.hiddenLayerSize = 100000

        # Weights (parameters)
        self.W1 = np.random.randn(self.inputLayerSize, self.hiddenLayerSize)
        self.W2 = np.random.randn(self.hiddenLayerSize, self.outputLayerSize)

    def forward(self, X):
        # Propogate inputs though network
        self.z2 = np.dot(X, self.W1)
        self.a2 = self.sigmoid(self.z2)
        self.z3 = np.dot(self.a2, self.W2)
        yHat = self.sigmoid(self.z3)
        return yHat

    def sigmoid(self, z):
        # Apply sigmoid activation function to scalar, vector, or matrix
        return 1 / (1 + np.exp(-z))

    def sigmoidPrime(self, z):
        # Gradient of sigmoid
        return np.exp(-z) / ((1 + np.exp(-z)) ** 2)

    def costFunction(self, X, y):
        # Compute cost for given X,y, use weights already stored in class.
        self.yHat = self.forward(X)
        J = 0.5 * sum((y - self.yHat) ** 2)
        return J

    def costFunctionPrime(self, X, y):
        # Compute derivative with respect to W and W2 for a given X and y:
        self.yHat = self.forward(X)

        delta3 = np.multiply(-(y - self.yHat), self.sigmoidPrime(self.z3))
        dJdW2 = np.dot(self.a2.T, delta3)

        delta2 = np.dot(delta3, self.W2.T) * self.sigmoidPrime(self.z2)
        dJdW1 = np.dot(X.T, delta2)

        return dJdW1, dJdW2

    # Helper Functions for interacting with other classes:
    def getParams(self):
        # Get W1 and W2 unrolled into vector:
        params = np.concatenate((self.W1.ravel(), self.W2.ravel()))
        return params

    def setParams(self, params):
        # Set W1 and W2 using single paramater vector.
        W1_start = 0
        W1_end = self.hiddenLayerSize * self.inputLayerSize
        self.W1 = np.reshape(params[W1_start:W1_end], (self.inputLayerSize, self.hiddenLayerSize))
        W2_end = W1_end + self.hiddenLayerSize * self.outputLayerSize
        self.W2 = np.reshape(params[W1_end:W2_end], (self.hiddenLayerSize, self.outputLayerSize))

    def computeGradients(self, X, y):
        dJdW1, dJdW2 = self.costFunctionPrime(X, y)
        return np.concatenate((dJdW1.ravel(), dJdW2.ravel()))

class trainer(object):
    def __init__(self, N):
        # Make Local reference to network:
        self.N = N

    def callbackF(self, params):
        self.N.setParams(params)
        self.J.append(self.N.costFunction(self.X, self.y))

    def costFunctionWrapper(self, params, X, y):
        self.N.setParams(params)
        cost = self.N.costFunction(X, y)
        grad = self.N.computeGradients(X, y)

        return cost, grad

    def train(self, X, y):
        # Make an internal variable for the callback function:
        self.X = X
        self.y = y

        # Make empty list to store costs:
        self.J = []

        params0 = self.N.getParams()

        options = {'maxiter': 200, 'disp': False}
        _res = optimize.minimize(self.costFunctionWrapper, params0, jac=True, method='L-BFGS-B', \
                                 args=(X, y), options=options, callback=self.callbackF)

        self.N.setParams(_res.x)
        self.optimizationResults = _res

import  mnist
if __name__ == '__main__':
    x_train, t_train, x_test, t_test = mnist.load()
    print(x_train.shape)
    print(t_train.shape)
    print(x_test.shape)
    print(t_test.shape)
    # # X = (hours sleeping, hours studying), y = Score on test
    # X = np.array(([3, 5], [5, 1], [10, 2]), dtype=float)
    # y = np.array(([75], [82], [93]), dtype=float)
    # # Normalize
    # X = X / np.amax(X, axis=0)
    # y = y / 100  # Max test score is 100

    train_number=100
    X =x_train[0:train_number,:]
    y=t_train[0:train_number]
    y=y.reshape((len(y),1))

    NN = Neural_Network()

    print('y is ',y[0:10])
    yHat=NN.forward(X)
    print('yHat before train ',yHat[0:10])

    T = trainer(NN)
    T.train(X, y)
    yHat = np.round(NN.forward(X))
    print('yHat after is ',yHat[0:10])

    # # plt.plot(T.J)
    # # plt.grid(1)
    # # plt.xlabel('Iterations')
    # # plt.ylabel('Cost')
    # # plt.show()


"""Miscellaneous stuff that doesn't really fit anywhere else."""

from textwrap import fill, dedent

# if you use
# filldedent('''
#             the text''')
# a space will be put before the first line because dedent will
# put a \n as the first line and fill replaces \n with spaces
# so we strip off any leading and trailing \n since printed wrapped
# text should not have leading or trailing spaces.
filldedent = lambda s: '\n' + fill(dedent(s).strip('\n'))

def default_sort_key(item, order=None):
    """
    A default sort key for lists of SymPy objects to pass to functions like sorted().

    This uses the default ordering. If you want a nonstandard ordering, you will
    have to create your own sort key using the sort_key() method of the object.

    Examples
    ========

    >>> from sympy import Basic, S, I, default_sort_key
    >>> from sympy.abc import x

    >>> sorted([S(1)/2, I, -I], key=default_sort_key)
    [1/2, -I, I]
    >>> a = [S(1)/2, I, -I]
    >>> a.sort(key=default_sort_key)
    >>> a
    [1/2, -I, I]

    >>> b = S("[x, 1/x, 1/x**2, x**2, x**(1/2), x**(1/4), x**(3/2)]")
    >>> b.sort(key=default_sort_key)

    The built-in functions min() and max() also take a key function (in Python
    2.5 or higher), that this can be used for.
    """

    #XXX: The following should also be in the docstring, but orders do not
    # actually work at the moment.

    # To use a nonstandard order, you must create your own sort key.  The default
    # order is lex.

    # >>> from sympy import sympify
    # >>> mykey = lambda item: sympify(item).sort_key(order='rev-lex')
    # >>> sorted([x, x**2, 1], key=default_sort_key)
    # [x**2, x, 1]
    # >>> sorted([x, x**2, 1], key=mykey)
    # [1, x, x**2]

    from sympy.core import S, Basic
    from sympy.core.sympify import sympify, SympifyError
    from sympy.core.compatibility import iterable

    if isinstance(item, Basic):
        return item.sort_key(order=order)

    if iterable(item, exclude=basestring):
        if isinstance(item, dict):
            args = item.items()
        else:
            args = list(item)

        args = [default_sort_key(arg, order=order) for arg in args]

        if isinstance(item, dict):
            args = sorted(args)

        cls_index, args = 10, (len(args), tuple(args))
    else:
        if not isinstance(item, basestring):
            try:
                item = sympify(item)
            except SympifyError:
                pass

        if isinstance(item, Basic):
            return item.sort_key(order=order)

        cls_index, args = 0, (1, (str(item),))

    return (cls_index, 0, item.__class__.__name__), args, S.One.sort_key(), S.One

import sys
size = getattr(sys, "maxint", None)
if size is None: #Python 3 doesn't have maxint
    size = sys.maxsize
if size > 2**32:
    ARCH = "64-bit"
else:
    ARCH = "32-bit"

def debug(*args):
    """
    Print ``*args`` if SYMPY_DEBUG is True, else do nothing.
    """
    from sympy import SYMPY_DEBUG
    if SYMPY_DEBUG:
        for a in args:
            print a,
        print


import numpy as np
import pylab as pl
import matplotlib.pyplot as plt

from matplotlib.ticker import AutoMinorLocator
from matplotlib.ticker import MultipleLocator

from scipy import interpolate

import importlib
import sys
import os

import paths;  importlib.reload(paths)
import pltaux; importlib.reload(pltaux)
import sysaux; importlib.reload(sysaux)

mu = ['1.00', '0.90', '0.80', '0.70', '0.60', '0.50', '0.40', '0.30', '0.20', '0.10', '0.05']

idxs_mu = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

ip = np.zeros(len(mu))

for i in range(len(mu)): ip[i] = np.sqrt(1.0 - float(mu[i])**2.0)

clv_n = np.loadtxt(paths.it0f + 'murmean_r_atl_abd/CLV_RAD')
clv_a = np.loadtxt(paths.out  + 'atl_clv_86.dat')

wvl_n = clv_n[:, 0] * 1e4 / 1e8
wvl_a = clv_a[:, 0] * 1e4 / 1e7; wvl = wvl_a

idx_n = np.where((wvl > min(wvl_n)) & (wvl < max(wvl_n)))

wvl = wvl[idx_n]

#sysaux.clean_dir(paths.figdir)

pltaux.figpar(fontsize = 20)

fig, ax = plt.subplots(nrows = 1, ncols = 1, figsize = (12, 10))

fig.tight_layout()

p = str(ip[0])[0 : 6]

its_a = clv_a[idx_n[0], 1]

its_n = interpolate.interp1d(wvl_n, clv_n[:, 1])(wvl)

ax.plot(wvl, its_n / its_a, color = 'k', label = '$\mu =$ ' + mu[0] + ', $p =$ ' + p + '000')

for idx_mu in idxs_mu:

    if idx_mu != 1:

        p = str(ip[idx_mu - 1])[0 : 6]

        if len(p) == 3: p = p + '000'

        its_a = clv_a[idx_n[0], idx_mu]

        its_n = interpolate.interp1d(wvl_n, clv_n[:, idx_mu])(wvl)

        ax.plot(wvl, its_n / its_a, label = '$\mu =$ ' + mu[idx_mu - 1] + ', $p =$ ' + p)

ax.xaxis.set_major_locator(MultipleLocator(10))
ax.yaxis.set_major_locator(MultipleLocator(0.002))

ax.set_xlabel('Wavelength, [$\mu$m]')
ax.set_ylabel('NESSY / ATLAS')

ax.grid(True)

ax.set_xlim(7, 160)
#ax.set_ylim(1.002, 1.022)
ax.set_ylim(0.998, 1.020)

leg = ax.legend(frameon = True, framealpha = 1, loc = 2, prop={'size': 15})

for handle in leg.legendHandles: handle.set_linewidth(3.0)

pltaux.savepdf('nesatl_rad')


<reponame>ariolwork/uni_conditional_gradient
from scipy.optimize import linprog
import math
# от рукинаписанные нужные части numpy
from my_numpy import np, my_list
eps = 0.00001

# class that contain function, it's derivative and spetial combination for optimization
class Func:
    def __init__(self, func, func_der):
        self.f = func # function J(u)
        self.fder = func_der # function derivate J'(u)

    def J_k(self, u_k, u):
        return sum(self.fder(u_k) * (u - u_k)) #function J_k(u)

# class that contain some type frames for optimisation and minimization method for this type of frames and linear function
class Frames:
    #-----------------------------------------------
    #type 0: frames like a_i <= u_i <= b_i
    def __set_frames0(self, a, b):
        self.a = a
        self.b = b
    #type 1: frame for symplex method
    def __set_frames1(self, A, b):
        self.A = A
        self.b = b

    __setframesfuncs = {
        0: __set_frames0,
        1: __set_frames1
    }
    #-----------------------------------------------
    def __set_size0(self):
        if len(self.a) == len(self.b):
            return len(self.a)
        else:
            return -1
    def __set_size1(self):
        if len(self.A) == len(self.b):
            return len(self.b)
        else:
            return -1

    __setSize = {
        0: __set_size0,
        1: __set_size1
    }
    #------------------------------------------------
    def __init__(self, type_of_conditions, minimize_func):
        self.type = type_of_conditions
        self.minimize = minimize_func
        self.setframes = self.__setframesfuncs.get(type_of_conditions)
        self.size = self.__setSize.get(type_of_conditions)

    def get_size(self):
        return self.size(self)

# class of task contains function, frames and some help functions and parameters
class Job:
    def __init__(self, func, frames, u_0, alpha):
        self.f = func
        self.frames = frames
        self.u_0 = u_0  # start point
        self.u_k = u_0 # the point got last time
        self.__alpha = alpha # rule(function) for alpha calculation
        self.k = 0 # step number

    # сheck task by
    # compare dimension of function, derivative, frames and x
    def check_errors(self):
        a = type(self.f.f(self.u_0))
        b = len(self.f.fder(self.u_0))
        c = self.frames.get_size()
        print("func:",a,"\nframes:",c,"\nder:",b,"\nu_0:", len(self.u_0), "\n")

    # calculate new point using previus
    def get_next_u(self, u1_k):
        self.k+=1
        return self.u_k + (u1_k - self.u_k)*self.__alpha(self, u1_k)

    # find abutting poin
    def find_u1_k(self):
        return self.frames.minimize(self.f, self.frames, self.u_k)

# one variable function minimisation methods
class One_variable_function_minimisation_methods:
    #---------------------------------------------------
    @staticmethod
    def golden_ratio_method(func, a, b, eps=0.000001):
        __MAGIC_CONSTANT_1 = (3 - math.sqrt(5))/2
        __MAGIC_CONSTANT_2 = (math.sqrt(5) - 1)/2
        while True:
            if b-a < eps:
                return (a+b)/2
            u1 = a + __MAGIC_CONSTANT_1*(b-a)
            u2 = a + __MAGIC_CONSTANT_2*(b-a)
            if func(u1)<=func(u2):
                b = u2
            else:
                a = u1
        return -1
    #---------------------------------------------------
    @staticmethod
    def tangent_method(func, a, b, eps=0.000001):
        while True:
            if func.fder(a)>=0:
                return a
            if func.fder(b)<=0:
                return b
            if abs(a-b)<eps:
                return (a+b)/2
            un = (func.f(a)-func.f(b)+b*func.fder(b)-a*func.fder(a))/(func.fder(b)-func.fder(a))
            if func.fder(un)<0:
                a = un
            else:
                b = un

#testng of one variable function minimisation methods
#print(One_variable_function_minimisation_methods.bisection_method((lambda x: x*x*x-x*x), -5, 1))
#print(One_variable_function_minimisation_methods.golden_ratio_method((lambda x: x*x*x-x*x), -5, 1))
#print(One_variable_function_minimisation_methods.tangent_method(Func((lambda x: x*x), (lambda x: 2.0*x)), -1, 2))

# alpha calculate rule 1
def alpha_1(J, u1_k):
    return 1.0/(J.k+1)

# alpha calculate rule 2
def alpha_2(J, u1_k):
    alpha = 1.0
    while True:
        u_k1 = J.u_k + alpha*(u1_k - J.u_k)
        if J.f.f(u_k1) < J.f.f(J.u_k):
            return alpha
        if alpha < eps:
            break
        alpha/=2.0
    return 0.0

# alpha calculate rule 3 (safety)
def alpha_3(J, u1_k):
    def f_k(alpha):
        return J.f.f(J.u_k+alpha*(u1_k-J.u_k))
    def f_k_der(alpha):
        return np.dot((u1_k-J.u_k),J.f.fder(J.u_k+alpha*(u1_k-J.u_k)))
    return One_variable_function_minimisation_methods.tangent_method(Func(f_k, f_k_der), 0, 1)

# minimazation function for spetial frames type (a<x<b)
def frames_minnimize_function(func, frames, u_k):
    ans = []
    der = func.fder(u_k)
    for i in range(0, len(der)):
        if der[i]>0:
            ans.append(frames.a[i])
        elif der[i]<0:
            ans.append(frames.b[i])
        else:
            ans.append((frames.a[i]+frames.b[i])/2)
    return np.array(ans)

# minimisation function(symplex method) for spetioal(linear) type of frames
def symplex_meyhod_minimize_function(func, frames, u_k):
    return np.array(linprog(func.fder(u_k), frames.A, frames.b).x)

# method for different stop rules
def calculate_m(job, eps, steps):
    def method_full(J, eps, steps):
        f_sequ = []
        u_k_sequ = []
        k = 0
        f_sequ.append(J.f.f(J.u_k))
        u_k_sequ.append(J.u_k)
        u_k = 0
        while True:
            u1_k = J.find_u1_k()
            u_k = J.u_k
            J.u_k = J.get_next_u(u1_k)
            f_sequ.append(J.f.f(J.u_k))
            u_k_sequ.append(J.u_k)
            if k>steps or np.all(J.u_k == u_k) or abs(J.f.f(J.u_k) - J.f.f(u_k)) <= eps:
                break
            k+=1
        return J.f.f(J.u_k), J.u_k, f_sequ, u_k_sequ, k, abs(J.f.f(J.u_k) - J.f.f(u_k))
    def method_eps(J, eps):
        f_sequ = []
        u_k_sequ = []
        k = 0
        f_sequ.append(J.f.f(J.u_k))
        u_k_sequ.append(J.u_k)
        u_k = 0
        while True:
            u1_k = J.find_u1_k()
            u_k = J.u_k
            J.u_k = J.get_next_u(u1_k)
            f_sequ.append(J.f.f(J.u_k))
            u_k_sequ.append(J.u_k)
            if k>100000000 or np.all(J.u_k == u_k) or abs(J.f.f(J.u_k) - J.f.f(u_k)) <= eps:
                break
            k+=1
        return J.f.f(J.u_k), J.u_k, f_sequ, u_k_sequ, k, abs(J.f.f(J.u_k) - J.f.f(u_k))
    def method_steps(J, steps):
        f_sequ = []
        u_k_sequ = []
        k = 0
        f_sequ.append(J.f.f(J.u_k))
        u_k_sequ.append(J.u_k)
        u_k = 0
#       print("u_k:{}, f:{}".format(J.u_k, J.f.f(J.u_k)))
        while True:
            u1_k = J.find_u1_k()
            u_k = J.u_k
            J.u_k = J.get_next_u(u1_k)
 #           print("u_k:{}, f:{}, u1_k:{}".format(J.u_k, J.f.f(J.u_k), u1_k))
            f_sequ.append(J.f.f(J.u_k))
            u_k_sequ.append(J.u_k)
            if k>steps or np.all(J.u_k == u_k):
                break
            k+=1
        return J.f.f(J.u_k), J.u_k, f_sequ, u_k_sequ, k+1, abs(J.f.f(J.u_k) - J.f.f(u_k))

    if steps == -1:
        return method_eps(job, eps)
    elif eps == -1:
        return method_steps(job, steps)
    return method_full(job, eps, steps)

#calculate_m(job1, -1, 100)