text:
import numpy as np
import json

class ModelWrapper(object):

    def __init__(self, model=None):
        if model is None:
            self._model = dict()
        else:
            self._model = model

    @property
    def Xtree(self):
        Xtree = self._model["Xtree"]
        while type(Xtree[0]) is not np.ndarray:
            Xtree = Xtree[0]
        Xtree = [Xtree[i].copy() for i in range(len(Xtree))]
        return Xtree

    @property
    def I(self):
        I = self._model["I"]
        while type(I[0]) is not np.ndarray:
            I = I[0]
        I = [I[i].copy() for i in range(len(I))]
        return I

    @property
    def a_grav(self):
        a_grav = self._model['a_grav']
        if not isinstance(a_grav, np.ndarray):
            a_grav = np.asfarray(a_grav)
        a_grav = a_grav.flatten().reshape(6, 1)
        return a_grav

    @property
    def idcomplot(self):
        idcomplot = self._model["idcomplot"]
        if isinstance(idcomplot, np.ndarray):
            idcomplot = idcomplot.flatten().astype(int).tolist()
        return idcomplot

    @property
    def idlinkplot(self):
        idlinkplot = self._model["idlinkplot"]
        if isinstance(idlinkplot, np.ndarray):
            idlinkplot = idlinkplot.flatten().astype(int).tolist()
        return idlinkplot

    @idlinkplot.setter
    def idlinkplot(self, idlinkplot):
        self._model["idlinkplot"] = idlinkplot

    @property
    def linkplot(self):
        linkplot = self._model["linkplot"]
        while type(linkplot[0]) is not np.ndarray:
            linkplot = linkplot[0]
        linkplot = [linkplot[i].copy() for i in range(len(linkplot))]
        return linkplot

    @linkplot.setter
    def linkplot(self, linkplot):
        self._model["linkplot"] = linkplot

    @property
    def idcontact(self):
        idcontact = self._model['idcontact']
        if isinstance(idcontact, np.ndarray):
            idcontact = idcontact.flatten().astype(int).tolist()
        return idcontact

    @idcontact.setter
    def idcontact(self, idcontact):
        self._model["idcontact"] = idcontact

    @property
    def contactpoint(self):
        contactpoint = self._model["contactpoint"]
        while type(contactpoint[0]) is not np.ndarray:
            contactpoint = contactpoint[0]
        contactpoint = [contactpoint[i].copy() for i in range(len(contactpoint))]
        return contactpoint

    @contactpoint.setter
    def contactpoint(self, contactpoint):
        self._model["contactpoint"] = contactpoint

    @property
    def parent(self):
        parent = self._model['parent']
        if isinstance(parent, np.ndarray):
            parent = parent.flatten().astype(int).tolist()
        return parent

    @property
    def NB(self):
        NB = int(self._model["NB"])
        return NB

    @NB.setter
    def NB(self, NB):
        self._model["NB"] = NB

    @property
    def NC(self):
        NC = int(self._model["NC"])
        return NC

    @NC.setter
    def NC(self, NC):
        self._model["NC"] = NC

    @property
    def jtype(self):
        jtype = self._model["jtype"]
        if isinstance(jtype, np.ndarray):
            jtype = jtype.flatten().astype(int).tolist()
        return jtype

    @property
    def jaxis(self):
        jaxis = self._model['jaxis']
        return jaxis

    @property
    def CoM(self):
        CoM = self._model["CoM"]
        while type(CoM[0]) is not np.ndarray:
            CoM = CoM[0]
        CoM = [CoM[i].copy() for i in range(len(CoM))]
        return CoM

    @CoM.setter
    def CoM(self, CoM):
        self._model["CoM"] = CoM

    @property
    def Inertia(self):
        Inertia = self._model["Inertia"]
        while type(Inertia[0]) is not np.ndarray:
            Inertia = Inertia[0]
        Inertia = [Inertia[i].copy() for i in range(len(Inertia))]
        return Inertia

    @Inertia.setter
    def Inertia(self, Inertia):
        self._model["Inertia"] = Inertia

    @property
    def ST(self):
        ST = self._model["ST"]
        while type(ST[0]) is not np.ndarray:
            ST = ST[0]
        return ST

    @ST.setter
    def ST(self, ST):
        self._model["ST"] = ST

    @property
    def Mass(self):
        Mass = self._model['Mass']
        if isinstance(Mass, np.ndarray):
            Mass = Mass.flatten().tolist()
        return Mass

    @Mass.setter
    def Mass(self, Mass):
        self._model["Mass"] = Mass

    @property
    def model(self):
        model = dict()
        model["NB"] = self.NB
        model["NC"] = self.NC
        model["a_grav"] = self.a_grav
        model["jtype"] = self.jtype
        model["jaxis"] = self.jaxis
        model["Xtree"] = self.Xtree
        model["I"] = self.I
        model["parent"] = self.parent
        model["idcomplot"] = self.idcomplot
        model["idlinkplot"] = self.idlinkplot
        model["idcontact"] = self.idcontact
        model["contactpoint"] = self.contactpoint
        model["CoM"] = self.CoM
        model["linkplot"] = self.linkplot
        model["Inertia"] = self.Inertia
        model["Mass"] = self.Mass
        model["ST"] = self.ST
        return model

    @property
    def json(self):
        json_model = dict()
        for key, value in self.model.items():
            if isinstance(value, np.ndarray):
                json_model[key] = value.tolist()
            elif isinstance(value, list):
                json_list = []
                for elem in value:
                    if isinstance(elem, np.ndarray):
                        json_list.append(elem.tolist())
                    else:
                        json_list.append(elem)
                json_model[key] = json_list
            else:
                json_model[key] = value
        return json_model

    def save(self, file_path: str):
        with open(file_path, 'w') as outfile:
            json.dump(self.json, outfile, indent=2)

    def load(self, file_path: str):
        with open(file_path, 'r') as infile:
            json_model = json.load(infile)

        model = dict()
        for key, value in json_model.items():
            model[key] = value
            if key in ["Xtree", "I", "CoM", "linkplot", "contactpoint", "Inertia"]:
                model[key] = [np.asarray(elem) for elem in value]
            elif key in ["a_grav", "Mass", "ST"]:
                model[key] = np.asfarray(value)
            else:
                model[key] = value
        self._model = model


text:
import io
import random
import numpy as np
from PIL import Image

import keras
from keras import backend as K
from utils import DepthNorm, predict, evaluate

import tensorflow as tf

def make_image(tensor):
    height, width, channel = tensor.shape
    image = Image.fromarray(tensor.astype('uint8'))
    output = io.BytesIO()
    image.save(output, format='JPEG', quality=90)
    image_string = output.getvalue()
    output.close()
    return tf.Summary.Image(height=height, width=width, colorspace=channel, encoded_image_string=image_string)

def get_nyu_callbacks(model, basemodel, train_generator, test_generator, test_set, runPath):
    callbacks = []

    # Callback: Tensorboard
    class LRTensorBoard(keras.callbacks.TensorBoard):
        def __init__(self, log_dir):
            super().__init__(log_dir=log_dir)

            self.num_samples = 6
            self.train_idx = np.random.randint(low=0, high=len(train_generator), size=10)
            self.test_idx = np.random.randint(low=0, high=len(test_generator), size=10)

        def on_epoch_end(self, epoch, logs=None):
            if not test_set == None:
                # Samples using current model
                import matplotlib.pyplot as plt
                from skimage.transform import resize
                plasma = plt.get_cmap('plasma')

                minDepth, maxDepth = 10, 1000

                train_samples = []
                test_samples = []

                for i in range(self.num_samples):
                    x_train, y_train = train_generator.__getitem__(self.train_idx[i], False)
                    x_test, y_test = test_generator[self.test_idx[i]]

                    x_train, y_train = x_train[0], np.clip(DepthNorm(y_train[0], maxDepth=1000), minDepth, maxDepth) / maxDepth
                    x_test, y_test = x_test[0], np.clip(DepthNorm(y_test[0], maxDepth=1000), minDepth, maxDepth) / maxDepth

                    h, w = y_train.shape[0], y_train.shape[1]

                    rgb_train = resize(x_train, (h,w), preserve_range=True, mode='reflect', anti_aliasing=True)
                    rgb_test = resize(x_test, (h,w), preserve_range=True, mode='reflect', anti_aliasing=True)

                    gt_train = plasma(y_train[:,:,0])[:,:,:3]
                    gt_test = plasma(y_test[:,:,0])[:,:,:3]

                    predict_train = plasma(predict(model, x_train, minDepth=minDepth, maxDepth=maxDepth)[0,:,:,0])[:,:,:3]
                    predict_test = plasma(predict(model, x_test, minDepth=minDepth, maxDepth=maxDepth)[0,:,:,0])[:,:,:3]

                    train_samples.append(np.vstack([rgb_train, gt_train, predict_train]))
                    test_samples.append(np.vstack([rgb_test, gt_test, predict_test]))

                self.writer.add_summary(tf.Summary(value=[tf.Summary.Value(tag='Train', image=make_image(255 * np.hstack(train_samples)))]), epoch)
                self.writer.add_summary(tf.Summary(value=[tf.Summary.Value(tag='Test', image=make_image(255 * np.hstack(test_samples)))]), epoch)

                # Metrics
                e = evaluate(model, test_set['rgb'], test_set['depth'], test_set['crop'], batch_size=6, verbose=True)
                logs.update({'rel': e[3]})
                logs.update({'rms': e[4]})
                logs.update({'log10': e[5]})

            super().on_epoch_end(epoch, logs)
    callbacks.append( LRTensorBoard(log_dir=runPath) )

    # Callback: Learning Rate Scheduler
    lr_schedule = keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.7, patience=5, min_lr=0.00009, min_delta=1e-2)
    callbacks.append( lr_schedule ) # reduce learning rate when stuck

    # Callback: save checkpoints
    callbacks.append(keras.callbacks.ModelCheckpoint(runPath + '/weights.{epoch:02d}-{val_loss:.2f}.h5', monitor='val_loss',
        verbose=1, save_best_only=False, save_weights_only=True, mode='min', period=1))

    return callbacks

ext: py

max_stars_repo_name: Monsets/Deep-Learning

max_issues_repo_name: Monsets/Deep-Learning

max_forks_repo_name: Monsets/Deep-Learning

reason: import numpy


text:
import numpy as np
from precise.skaters.covarianceutil.conventions import X_TYPE, X_DATA_TYPE, is_data
from precise.skaters.covariance.buffactory import buf_pcov_factory
from precise.skaters.covarianceutil.datafunctions import data_population_covariance
import warnings

def buf_sk_factory(cls, y:X_TYPE=None, s:dict=None,  n_buffer:int=100, n_emp=5, cls_kwargs:dict=None, fit_kwargs:dict=None, e=1):
    """
        :param cls  an sklearn covariance estimating class
        :param n_emp:   If we don't yet have n_emp data points, will revert to empirical
    """

    if cls_kwargs is None:
        cls_kwargs = {}

    if fit_kwargs is None:
        fit_kwargs = {}

    def sk_apply_cov(cls, xs, cls_kwargs:dict, fit_kwargs:dict, n_emp:int):

        if len(xs) < n_emp:
            try:
                _pcov = data_population_covariance(xs)
            except:
                _pcov = np.eye(len(xs))
            try:
                _location = np.nanmean(xs,axis=0)
            except:
                _location = np.zeros(len(xs))
            outputs = {'loc':_location,'pcov':_pcov}
        else:
            obj = cls(**cls_kwargs)
            with warnings.catch_warnings():
                warnings.simplefilter("ignore")
                obj.fit(np.array(xs),**fit_kwargs)
            try:
                outputs = {'loc': obj.location_, 'pcov': obj.covariance_}
            except AttributeError:
                print('obj lacks ._location or ._covariance')
                raise
        return outputs

    func = lambda xs: sk_apply_cov(cls=cls, xs=xs, fit_kwargs=fit_kwargs, n_emp=n_emp, cls_kwargs=cls_kwargs)
    return buf_pcov_factory( func=func, y=y, s=s, n_buffer=n_buffer, e=e)

max_stars_repo_name: MarcoGorelli/precise

max_issues_repo_name: MarcoGorelli/precise

max_forks_repo_name: MarcoGorelli/precise


text:
from mpl_toolkits.basemap import Basemap
import numpy as np
import matplotlib.pyplot as plt
# lon_0, lat_0 are the center point of the projection.
# satellite_height is the altitude of the camera.
# resolution = 'l' means use low resolution coastlines.
h = 3000.
m = Basemap(projection='nsper',lon_0=-105,lat_0=40,
        satellite_height=h*1000.,resolution='l')
m.drawcoastlines()
m.fillcontinents(color='coral',lake_color='aqua')
# draw parallels and meridians.
m.drawparallels(np.arange(-90.,120.,30.))
m.drawmeridians(np.arange(0.,420.,60.))
m.drawmapboundary(fill_color='aqua')
plt.title("Full Disk Near-Sided Perspective Projection %d km above earth" %
        h,fontsize=10)
plt.show()

max_stars_repo_name: DWesl/basemap

max_issues_repo_name: DWesl/basemap

max_forks_repo_name: DWesl/basemap


text:
""" Process all the model finetuning hyperparameter test output files.

Fine-tuning file names look like this: hyperparam_search<model architecture>_<hyperparam>.2014-07-22.00:02:37.242738

The average training error for each epoch and batch is reported:
e.g epoch 1, minibatch 1/2051, training error 487.399902

The validation error over all validation batches is reported at the end of each epoch:
e.g epoch 1, minibatch 2051/2051, validation error 266.505805

For hyperparameters, we care only about the validation error over the epochs.

Each layer transition is marked by the line: Pickling the model..."""

import sys, re, os
import numpy as np
import pandas as pd
from collections import OrderedDict

from ggplot import *

# Extract the model name from each filename.
def extract_model_and_param(regex,filename):
    match = regex.match(filename)
    if match is not None:
        return match.groups()

# Extract the layer and cost from a line
def parse_line(line,data_regex):
    match = data_regex.match(line)
    if match is not None:
        return match.groups()
    else:
        return (None, None, None, None, None)

input_dir = '/data/sda_output_data/test_hyperparam_output'

# read a list of all files in the directory that match model output files
currdir = os.getcwd()
os.chdir(input_dir)
model_files = os.listdir(".")

# compile a regex to extract the model from a given filename
model_and_param = re.compile("hyperparam_search([\d_]+)_([\w]+)\.*")
data_regex = re.compile("epoch ([\d]+)\, minibatch ([\d])+\/([\d]+)\, ([a-z]+) error ([\d.]+)")

# Store the contents of each file as a DataFrame, add it to the hyperparam_dfs list.
hyperparam_dfs = []
print "...Processing files"

# for each file:
for f in model_files:
    validation_model = []
    epoch_list = []
    if not f.startswith("hyperparam_search"):
        continue
    f_model,h_param = extract_model_and_param(model_and_param, f)

    infile = open(f, 'r')
    for line in infile:
        if line.startswith(h_param):
            h_value = float(line.strip().split()[1])
        if not line.startswith("epoch"):
            continue
        (epoch, mb_index, mb_total, phase, err) = parse_line(line,data_regex)
        if epoch is not None and phase == 'validation':
            epoch_list.append(int(epoch))
            validation_model.append(float(err))

    infile.close()

    # build the df, store in list
    model_list = [f_model for i in xrange(len(validation_model))]
    h_param_list = [h_param for i in xrange(len(validation_model))]
    h_value_list = [str(h_value) for i in xrange(len(validation_model))]
    f_dict = {"model": model_list, "param": h_param_list, "value": h_value_list, "score": validation_model, "epoch": epoch_list}
    hyperparam_dfs.append(pd.DataFrame(data=f_dict))

print "...Done"
print "...rbinding DataFrames"
master_df = hyperparam_dfs[0]
for i in xrange(1,len(hyperparam_dfs)):
    master_df = master_df.append(hyperparam_dfs[i])
print "...Done"

three_layer = master_df[master_df.model == '1000_400_20']
three_layer = three_layer[["epoch","score","value","param"]]
four_layer = master_df[master_df.model != '1000_400_20']
four_layer = four_layer[["epoch","score","value","param"]]

three_layer.to_csv(path_or_buf="three_layer_model.csv")
four_layer.to_csv(path_or_buf="four_layer_model.csv")
master_df.to_csv(path_or_buf="both_models.csv")
print ggplot(three_layer, aes(x='epoch', y='score', color='value')) + \
      geom_line() + \
      facet_wrap("param")


text:
import numpy as np
from .. import direct, iterative

import pytest
from numpy.testing import assert_allclose
from scipy.sparse import csr_matrix
from scipy.sparse.linalg import aslinearoperator

OPTYPES = {'array': np.asarray,
           'sparse': csr_matrix,
           'operator': aslinearoperator}

def data(N=15, M=10, K=None, sigma=0.1, complex=False, rseed=53489):
    rand = np.random.RandomState(rseed)
    A = rand.randn(N, M)
    if K is None:
        x = rand.randn(M)
    else:
        x = rand.randn(M, K)
    if complex:
        A = A + 1j * rand.randn(*A.shape)
        x = x + 1j * rand.rand(*x.shape)
    y = np.dot(A, x)
    y += sigma * rand.randn(*y.shape)
    if complex:
        y += 1j * sigma * rand.randn(*y.shape)
    return A, x, y

def conv_data(N=15, M=10, mode='full', sigma=0.1, complex=False, rseed=53489):
    rand = np.random.RandomState(rseed)
    w = rand.rand(N)
    x = rand.randn(M)
    if complex:
        w = w + 1j * rand.randn(N)
        x = x + 1j * rand.rand(M)
    y = np.convolve(w, x, mode=mode)
    y += sigma * rand.randn(*y.shape)
    if complex:
        y += 1j * sigma * rand.randn(*y.shape)
    return w, x, y

@pytest.mark.parametrize('optype', ['array', 'sparse', 'operator'])
@pytest.mark.parametrize('complex', [True, False])
@pytest.mark.parametrize('sigma', [0, 0.001, 0.1])
@pytest.mark.parametrize('K', [None, 2])
@pytest.mark.parametrize('M', [4, 9])
@pytest.mark.parametrize('N', [11])
def test_iterative_unregularized(N, M, K, sigma, complex, optype):
    A, x, y = data(N, M, complex=complex, sigma=sigma)
    A = OPTYPES[optype](A)
    xfit = iterative.least_squares(A, y)
    assert_allclose(x, xfit, atol=max(1E-5, 5 * sigma))

@pytest.mark.parametrize('gamma_L2', [0, 1.0])
@pytest.mark.parametrize('gamma_L1', [0, 1.0])
@pytest.mark.parametrize('complex', [True, False])
@pytest.mark.parametrize('sigma', [0, 0.001])
@pytest.mark.parametrize('M', [4, 9])
@pytest.mark.parametrize('N', [11])
def test_iterative_cost(N, M, sigma, complex, gamma_L1, gamma_L2):
    A, x, y = data(N, M, complex=complex, sigma=sigma)
    xfit = iterative.least_squares(A, y, gamma_L1=gamma_L1, gamma_L2=gamma_L2)
    cost_0 = iterative.least_squares_cost(A, xfit, y, gamma_L1=gamma_L1,
                                          gamma_L2=gamma_L2)

    # Make sure we've actually found a minimum
    # By sampling 10 points near the fit value
    rand = np.random.RandomState(543543)
    x_perturbed = xfit[:, None] + 0.01 * rand.randn(xfit.shape[0], 10)
    cost_perturbed = iterative.least_squares_cost(A, x_perturbed, y[:, None],
                                                  gamma_L1=gamma_L1,
                                                  gamma_L2=gamma_L2)

    assert np.all(cost_0 <= cost_perturbed)

@pytest.mark.parametrize('conv_method', ['fft', 'matrix', 'direct'])
@pytest.mark.parametrize('complex', [True, False])
@pytest.mark.parametrize('mode', ['full', 'valid', 'same'])
@pytest.mark.parametrize('sigma', [0])
@pytest.mark.parametrize('M', [10, 15])
@pytest.mark.parametrize('N', [10, 15])
def test_iterative_deconvolution(N, M, sigma, mode, complex, conv_method):
    w, x, y = conv_data(N, M, mode=mode, complex=complex, sigma=sigma)
    if len(y) < len(x):
        with pytest.warns(UserWarning) as warning:
            xfit = iterative.deconvolution(w, y, Nx=len(x), mode=mode,
                                           conv_method=conv_method)
        assert len(warning) == 1
        assert warning[0].message.args[0].startswith("Ill-posed deconvolution")
    else:
        xfit = iterative.deconvolution(w, y, Nx=len(x), mode=mode,
                                       conv_method=conv_method)
        assert_allclose(x, xfit, atol=1E-3)

max_stars_repo_name: jakevdp/regper

max_issues_repo_name: afcarl/regper

max_forks_repo_name: afcarl/regper

reason: import numpy,from numpy,from scipy


text:
import numpy as np
import cv2
import matplotlib.pyplot as plt
import os

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D,BatchNormalization,MaxPooling2D,Flatten,Dense,Dropout
# tf.config.set_visible_devices([], 'GPU')
# path to your dataset
path = "data/"
image_size = (150,150)

#initializations
data = []
#looping through all the folders
folders = os.listdir(path)
for folder in folders:
    new_path = os.path.join(path,folder)
    total = len(os.listdir(new_path))
    label = folders.index(folder)
    print('folder_name = {} and no of images = {}'.format(folder,total))
    for img in os.listdir(new_path):#loop through all the images in that folder
        #read the images one by one
        try:
            img = cv2.imread( os.path.join(new_path,img),0) #grayscale
            img = cv2.resize(img,image_size) #check here once
            data.append([img,label])
        except Exception as e:
            print('Exception ',e)

#shuffle the data in place
import random
random.shuffle(data)

#seperating images are labels after shuffling
images = []
labels = []
for image,label in data:
    images.append(image)
    labels.append(label)

#normalizing the images
images = np.array(images)/255
labels = np.array(labels)

#converting to 4D
images = np.expand_dims(images,axis = 3)

# seperating train and test dataset
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(images,labels,test_size = 0.1,random_state = 0)

# Custom model
#initializing the model
model=Sequential()

#The first CNN layer followed by Relu and MaxPooling layers
model.add(Conv2D(512,(3,3),activation = 'relu',input_shape=images.shape[1:]))
model.add(MaxPooling2D())

#The second convolution layer followed by Relu and MaxPooling layers
model.add(Conv2D(256,(3,3),activation = 'relu'))
model.add(MaxPooling2D())

#Flattening
model.add(Flatten())

#Adding dropout to avoid overfitting
model.add(Dropout(0.5))

#Dense Layer of 128 neurons
model.add(Dense(128,activation='relu'))

#Output layer
model.add(Dense(1,activation='sigmoid'))

model.compile(optimizer='adam',loss = 'binary_crossentropy',metrics = ['accuracy'])

# BATCH_SIZE = 32
EPOCHS = 10
history=model.fit(X_train,y_train,epochs=EPOCHS, validation_data = (X_test,y_test))

model_name = 'model_updated.h5'
path = '/content/gdrive/My Drive/models/mask-detector/model' + '/' + model_name
#save the model
model.save(path)

max_stars_repo_name: adityachm/mask-detector

max_issues_repo_name: adityachm/mask-detector

max_forks_repo_name: adityachm/mask-detector


text:
import classes as cl
import datetime
import formulas as f
import json
import math
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.dates import (MONTHLY, DateFormatter, rrulewrapper, RRuleLocator, drange)
import numpy as np
import pandas as pd
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()

dissolution_rate = 2.5 #mm/d
fs = open('environmental_data.json','r')
data = json.loads(fs.read())
rainfall = data.get("rainfall")
evaporation = data.get("evaporation")
infiltration_losses = data.get("infiltration_losses")

def IterateFlows(concentrate, d, D, discharge, pond):
    d+=1
    dd = d % 365
    if concentrate[-1].data.get("flow") > 0:
        flow = concentrate[-1].data.get("flow")
        concentrate[-1].data["pc_wt"] = pond[-1].data.get("pc_wt")
        concentrate[-1].data["P"] = pond[-1].data.get("P")
        concentrate[-1].data["T"] = pond[-1].data.get("T")
        concentrate[-1].CalcOsmoticProperties()
        concentrate[-1].CalcMassRate()
        concentrate_water = concentrate[-1].data.get("mass_water")
        concentrate_NaCl = concentrate[-1].data.get("mass_NaCl")
    else:
        concentrate_water = concentrate[-1].data.get("mass_water")
        concentrate_NaCl = concentrate[-1].data.get("mass_NaCl")
    A = pond[-1].data.get("A")
    P = discharge[-1].data.get("P")
    T = discharge[-1].data.get("T")
    m_NaCl = pond[-1].data["mass_NaCl"]
    m_w = pond[-1].data["mass_water"]
    rho = pond[-1].data.get("density")
    rho_w = f.DensityWater(T)
    pc_wt = pond[-1].data.get("pc_wt")
    discharge_water = discharge[-1].data["mass_water"]
    discharge_NaCl = discharge[-1].data["mass_NaCl"]
    rain = rainfall[dd] * A * rho_w #kg
    evap = evaporation[dd] * A * rho_w #kg
    soil_loss_water = A * infiltration_losses[dd] * rho * (1-pc_wt) if pond[-1].data["level"] > 0 else 0
    seepage_NaCl = A * infiltration_losses[dd] * rho * pc_wt if pond[-1].data["level"] > 0 else 0
    d_m_w = discharge_water + rain - evap - soil_loss_water - concentrate_water
    m_w += d_m_w
    if m_w < 0: raise Exception("All water lost")
    d_m_NaCl = discharge_NaCl - soil_loss_water - concentrate_NaCl
    m_NaCl += d_m_NaCl
    if m_NaCl < 0: raise Exception("All NaCl lost")
    m_t = m_w + m_NaCl
    m_NaCl_s = pond[-1].data.get("mass_NaCl_solid")
    pond.append(cl.pond({
        "A": A,
        "P": P,
        "T": T,
        "mass_water": m_w,
        "mass_NaCl": m_NaCl,
        "mass_total": m_t,
        "mass_NaCl_solid": m_NaCl_s,
    }))
    pond[-1].CalcPcWt()
    pond[-1].CalcNaClSolidLevel()
    pond_pc_wt = pond[-1].data.get("pc_wt")
    if pond_pc_wt > 0.265: #saturation level
        pond_m_t = pond[-1].data.get("mass_total")
        pond_m_NaCl = pond[-1].data.get("mass_NaCl")
        NaCl_to_solid = pond_m_t*(pond_pc_wt-0.265)
        pond[-1].data["mass_NaCl_solid"] += NaCl_to_solid
        pond[-1].data["mass_NaCl"] -= NaCl_to_solid
    else:
        m_NaCl_s = pond[-1].data.get("mass_NaCl_solid")
        if m_NaCl_s > 0:
            pond_m_t = pond[-1].data.get("mass_total")
            NaCl_to_aqueous = min(pond[-1].CalcMassOfDepthSolidNaCl(dissolution_rate), pond_m_t*(0.265-pond_pc_wt))
            pond[-1].data["mass_NaCl_solid"] -= NaCl_to_aqueous
            pond[-1].data["mass_NaCl"] += NaCl_to_aqueous
    pond[-1].CalcPcWt()
    pond[-1].CalcOsmoticProperties()
    pond[-1].CalcVolume()
    pond[-1].CalcLevel()
    pond[-1].CalcNaClSolidLevel()
    cr = 1
    post = pond[-1].data["mass_NaCl"]
    while cr > 1e-12:
        pre = post
        pond_pc_wt = pond[-1].data.get("pc_wt")
        if pond_pc_wt > 0.265: #saturation level
            pond_m_t = pond[-1].data.get("mass_total")
            pond_m_NaCl = pond[-1].data.get("mass_NaCl")
            NaCl_to_solid = pond_m_t*(pond_pc_wt-0.265)
            pond[-1].data["mass_NaCl_solid"] += NaCl_to_solid
            pond[-1].data["mass_NaCl"] -= NaCl_to_solid
        else:
            m_NaCl_s = pond[-1].data.get("mass_NaCl_solid")
            if m_NaCl_s > 0:
                pond_m_t = pond[-1].data.get("mass_total")
                NaCl_to_aqueous = min(pond[-1].CalcMassOfDepthSolidNaCl(dissolution_rate), pond_m_t*(0.265-pond_pc_wt))
                pond[-1].data["mass_NaCl_solid"] -= NaCl_to_aqueous
                pond[-1].data["mass_NaCl"] += NaCl_to_aqueous
        post = pond[-1].data["mass_NaCl"]
        pond[-1].CalcPcWt()
        pond[-1].CalcOsmoticProperties()
        pond[-1].CalcVolume()
        pond[-1].CalcLevel()
        pond[-1].CalcNaClSolidLevel()
        cr = abs(pre/post -1)

    return pond

max_stars_repo_name: drizdar/Propmod

max_issues_repo_name: drizdar/Propmod

max_forks_repo_name: drizdar/Propmod


text:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright 1999-2020 Alibaba Group Holding Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import numpy as np

from ... import opcodes as OperandDef
from ..datasource import tensor as astensor
from .core import TensorComplexFFTMixin, validate_fft, TensorStandardFFT

class TensorIFFT(TensorStandardFFT, TensorComplexFFTMixin):
    _op_type_ = OperandDef.IFFT

    def __init__(self, n=None, axis=-1, norm=None, dtype=None, **kw):
        super().__init__(_n=n, _axis=axis, _norm=norm, _dtype=dtype, **kw)

def ifft(a, n=None, axis=-1, norm=None):
    """
    Compute the one-dimensional inverse discrete Fourier Transform.

    This function computes the inverse of the one-dimensional *n*-point
    discrete Fourier transform computed by `fft`.  In other words,
    ``ifft(fft(a)) == a`` to within numerical accuracy.
    For a general description of the algorithm and definitions,
    see `mt.fft`.

    The input should be ordered in the same way as is returned by `fft`,
    i.e.,

    * ``a[0]`` should contain the zero frequency term,
    * ``a[1:n//2]`` should contain the positive-frequency terms,
    * ``a[n//2 + 1:]`` should contain the negative-frequency terms, in
      increasing order starting from the most negative frequency.

    For an even number of input points, ``A[n//2]`` represents the sum of
    the values at the positive and negative Nyquist frequencies, as the two
    are aliased together. See `numpy.fft` for details.

    Parameters
    ----------
    a : array_like
        Input tensor, can be complex.
    n : int, optional
        Length of the transformed axis of the output.
        If `n` is smaller than the length of the input, the input is cropped.
        If it is larger, the input is padded with zeros.  If `n` is not given,
        the length of the input along the axis specified by `axis` is used.
        See notes about padding issues.
    axis : int, optional
        Axis over which to compute the inverse DFT.  If not given, the last
        axis is used.
    norm : {None, "ortho"}, optional
        Normalization mode (see `numpy.fft`). Default is None.

    Returns
    -------
    out : complex Tensor
        The truncated or zero-padded input, transformed along the axis
        indicated by `axis`, or the last one if `axis` is not specified.

    Raises
    ------
    IndexError
        If `axes` is larger than the last axis of `a`.

    See Also
    --------
    mt.fft : An introduction, with definitions and general explanations.
    fft : The one-dimensional (forward) FFT, of which `ifft` is the inverse
    ifft2 : The two-dimensional inverse FFT.
    ifftn : The n-dimensional inverse FFT.

    Notes
    -----
    If the input parameter `n` is larger than the size of the input, the input
    is padded by appending zeros at the end.  Even though this is the common
    approach, it might lead to surprising results.  If a different padding is
    desired, it must be performed before calling `ifft`.

    Examples
    --------
    >>> import mars.tensor as mt

    >>> mt.fft.ifft([0, 4, 0, 0]).execute()
    array([ 1.+0.j,  0.+1.j, -1.+0.j,  0.-1.j])

    Create and plot a band-limited signal with random phases:

    >>> import matplotlib.pyplot as plt
    >>> t = mt.arange(400)
    >>> n = mt.zeros((400,), dtype=complex)
    >>> n[40:60] = mt.exp(1j*mt.random.uniform(0, 2*mt.pi, (20,)))
    >>> s = mt.fft.ifft(n)
    >>> plt.plot(t.execute(), s.real.execute(), 'b-', t.execute(), s.imag.execute(), 'r--')
    ...
    >>> plt.legend(('real', 'imaginary'))
    ...
    >>> plt.show()

    """
    a = astensor(a)
    validate_fft(a, axis, norm)
    op = TensorIFFT(n=n, axis=axis, norm=norm, dtype=np.dtype(np.complex_))
    return op(a)


text:
"""
Encapsulates camera intrinsic parameters for projecting / deprojecitng points
Author: Jeff Mahler
"""
import copy
import logging
import numpy as np
import json
import os

from autolab_core import Point, PointCloud, ImageCoords

from .constants import INTR_EXTENSION
from .image import DepthImage, PointCloudImage

class CameraIntrinsics(object):
    """A set of intrinsic parameters for a camera. This class is used to project
    and deproject points.
    """

    def __init__(self, frame, fx, fy=None, cx=0.0, cy=0.0, skew=0.0, height=None, width=None):
        """Initialize a CameraIntrinsics model.

        Parameters
        ----------
        frame : :obj:`str`
            The frame of reference for the point cloud.
        fx : float
            The x-axis focal length of the camera in pixels.
        fy : float
            The y-axis focal length of the camera in pixels.
        cx : float
            The x-axis optical center of the camera in pixels.
        cy : float
            The y-axis optical center of the camera in pixels.
        skew : float
            The skew of the camera in pixels.
        height : float
            The height of the camera image in pixels.
        width : float
            The width of the camera image in pixels
        """
        self._frame = frame
        self._fx = float(fx)
        self._fy = float(fy)
        self._cx = float(cx)
        self._cy = float(cy)
        self._skew = float(skew)
        self._height = int(height)
        self._width = int(width)

        # set focal, camera center automatically if under specified
        if fy is None:
            self._fy = fx

        # set camera projection matrix
        self._K = np.array([[self._fx, self._skew, self._cx],
                            [       0,   self._fy, self._cy],
                            [       0,          0,        1]])

    @property
    def frame(self):
        """:obj:`str` : The frame of reference for the point cloud.
        """
        return self._frame

    @property
    def fx(self):
        """float : The x-axis focal length of the camera in pixels.
        """
        return self._fx

    @property
    def fy(self):
        """float : The y-axis focal length of the camera in pixels.
        """
        return self._fy

    @property
    def cx(self):
        """float : The x-axis optical center of the camera in pixels.
        """
        return self._cx

    @cx.setter
    def cx(self, z):
        self._cx = z
        self._K = np.array([[self._fx, self._skew, self._cx],
                            [       0,   self._fy, self._cy],
                            [       0,          0,        1]])

    @property
    def cy(self):
        """float : The y-axis optical center of the camera in pixels.
        """
        return self._cy

    @cy.setter
    def cy(self, z):
        self._cy = z
        self._K = np.array([[self._fx, self._skew, self._cx],
                            [       0,   self._fy, self._cy],
                            [       0,          0,        1]])

    @property
    def skew(self):
        """float : The skew of the camera in pixels.
        """
        return self._skew

    @property
    def height(self):
        """float : The height of the camera image in pixels.
        """
        return self._height

    @property
    def width(self):
        """float : The width of the camera image in pixels
        """
        return self._width

    @property
    def proj_matrix(self):
        """:obj:`numpy.ndarray` : The 3x3 projection matrix for this camera.
        """
        return self._K

    @property
    def K(self):
        """:obj:`numpy.ndarray` : The 3x3 projection matrix for this camera.
        """
        return self._K

    @property
    def vec(self):
        """:obj:`numpy.ndarray` : Vector representation for this camera.
        """
        return np.r_[self.fx, self.fy, self.cx, self.cy, self.skew, self.height, self.width]

    @property
    def rosmsg(self):
        """:obj:`sensor_msgs.CamerInfo` : Returns ROS CamerInfo msg
        """
        from sensor_msgs.msg import CameraInfo, RegionOfInterest
        from std_msgs.msg import Header

        msg_header = Header()
        msg_header.frame_id = self._frame

        msg_roi = RegionOfInterest()
        msg_roi.x_offset = 0
        msg_roi.y_offset = 0
        msg_roi.height = 0
        msg_roi.width = 0
        msg_roi.do_rectify = 0

        msg = CameraInfo()
        msg.header = msg_header
        msg.height = self._height
        msg.width = self._width
        msg.distortion_model = 'plumb_bob'
        msg.D = [0.0, 0.0, 0.0, 0.0, 0.0]
        msg.K = [self._fx, 0.0, self._cx, 0.0, self._fy, self._cy, 0.0, 0.0, 1.0]
        msg.R = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0]
        msg.P = [self._fx, 0.0, self._cx, 0.0, 0.0, self._fx, self._cy, 0.0, 0.0, 0.0, 1.0, 0.0]
        msg.binning_x = 0
        msg.binning_y = 0
        msg.roi = msg_roi

        return msg

    @staticmethod
    def from_vec(vec, frame='unassigned'):
        return CameraIntrinsics(frame,
                                fx=vec[0],
                                fy=vec[1],
                                cx=vec[2],
                                cy=vec[3],
                                skew=vec[4],
                                height=vec[5],
                                width=vec[6])

    def crop(self, height, width, crop_ci, crop_cj):
        """ Convert to new camera intrinsics for crop of image from original camera.

        Parameters
        ----------
        height : int
            height of crop window
        width : int
            width of crop window
        crop_ci : int
            row of crop window center
        crop_cj : int
            col of crop window center

        Returns
        -------
        :obj:`CameraIntrinsics`
            camera intrinsics for cropped window
        """
        cx = self.cx + float(width-1)/2 - crop_cj
        cy = self.cy + float(height-1)/2 - crop_ci
        cropped_intrinsics = CameraIntrinsics(frame=self.frame,
                                              fx=self.fx,
                                              fy=self.fy,
                                              skew=self.skew,
                                              cx=cx, cy=cy,
                                              height=height,
                                              width=width)
        return cropped_intrinsics

    def resize(self, scale):
        """ Convert to new camera intrinsics with parameters for resized image.

        Parameters
        ----------
        scale : float
            the amount to rescale the intrinsics

        Returns
        -------
        :obj:`CameraIntrinsics`
            camera intrinsics for resized image
        """
        center_x = float(self.width-1) / 2
        center_y = float(self.height-1) / 2
        orig_cx_diff = self.cx - center_x
        orig_cy_diff = self.cy - center_y
        height = scale * self.height
        width = scale * self.width
        scaled_center_x = float(width-1) / 2
        scaled_center_y = float(height-1) / 2
        fx = scale * self.fx
        fy = scale * self.fy
        skew = scale * self.skew
        cx = scaled_center_x + scale * orig_cx_diff
        cy = scaled_center_y + scale * orig_cy_diff
        scaled_intrinsics = CameraIntrinsics(frame=self.frame,
                                              fx=fx, fy=fy, skew=skew, cx=cx, cy=cy,
                                              height=height, width=width)
        return scaled_intrinsics

    def project(self, point_cloud, round_px=True):
        """Projects a point cloud onto the camera image plane.

        Parameters
        ----------
        point_cloud : :obj:`autolab_core.PointCloud` or :obj:`autolab_core.Point`
            A PointCloud or Point to project onto the camera image plane.

        round_px : bool
            If True, projections are rounded to the nearest pixel.

        Returns
        -------
        :obj:`autolab_core.ImageCoords` or :obj:`autolab_core.Point`
            A corresponding set of image coordinates representing the given
            PointCloud's projections onto the camera image plane. If the input
            was a single Point, returns a 2D Point in the camera plane.

        Raises
        ------
        ValueError
            If the input is not a PointCloud or Point in the same reference
            frame as the camera.
        """
        if not isinstance(point_cloud, PointCloud) and not (isinstance(point_cloud, Point) and point_cloud.dim == 3):
            raise ValueError('Must provide PointCloud or 3D Point object for projection')
        if point_cloud.frame != self._frame:
            raise ValueError('Cannot project points in frame %s into camera with frame %s' %(point_cloud.frame, self._frame))

        points_proj = self._K.dot(point_cloud.data)
        if len(points_proj.shape) == 1:
            points_proj = points_proj[:, np.newaxis]
        point_depths = np.tile(points_proj[2,:], [3, 1])
        points_proj = np.divide(points_proj, point_depths)
        if round_px:
            points_proj = np.round(points_proj)

        if isinstance(point_cloud, Point):
            return Point(data=points_proj[:2,:].astype(np.int16), frame=self._frame)
        return ImageCoords(data=points_proj[:2,:].astype(np.int16), frame=self._frame)

    def project_to_image(self, point_cloud, round_px=True):
        """Projects a point cloud onto the camera image plane and creates
        a depth image. Zero depth means no point projected into the camera
        at that pixel location (i.e. infinite depth).

        Parameters
        ----------
        point_cloud : :obj:`autolab_core.PointCloud` or :obj:`autolab_core.Point`
            A PointCloud or Point to project onto the camera image plane.

        round_px : bool
            If True, projections are rounded to the nearest pixel.

        Returns
        -------
        :obj:`DepthImage`
            A DepthImage generated from projecting the point cloud into the
            camera.

        Raises
        ------
        ValueError
            If the input is not a PointCloud or Point in the same reference
            frame as the camera.
        """
        if not isinstance(point_cloud, PointCloud) and not (isinstance(point_cloud, Point) and point_cloud.dim == 3):
            raise ValueError('Must provide PointCloud or 3D Point object for projection')
        if point_cloud.frame != self._frame:
            raise ValueError('Cannot project points in frame %s into camera with frame %s' %(point_cloud.frame, self._frame))

        points_proj = self._K.dot(point_cloud.data)
        if len(points_proj.shape) == 1:
            points_proj = points_proj[:, np.newaxis]
        point_depths = points_proj[2,:]
        point_z = np.tile(point_depths, [3, 1])
        points_proj = np.divide(points_proj, point_z)
        if round_px:
            points_proj = np.round(points_proj)
        points_proj = points_proj[:2,:].astype(np.int16)

        valid_ind = np.where((points_proj[0,:] >= 0) & \
                             (points_proj[1,:] >= 0) & \
                             (points_proj[0,:] < self.width) & \
                             (points_proj[1,:] < self.height))[0]

        depth_data = np.zeros([self.height, self.width])
        depth_data[points_proj[1,valid_ind], points_proj[0,valid_ind]] = point_depths[valid_ind]
        return DepthImage(depth_data, frame=self.frame)

    def deproject(self, depth_image):
        """Deprojects a DepthImage into a PointCloud.

        Parameters
        ----------
        depth_image : :obj:`DepthImage`
            The 2D depth image to projet into a point cloud.

        Returns
        -------
        :obj:`autolab_core.PointCloud`
            A 3D point cloud created from the depth image.

        Raises
        ------
        ValueError
            If depth_image is not a valid DepthImage in the same reference frame
            as the camera.
        """
        # check valid input
        if not isinstance(depth_image, DepthImage):
            raise ValueError('Must provide DepthImage object for projection')
        if depth_image.frame != self._frame:
            raise ValueError('Cannot deproject points in frame %s from camera with frame %s' %(depth_image.frame, self._frame))

        # create homogeneous pixels
        row_indices = np.arange(depth_image.height)
        col_indices = np.arange(depth_image.width)
        pixel_grid = np.meshgrid(col_indices, row_indices)
        pixels = np.c_[pixel_grid[0].flatten(), pixel_grid[1].flatten()].T
        pixels_homog = np.r_[pixels, np.ones([1, pixels.shape[1]])]
        depth_arr = np.tile(depth_image.data.flatten(), [3,1])

        # deproject
        points_3d = depth_arr * np.linalg.inv(self._K).dot(pixels_homog)
        return PointCloud(data=points_3d, frame=self._frame)

    def deproject_to_image(self, depth_image):
        """Deprojects a DepthImage into a PointCloudImage.

        Parameters
        ----------
        depth_image : :obj:`DepthImage`
            The 2D depth image to projet into a point cloud.

        Returns
        -------
        :obj:`PointCloudImage`
            A point cloud image created from the depth image.

        Raises
        ------
        ValueError
            If depth_image is not a valid DepthImage in the same reference frame
            as the camera.
        """
        point_cloud = self.deproject(depth_image)
        point_cloud_im_data = point_cloud.data.T.reshape(depth_image.height, depth_image.width, 3)
        return PointCloudImage(data=point_cloud_im_data,
                               frame=self._frame)

    def deproject_pixel(self, depth, pixel):
        """Deprojects a single pixel with a given depth into a 3D point.

        Parameters
        ----------
        depth : float
            The depth value at the given pixel location.

        pixel : :obj:`autolab_core.Point`
            A 2D point representing the pixel's location in the camera image.

        Returns
        -------
        :obj:`autolab_core.Point`
            The projected 3D point.

        Raises
        ------
        ValueError
            If pixel is not a valid 2D Point in the same reference frame
            as the camera.
        """
        if not isinstance(pixel, Point) and not pixel.dim == 2:
            raise ValueError('Must provide 2D Point object for pixel projection')
        if pixel.frame != self._frame:
            raise ValueError('Cannot deproject pixel in frame %s from camera with frame %s' %(pixel.frame, self._frame))

        point_3d = depth * np.linalg.inv(self._K).dot(np.r_[pixel.data, 1.0])
        return Point(data=point_3d, frame=self._frame)

    def save(self, filename):
        """Save the CameraIntrinsics object to a .intr file.

        Parameters
        ----------
        filename : :obj:`str`
            The .intr file to save the object to.

        Raises
        ------
        ValueError
            If filename does not have the .intr extension.
        """
        file_root, file_ext = os.path.splitext(filename)
        if file_ext.lower() != INTR_EXTENSION:
            raise ValueError('Extension %s not supported for CameraIntrinsics. Must be stored with extension %s' %(file_ext, INTR_EXTENSION))

        camera_intr_dict = copy.deepcopy(self.__dict__)
        camera_intr_dict['_K'] = 0 # can't save matrix
        f = open(filename, 'w')
        json.dump(camera_intr_dict, f)
        f.close()

    @staticmethod
    def load(filename):
        """Load a CameraIntrinsics object from a file.

        Parameters
        ----------
        filename : :obj:`str`
            The .intr file to load the object from.

        Returns
        -------
        :obj:`CameraIntrinsics`
            The CameraIntrinsics object loaded from the file.

        Raises
        ------
        ValueError
            If filename does not have the .intr extension.
        """
        file_root, file_ext = os.path.splitext(filename)
        if file_ext.lower() != INTR_EXTENSION:
            raise ValueError('Extension %s not supported for CameraIntrinsics. Must be stored with extension %s' %(file_ext, INTR_EXTENSION))

        f = open(filename, 'r')
        ci = json.load(f)
        f.close()
        return CameraIntrinsics(frame=ci['_frame'],
                                fx=ci['_fx'],
                                fy=ci['_fy'],
                                cx=ci['_cx'],
                                cy=ci['_cy'],
                                skew=ci['_skew'],
                                height=ci['_height'],
                                width=ci['_width'])

max_stars_repo_name: esteng/guiding-multi-step

max_issues_repo_name: esteng/guiding-multi-step

max_forks_repo_name: esteng/guiding-multi-step


text:
"""
Sum-product algorithm for tree MRF
Authors: lingxiao@cmu.edu
"""

from inference.core import Inference
import numpy as np
from scipy.special import logsumexp
import random

class TreeBP(Inference):

    def _safe_norm_exp(self, logit):
        logit -= np.max(logit, axis=1, keepdims=True)
        prob = np.exp(logit)
        prob /= prob.sum(axis=1, keepdims=True)
        return prob

    def run_one(self, graph):
        """
         Asynchronous BP using DFS over tree
        """
        # Question: is W symmetric or not ?
        if self.mode == "marginal": # not using log
            sumOp = logsumexp
        else:
            sumOp = np.max

        row, col = np.where(graph.W)
        n_V, n_E = len(graph.b), len(row)
        # create messages, using dict, log scale
        messages = {edge: np.zeros(2) for edge in zip(row,col)}
        # create neighbors   d
        neighbors = {i:[] for i in range(n_V)}
        for i,j in zip(row,col): neighbors[i].append(j)
        # randomly choose a node as root for tree
        root = random.choice(range(n_V))

        xij = np.array([[1,-1],[-1,1]])
        xi = np.array([-1, 1])

        def send_message(i,j): # send message for i to j
            in_message_prod = 0
            for k in neighbors[i]:
                if k != j: in_message_prod += messages[(k,i)]
            # calculate message from i to j
            local_potential = graph.W[i,j]*xij + graph.b[i]*xi
            messages[(i,j)] = sumOp(local_potential + in_message_prod, axis=1)

        def collect(i,j): # collect message for i comming from j
            in_message_prod = 0
            for k in neighbors[j]:
                if k != i: collect(j, k)
            # calculate message from j to i
            send_message(j,i)

        def distribute(i,j): # distribute message from i to j
            # calculate message from i to j
            send_message(i,j)
            # send message from j to all k except i
            for k in neighbors[j]:
                if k != i: distribute(j,k)

        # leaves to root collect (down-to-up)
        for i in neighbors[root]:
            collect(root, i)
        # root to leaves distribute (up-to-down)
        for i in neighbors[root]:
            distribute(root, i)

        # calculate marginal or map
        probs = np.zeros([n_V, 2])
        for i in range(n_V):
            probs[i] = graph.b[i]*xi
            for j in neighbors[i]:
                probs[i] +=  messages[(j,i)]

        # normalize
        if self.mode == 'marginal':
            results = self._safe_norm_exp(probs)

        if self.mode == 'map':
            results = np.argmax(probs, axis=1)
            results[results==0] = -1

        return results

    def run(self, graphs, verbose=False):
        self.verbose = verbose
        res = []
        graph_iterator = tqdm(graphs) if self.verbose else graphs
        for graph in graph_iterator:
            res.append(self.run_one(graph))
        return res

reason: import numpy,from scipy


text:
from estrategias.jogadores import Jogador
import random
import numpy as np

class MeuJogador(Jogador):
    """
    Feito por Lauder Leal
    Caça com metade dos jogadores
    """
    def __init__(self):
        self._name = "Thanos"

    def escolha_de_cacada(self, rodada, comida_atual, reputacao_atual, m, reputacoes_dos_jogadores):
        escolhas = []
        if rodada == 1:
            for i in range(0,len(reputacoes_dos_jogadores)):
                escolhas.append('c')
        elif rodada < 1000:
            for i in range(0,len(reputacoes_dos_jogadores)):
                if i%4 == 0 or i%4 == 3:
                    escolhas.append('d')
                else:
                    escolhas.append('c')
        else:
            for i in range(0,len(reputacoes_dos_jogadores)):
                if reputacoes_dos_jogadores[i] > 0.7:
                    escolhas.append('c')
                else:
                    escolhas.append('d')
        return escolhas


text:
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from typing import Union, Optional, Callable

import numpy as np
from PIL import Image
import matplotlib.cm

from eli5.base import Explanation

def format_as_image(expl, # type: Explanation
    resampling_filter=Image.LANCZOS, # type: int
    colormap=matplotlib.cm.viridis, # type: Callable[[np.ndarray], np.ndarray]
    alpha_limit=0.65, # type: Optional[Union[float, int]]
    ):
    # type: (...) -> Image
    """format_as_image(expl, resampling_filter=Image.LANCZOS, colormap=matplotlib.cm.viridis, alpha_limit=0.65)

    Format a :class:`eli5.base.Explanation` object as an image.

    Note that this formatter requires ``matplotlib`` and ``Pillow`` optional dependencies.

    :param Explanation expl:
        :class:`eli5.base.Explanation` object to be formatted.
        It must have an ``image`` attribute with a Pillow image that will be overlaid.
        It must have a ``targets`` attribute, a list of :class:`eli5.base.TargetExplanation` \
        instances that contain the attribute ``heatmap``, \
        a rank 2 numpy array with float values in the interval [0, 1].
        Currently ``targets`` must be length 1 (only one target is supported).

        :raises TypeError: if ``heatmap`` is not a numpy array.
        :raises ValueError: if ``heatmap`` does not contain values as floats in the interval [0, 1].
        :raises TypeError: if ``image`` is not a Pillow image.

    :param resampling_filter:
        Interpolation ID or Pillow filter to use when resizing the image.

        Example filters from PIL.Image
            * ``NEAREST``
            * ``BOX``
            * ``BILINEAR``
            * ``HAMMING``
            * ``BICUBIC``
            * ``LANCZOS``

        See also `<https://pillow.readthedocs.io/en/stable/handbook/concepts.html#filters>`_.

        *Note that these attributes are integer values*.

        Default is ``PIL.Image.LANCZOS``.
    :type resampling_filter: int, optional

    :param colormap:
        Colormap scheme to be applied when converting the heatmap from grayscale to RGB.
        Either a colormap from matplotlib.cm,
        or a callable that takes a rank 2 array and
        returns the colored heatmap as a [0, 1] RGBA numpy array.

        Example colormaps from matplotlib.cm
            * ``viridis``
            * ``jet``
            * ``binary``

        See also https://matplotlib.org/gallery/color/colormap_reference.html.

        Default is ``matplotlib.cm.viridis`` (green/blue to yellow).
    :type colormap: callable, optional

    :param alpha_limit:
        Maximum alpha (transparency / opacity) value allowed
        for the alpha channel pixels in the RGBA heatmap image.

        Between 0.0 and 1.0.

        Useful when laying the heatmap over the original image,
        so that the image can be seen over the heatmap.

        Default is 0.65.

        :raises ValueError: if ``alpha_limit`` is outside the [0, 1] interval.
        :raises TypeError: if ``alpha_limit`` is not float, int, or None.
    :type alpha_limit: float or int, optional

    Returns
    -------
    overlay : PIL.Image.Image
        PIL image instance of the heatmap blended over the image.
    """
    image = expl.image
    # validate image
    if not isinstance(image, Image.Image):
        raise TypeError('Explanation image must be a PIL.Image.Image instance. '
                        'Got: {}'.format(image))
    if image.mode != 'RGBA':
        # normalize to 'RGBA'
        image = image.convert('RGBA')

    if not expl.targets:
        # no heatmaps
        return image
    else:
        assert len(expl.targets) == 1
        heatmap = expl.targets[0].heatmap
        _validate_heatmap(heatmap)

    # The order of our operations is: 1. colorize 2. resize
    # as opposed: 1. resize 2. colorize

    # save the original heatmap values
    heatvals = heatmap
    # apply colours to the grayscale array
    heatmap = _colorize(heatmap, colormap=colormap)  # -> rank 3 RGBA array

    # make the alpha intensity correspond to the grayscale heatmap values
    # cap the intensity so that it's not too opaque when near maximum value
    _update_alpha(heatmap, starting_array=heatvals, alpha_limit=alpha_limit)

    heatmap = expand_heatmap(heatmap, image, resampling_filter=resampling_filter)
    overlay = _overlay_heatmap(heatmap, image)
    return overlay

def heatmap_to_image(heatmap):
    # type: (np.ndarray) -> Image
    """
    Convert the numpy array ``heatmap`` to a Pillow image.

    Parameters
    ----------
    heatmap : numpy.ndarray
        Rank 2 grayscale ('L') array or rank 3 coloured ('RGB' or RGBA') array,
        with values in interval [0, 1] as floats.

    :raises TypeError: if ``heatmap`` is not a numpy array.
    :raises ValueError: if ``heatmap`` does not contain values as floats in the interval [0, 1].
    :raises ValueError: if ``heatmap`` rank is neither 2 nor 3.
    :raises ValueError: if rank 3 ``heatmap`` does not have 4 (RGBA) or 3 (RGB) channels.

    Returns
    -------
    heatmap_image : PIL.Image.Image
        Heatmap as an image with a suitable mode.
    """
    _validate_heatmap(heatmap)
    rank = len(heatmap.shape)
    if rank == 2:
        mode = 'L'
    elif rank == 3:
        channels = heatmap.shape[2]
        if channels == 4:
            mode = 'RGBA'
        elif channels == 3:
            mode = 'RGB'
        else:
            raise ValueError('Rank 3 heatmap must have 4 channels (RGBA), '
                             'or 3 channels (RGB). '
                             'Got shape with {} channels'.format(channels))
    else:
        raise ValueError('heatmap must have rank 2 (L, grayscale) '
                         'or rank 3 (RGBA, colored). '
                         'Got: %d' % rank)
    heatmap = (heatmap*255).astype('uint8') # -> [0, 255] int
    return Image.fromarray(heatmap, mode=mode)

def _validate_heatmap(heatmap):
    """Check that ``heatmap`` is a numpy array
    with float values between 0 and 1."""
    if not isinstance(heatmap, np.ndarray):
        raise TypeError('heatmap must be a numpy.ndarray instance. '
                        'Got: {}'.format(heatmap))
    mi = np.min(heatmap)
    ma = np.max(heatmap)
    if not (0 <= mi and ma <= 1):
        raise ValueError('heatmap must contain float values '
                         'between 0 and 1 inclusive. '
                         'Got array with minimum: {} '
                         'and maximum: {}'.format(mi, ma))

def _colorize(heatmap, colormap):
    # type: (np.ndarray, Callable[[np.ndarray], np.ndarray]) -> np.ndarray
    """
    Apply the ``colormap`` function to a grayscale
    rank 2 ``heatmap`` array (with float values in interval [0, 1]).
    Returns an RGBA rank 3 array with float values in range [0, 1].
    """
    heatmap = colormap(heatmap) # -> [0, 1] RGBA ndarray
    return heatmap

def _update_alpha(image_array, starting_array=None, alpha_limit=None):
    # type: (np.ndarray, Optional[np.ndarray], Optional[Union[float, int]]) -> None
    """
    Update the alpha channel values of an RGBA rank 3 ndarray ``image_array``,
    optionally creating the alpha channel from rank 2 ``starting_array``,
    and setting upper limit for alpha values (opacity) to ``alpha_limit``.

    This function modifies ``image_array`` in-place.
    """
    # FIXME: this function may be too specialized and could be refactored
    # get the alpha channel slice
    if isinstance(starting_array, np.ndarray):
        alpha = starting_array
    else:
        # take the alpha channel as is
        alpha = image_array[:,:,3]
    # set maximum alpha value
    alpha = _cap_alpha(alpha, alpha_limit)
    # update alpha channel in the original image
    image_array[:,:,3] = alpha

def _cap_alpha(alpha_arr, alpha_limit):
    # type: (np.ndarray, Union[None, float, int]) -> np.ndarray
    """
    Limit the alpha values in ``alpha_arr``
    by setting the maximum alpha value to ``alpha_limit``.
    Returns a a new array with the values capped.
    """
    if alpha_limit is None:
        return alpha_arr
    elif isinstance(alpha_limit, (float, int)):
        if 0 <= alpha_limit <= 1:
            new_alpha = np.minimum(alpha_arr, alpha_limit)
            return new_alpha
        else:
            raise ValueError('alpha_limit must be'
                             'between 0 and 1 inclusive, got: %f' % alpha_limit)
    else:
        raise TypeError('alpha_limit must be int or float,'
                        'got: {}'.format(alpha_limit))

def expand_heatmap(heatmap, image, resampling_filter=Image.LANCZOS):
    # type: (np.ndarray, Image, Union[None, int]) -> Image
    """
    Resize the ``heatmap`` image array to fit over the original ``image``,
    using the specified ``resampling_filter`` method.
    The heatmap is converted to an image in the process.

    Parameters
    ----------
    heatmap : numpy.ndarray
        Heatmap that is to be resized, as an array.

    image : PIL.Image.Image
        The image whose dimensions will be resized to.

    resampling_filter : int or None
        Interpolation to use when resizing.

        See :func:`eli5.format_as_image` for more details on the `resampling_filter` parameter.

    :raises TypeError: if ``image`` is not a Pillow image instance.

    Returns
    -------
    resized_heatmap : PIL.Image.Image
        The heatmap, resized, as a PIL image.
    """
    if not isinstance(image, Image.Image):
        raise TypeError('image must be a PIL.Image.Image instance. '
                        'Got: {}'.format(image))
    heatmap = heatmap_to_image(heatmap)
    spatial_dimensions = (image.width, image.height)
    heatmap = heatmap.resize(spatial_dimensions, resample=resampling_filter)
    return heatmap

def _overlay_heatmap(heatmap, image):
    # type: (Image, Image) -> Image
    """
    Blend (combine) ``heatmap`` over ``image``,
    using alpha channel values appropriately (must have mode `RGBA`).
    Output is 'RGBA'.
    """
    # note that the order of alpha_composite arguments matters
    overlayed_image = Image.alpha_composite(image, heatmap)
    return overlayed_image


text:
import datetime
import re
from functools import lru_cache, wraps
from gettext import gettext as _
from math import log10

import numpy as np

__all__ = ["fmt", "pc", "pm", "p10k", "indent", "rpartition", "interpolant", "lru_safe_cache"]

N_RE = re.compile(r"(-?)(\d+)(\.\d{,2})?\d*")
identity = lambda x: x
HUMANIZED_SUFFIXES = (
    (0.1, 1, identity, "{:.04n}", ""),
    (1e2, 1, identity, "{:.03n}", ""),
    (1e3, 1, identity, "{:.2n}", ""),
    (1e6, 1, int, "{:n}", ""),
    (1e8, 1e6, identity, "{:.3n}", _("M")),
    (1e9, 1e6, identity, "{:.2n}", _("M")),
    (1e11, 1e9, identity, "{:.3n}", _("B")),
    (1e12, 1e9, identity, "{:.2n}", _("B")),
    (1e13, 1e12, identity, "{:.3n}", _("T")),
    (1e14, 1e12, identity, "{:.2n}", _("T")),
)

def fmt(n):
    """
    Heuristically choose best format option for number.
    """

    if n == float("inf"):
        return _("infinity")
    try:
        return ", ".join(map(fmt, n))
    except TypeError:
        pass
    m = abs(n)

    if int(n) == n and m < 1e6:
        return "{:n}".format(int(n))

    if m < 0.01:
        e = int(-log10(m)) + 1
        return "{:.3n}".format(n * 10 ** e) + f"e-%02d" % e
    for k, div, fn, fmt_, suffix in HUMANIZED_SUFFIXES:
        if m < k:
            dec = fn(m) / div
            dec -= int(dec)
            dec = fmt_.format(1 + dec)[1:]
            prefix = "{:n}".format(int(fn(n) / div))
            return prefix + dec + suffix
    return "{:.2n}".format(n)

def _fmt_aux(n, suffix=""):
    m = N_RE.match(str(n))
    sign, number, decimal = m.groups()
    return sign + _fix_int(number, 3) + (decimal or "") + suffix

def _fix_int(s, n):
    return ",".join(map("".join, rpartition(s, n)))

def rpartition(seq, n):
    """
    Partition sequence in groups of n starting from the end of sequence.
    """
    seq = list(seq)
    out = []
    while seq:
        new = []
        for _ in range(n):
            if not seq:
                break
            new.append(seq.pop())
        out.append(new[::-1])
    return out[::-1]

def pc(n):
    """
    Write number as percentages.
    """
    if n == 0:
        return "0.0%"
    return fmt(100 * n) + "%"

def pm(n):
    """
    Write number as parts per thousand.
    """
    if n == 0:
        return "0.0‰"
    return fmt(1000 * n) + "‰"

def p10k(n):
    """
    Write number as parts per ten thousand.
    """
    if n == 0:
        return "0.0‱"
    return fmt(10000 * n) + "‱"

def interpolant(x, y):
    """
    Creates a linear interpolant for the given function passed as sequences of
    x, y points.
    """
    x = np.array(x)
    y = np.array(y)

    def fn(t):
        return np.interp(t, x, y)

    return fn

def lru_safe_cache(size):
    """
    A safe LRU cache that returns a copy of the cached element to prevent
    mutations from cached values.
    """

    def decorator(func):
        cached = lru_cache(size)(func)

        @wraps(func)
        def fn(*args, **kwargs):
            return cached(*args, **kwargs).copy()

        fn.unsafe = cached
        return fn

    return decorator

def indent(st, indent=4):
    """
    Indent string.
    """
    if isinstance(indent, int):
        indent = " " * indent
    return "".join(indent + ln for ln in st.splitlines(keepends=True))

def today() -> datetime.date:
    """
    Return the date today.
    """
    return now().date()

def now() -> datetime.datetime:
    """
    Return a datetime timestamp.
    """
    return datetime.datetime.now()


text:
import collections
import datetime
import itertools
import math
import os

import numpy as np
import torch

from .abstract_game import AbstractGame

class MuZeroConfig:
    def __init__(self):
        # 这里有更多信息: https://github.com/werner-duvaud/muzero-general/wiki/Hyperparameter-Optimization

        self.seed = 0  # numpy、torch和游戏的种子
        self.max_num_gpus = None  # 确定要使用的最大GPU数。如果有足够的显存，使用单个GPU（将其设置为1）通常会更快。None会使用所有可用的GPU

        ### 游戏
        self.observation_shape = (3, 11, 11)  # 游戏观察的尺寸必须为3（通道、高度、宽度）。对于1D数组，请将其形状改为（1，1，数组长度）
        self.action_space = list(range(11 * 11))  # 所有可能动作的固定列表。您应该只编辑长度
        self.players = list(range(2))  # 玩家的列表。您应该只编辑长度
        self.stacked_observations = 0  # 要添加到 当前观察 的 先前观察 和 先前动作 的数量

        # 评估
        self.muzero_player = 0  # Muzero 玩游戏的先后手（0:Muzero 先手，1:Muzero 后手）
        self.opponent = "random"  # MuZero 对战的硬编码智能体，以评估他在多人游戏中的进展。它不影响训练。如果在游戏类中实现，分为 None, "random" or "expert"

        ### 自博弈
        self.num_workers = 1  # 给回放池提供数据的并发自博弈 工作进程/线程 数目
        self.selfplay_on_gpu = False
        self.max_moves = 121  # 如果游戏未在之前完成，则能移动的最大数量
        self.num_simulations = 300  # 自模拟的未来移动次数（MCTS对当前根结点展开模拟的次数）
        self.discount = 1  # 按时间顺序排列的奖励折扣
        self.temperature_threshold = None  # 将 visit_softmax_temperature_fn 给出的温度降至0（即选择最佳动作）之前的移动次数。如果是 None，visit_softmax_temperature_fn 每次都会被用到

        # 根先验探索噪声
        self.root_dirichlet_alpha = 0.3  # 狄利克雷分布的α参数
        self.root_exploration_fraction = 0.25  # 噪声所占的比例

        # UCB 公式
        self.pb_c_base = 19652
        self.pb_c_init = 1.25

        ### 神经网络
        self.network = "resnet"  # "resnet" 或 "fullyconnected"
        self.support_size = 10  # 价值和奖励被缩放（几乎都是用sqrt）并编码在一个向量上，向量的范围为-support_size到support_size。选择它以便使 support_size <= sqrt(max(abs(discounted reward)))

        # 残差网络
        self.downsample = False  # 表示网络 前的下采样观测值, False / "CNN" (更轻量级的) / "resnet" (见论文附录网络架构)
        self.blocks = 3  # ResNet中的块数
        self.channels = 64  # ResNet中的通道数
        self.reduced_channels_reward = 2  # 奖励头 中的通道数
        self.reduced_channels_value = 2  # 价值头 中的通道数
        self.reduced_channels_policy = 4  # 策略头 中的通道数
        self.resnet_fc_reward_layers = [32]  # 在 动态网络 的 奖励头 中定义隐藏层
        self.resnet_fc_value_layers = [32]  # 在 预测网络 的 价值头 中定义隐藏层
        self.resnet_fc_policy_layers = [32]  # 在 预测网络 的 策略头 中定义隐藏层

        # 全连接神经网络
        self.encoding_size = 32
        self.fc_representation_layers = []  # 定义 表示网络 中的隐藏层
        self.fc_dynamics_layers = [64]  # 定义 动态网络 中的隐藏层
        self.fc_reward_layers = [64]  # 定义 奖励网络 中的隐藏层
        self.fc_value_layers = []  # 定义 价值网络 中的隐藏层
        self.fc_policy_layers = []  # 定义 策略网络 中的隐藏层

        ### 训练
        self.results_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../results", os.path.basename(__file__)[:-3], datetime.datetime.now().strftime("%Y-%m-%d--%H-%M-%S"))  # 存储 模型权重 和 Tensorboard 日志的路径
        self.save_model = True  # 将 results_path 中的检查点另存为 model.checkpoint
        self.training_steps = 2000  # 训练步总数（即根据批次更新权重）
        self.batch_size = 64  # 在每个训练步中 训练的游戏片段 的数量
        self.checkpoint_interval = 5  # 保存模型的训练步间隔
        self.value_loss_weight = 1  # 缩放价值损失以避免价值函数的过拟合，论文建议为0.25（见论文附录 重新分析）
        self.train_on_gpu = torch.cuda.is_available()  # 在GPU上训练（如果可用）

        self.optimizer = "Adam"  # "Adam" or "SGD". 论文中使用 SGD
        self.weight_decay = 1e-4  # L2权重正则化
        self.momentum = 0.9  # 仅当优化器为SGD时使用

        # 指数学习速率调度器
        self.lr_init = 0.002  # 初始学习率
        self.lr_decay_rate = 0.9  # 将其设置为1以使用恒定的学习速率
        self.lr_decay_steps = self.training_steps

        ### 回放池
        self.replay_buffer_size = 10000  # 要保留在回放池中的自博弈游戏盘数
        self.num_unroll_steps = 121  # 每盘游戏为批元素保留的游戏移动数（移动为样本的单位），即论文中的“展开的K假设步”
        self.td_steps = 121  # 计算 目标价值 时要考虑的未来步数，即论文中的“n-step前瞻的n”
        self.PER = True  # 优先回放（见论文附录 训练），优先选择回放池中网络意外的元素
        self.PER_alpha = 0.5  # 使用多少优先级，0对应于uniform分布的情况，论文建议1

        # 重新分析（见论文附录 重新分析）
        self.use_last_model_value = False  # 使用最后一个模型提供更新鲜、稳定的 n-step 价值（见论文附录 重新分析）
        self.reanalyse_on_gpu = False

        ### 调整 自博弈/训练 比率，以避免 过拟合/欠拟合
        self.self_play_delay = 0  # 每次玩一盘游戏后等待的秒数
        self.training_delay = 0  # 每个训练步后等待的秒数
        self.ratio = 1 / 50  # 每个 自博弈步 的 期望训练步 比率。与同步版本等效，训练可能需要更长的时间。设置为“None”以禁用它

    def visit_softmax_temperature_fn(self, trained_steps):
        """
        更改 访问次数分布 的参数——确保随着训练的进行，动作选择变得更加贪婪。越小，越有可能选择最佳行动（即访问次数最多）。

        Returns:
            Positive float.
        """
        if trained_steps < 0.5 * self.training_steps:
            return 1.0
        elif trained_steps < 0.75 * self.training_steps:
            return 0.5
        else:
            return 0.25

class Game(AbstractGame):
    """
    游戏装饰器
    """

    def __init__(self, seed=None):
        self.env = Hex()

    def step(self, action):
        """
        在游戏中执行一个动作

        Args:
            action : 要采取的 动作空间 中的 动作。

        Returns:
            新的观察、奖励和（标记游戏是否结束）布尔值。
        """
        observation, reward, done = self.env.step(action)
        return observation, reward, done

    def to_play(self):
        """
        返回当前的玩家

        Returns:
            当前玩家，它应该是配置中玩家列表的一个元素
        """
        return self.env.to_play()

    def legal_actions(self):
        """
        应在每个回合返回合法动作，如果不可用，可返回整个动作空间。在每个回合，游戏必须能够处理一个返回的动作。
        对于计算合法动作太长的复杂游戏，其想法是将合法动作定义为整个动作空间，但如果动作非法，则返回负奖励。

        Returns:
            An array of integers，动作空间的子集
        """
        return self.env.legal_actions()

    def reset(self):
        """
        为新游戏重置游戏

        Returns:
            游戏的初始化观察
        """
        return self.env.reset()

    def close(self):
        """
        正确地结束游戏
        """
        pass

    def render(self):
        """
        可视化（渲染）游戏观察
        """
        self.env.render()
        # input("Press enter to take a step ")

    def human_to_action(self):
        """
        对于多人游戏，要求用户采取合法动作并返回相应的动作编号

        Returns:
            An integer from the action space.
        """
        valid = False
        while not valid:
            valid, action = self.env.human_input_to_action()
        return action

    def action_to_string(self, action):
        """
        将动作编号转换为表示该动作的字符串
        Args:
            action_number: an integer from the action space.
        Returns:
            表示该动作的 字符串
        """
        return self.env.action_to_human_input(action)

class Hex:
    def __init__(self):
        self.board_size = 11
        self.board = np.zeros((self.board_size, self.board_size), dtype="int32")
        self.player = 1  # 红棋为1，蓝棋为-1
        self._directions = [(-1, 0), (0, -1), (1, -1), (1, 0), (0, 1), (-1, 1)]
        self.column_markers = [
            chr(x) for x in range(ord("A"), ord("A") + self.board_size)
        ]
        self.row_markers = [
            str(x) for x in range(1, self.board_size + 1)
        ]

    def to_play(self):
        return 0 if self.player == 1 else 1  # 先手返回0，后手返回1

    def reset(self):
        self.board = np.zeros((self.board_size, self.board_size), dtype="int32")
        self.player = 1
        return self.get_observation()

    def step(self, action):
        x = math.floor(action / self.board_size)
        y = action % self.board_size
        self.board[x][y] = self.player

        done = self.is_finished()

        reward = 1 if done else 0  # 当前玩家获胜，奖励为1   R(St)对应Player(St-1)

        self.player *= -1

        return self.get_observation(), reward, done

    def get_observation(self):
        board_player1 = np.where(self.board == 1, 1.0, 0.0)
        board_player2 = np.where(self.board == -1, 1.0, 0.0)
        board_to_play = np.full((11, 11), self.player, dtype="int32")
        return np.array([board_player1, board_player2, board_to_play])  # 3, 11, 11

    def legal_actions(self):
        legal = []
        for i in range(self.board_size):
            for j in range(self.board_size):
                if self.board[i][j] == 0:
                    legal.append(i * self.board_size + j)
        return legal

    def is_finished(self):
        for j in range(self.board_size):
            if self.is_connected((0, j), 1):
                return True
        for i in range(self.board_size):
            if self.is_connected((i, 0), -1):
                return True
        return False  # 游戏未结束

    def is_connected(self, root, color):
        """判断从上到下或者从左到右是否形成完整的连接，若是则返回True，否则返回False"""
        if self.board[root] != color:
            return False
        visited, queue = {root}, collections.deque([root])
        while queue:
            pos = queue.popleft()
            for neighbor in self.get_neighbors(pos, color):
                if neighbor not in visited:
                    if (color == 1 and neighbor[0] == self.board_size - 1) or (
                            color == -1 and neighbor[1] == self.board_size - 1):
                        return True
                    visited.add(neighbor)
                    queue.append(neighbor)
        return False

    def get_neighbors(self, pos, color):
        """返回一个包含所有同颜色邻居的列表"""
        x, y = pos
        neighbors = []
        for x_offset, y_offset in self._directions:
            nx, ny = (x + x_offset, y + y_offset)
            if self.is_valid_pos(nx, ny):
                if self.board[(nx, ny)] == color:
                    neighbors.append((nx, ny))
        return neighbors

    def is_valid_pos(self, i, j):
        if i < 0 or j < 0 or i >= self.board_size or j >= self.board_size:
            return False
        return True

    def render(self):
        pretty_print_map = {
            1: '\x1b[0;36;41mR  ',
            0: '\x1b[0;31;43m-  ',
            -1: '\x1b[0;31;46mB  ',
        }
        board = np.copy(self.board)
        # 原始棋盘内容
        raw_board_contents = []
        for i in range(self.board_size):
            row = []
            for j in range(self.board_size):
                row.append(pretty_print_map[board[i, j]])
                row.append('\x1b[0m')
            raw_board_contents.append(''.join(row))
        # 行标签 N~1
        row_labels_left = [" " * (self.board_size - i) + '%2d' % i + "\\" for i in
                           range(self.board_size, 0, -1)]
        row_labels_right = ["\\ " + '%2d' % i for i in range(self.board_size, 0, -1)]
        # 带标注的每一行的内容
        annotated_board_contents = [''.join(r) for r in zip(row_labels_left, raw_board_contents, row_labels_right)]
        # 列标签
        header_footer_rows = ['   ' + '  '.join('ABCDEFGHIJK'[:self.board_size]) + '   ']
        tailer_footer_rows = ["   " + " " * (self.board_size) + '  '.join(
            'ABCDEFGHIJK'[:self.board_size]) + '   ']
        # 带标注的棋盘
        # itertools.chain将不同容器中的元素连接起来，便于遍历
        annotated_board = '\n'.join(itertools.chain(header_footer_rows, annotated_board_contents, tailer_footer_rows))
        print(annotated_board)

    def human_input_to_action(self):
        human_input = input("Enter an action: ")
        if (
            len(human_input) == 2
            and human_input[0] in self.column_markers
            and human_input[1:] in self.row_markers
        ):
            y = ord(human_input[0]) - 65
            x = self.board_size - int(human_input[1:])
            if self.board[x][y] == 0:
                return True, x * self.board_size + y
        return False, -1

    def action_to_human_input(self, action):
        x = math.floor(action / self.board_size)
        y = action % self.board_size
        x = str(self.board_size - x)
        y = chr(y + 65)
        return y + x

max_stars_repo_name: Peppa-jyh/MuZero-CN

max_issues_repo_name: Peppa-jyh/MuZero-CN

max_forks_repo_name: Peppa-jyh/MuZero-CN