text:
from sympy.core import Symbol, Function, Float, Rational, Integer, I, Mul, Pow, Eq
from sympy.functions import exp, factorial, sin
from sympy.logic import And
from sympy.series import Limit
from sympy.utilities.pytest import raises

from sympy.parsing.sympy_parser import (
    parse_expr, standard_transformations, rationalize, TokenError,
    split_symbols, implicit_multiplication, convert_equals_signs,
)

def test_sympy_parser():
    x = Symbol('x')
    inputs = {
        '2*x': 2 * x,
        '3.00': Float(3),
        '22/7': Rational(22, 7),
        '2+3j': 2 + 3*I,
        'exp(x)': exp(x),
        'x!': factorial(x),
        '3.[3]': Rational(10, 3),
        '10!': 3628800,
        '-(2)': -Integer(2),
        '[-1, -2, 3]': [Integer(-1), Integer(-2), Integer(3)],
        'Symbol("x").free_symbols': x.free_symbols,
        "S('S(3).n(n=3)')": 3.00,
        'factorint(12, visual=True)': Mul(
            Pow(2, 2, evaluate=False),
            Pow(3, 1, evaluate=False),
            evaluate=False),
        'Limit(sin(x), x, 0, dir="-")': Limit(sin(x), x, 0, dir='-'),

    }
    for text, result in inputs.items():
        assert parse_expr(text) == result

def test_rationalize():
    inputs = {
        '0.123': Rational(123, 1000)
    }
    transformations = standard_transformations + (rationalize,)
    for text, result in inputs.items():
        assert parse_expr(text, transformations=transformations) == result

def test_factorial_fail():
    inputs = ['x!!!', 'x!!!!', '(!)']

    for text in inputs:
        try:
            parse_expr(text)
            assert False
        except TokenError:
            assert True

def test_local_dict():
    local_dict = {
        'my_function': lambda x: x + 2
    }
    inputs = {
        'my_function(2)': Integer(4)
    }
    for text, result in inputs.items():
        assert parse_expr(text, local_dict=local_dict) == result

def test_global_dict():
    global_dict = {
        'Symbol': Symbol
    }
    inputs = {
        'Q & S': And(Symbol('Q'), Symbol('S'))
    }
    for text, result in inputs.items():
        assert parse_expr(text, global_dict=global_dict) == result

def test_issue_2515():
    raises(TokenError, lambda: parse_expr('(()'))
    raises(TokenError, lambda: parse_expr('"""'))

def test_issue_7663():
    x = Symbol('x')
    e = '2*(x+1)'
    assert parse_expr(e, evaluate=0) == parse_expr(e, evaluate=False)

def test_issue_10560():
    inputs = {
        '4*-3' : '(-3)*4',
        '-4*3' : '(-4)*3',
    }
    for text, result in inputs.items():
        assert parse_expr(text, evaluate=False) == parse_expr(result, evaluate=False)

def test_issue_10773():
    inputs = {
    '-10/5': '(-10)/5',
    '-10/-5' : '(-10)/(-5)',
    }
    for text, result in inputs.items():
        assert parse_expr(text, evaluate=False) == parse_expr(result, evaluate=False)

def test_split_symbols():
    transformations = standard_transformations + \
                      (split_symbols, implicit_multiplication,)
    x = Symbol('x')
    y = Symbol('y')
    xy = Symbol('xy')

    assert parse_expr("xy") == xy
    assert parse_expr("xy", transformations=transformations) == x*y

def test_split_symbols_function():
    transformations = standard_transformations + \
                      (split_symbols, implicit_multiplication,)
    x = Symbol('x')
    y = Symbol('y')
    a = Symbol('a')
    f = Function('f')

    assert parse_expr("ay(x+1)", transformations=transformations) == a*y*(x+1)
    assert parse_expr("af(x+1)", transformations=transformations,
                      local_dict={'f':f}) == a*f(x+1)

def test_match_parentheses_implicit_multiplication():
    transformations = standard_transformations + \
                      (implicit_multiplication,)
    raises(TokenError, lambda: parse_expr('(1,2),(3,4]',transformations=transformations))

def test_convert_equals_signs():
    transformations = standard_transformations + \
                        (convert_equals_signs, )
    x = Symbol('x')
    y = Symbol('y')
    assert parse_expr("1*2=x", transformations=transformations) == Eq(2, x)
    assert parse_expr("y = x", transformations=transformations) == Eq(y, x)
    assert parse_expr("(2*y = x) = False",
        transformations=transformations) == Eq(Eq(2*y, x), False)

reason: from sympy


text:
import torch
import matplotlib.pyplot as plt
import numpy as np
import os
import shutil

from combine2d.core import gis, test_cases
from combine2d.core.utils import NonRGIGlacierDirectory
from combine2d.core.first_guess import compile_first_guess
from combine2d.core.inversion import InversionDirectory
from combine2d.core.dynamics import create_glacier
from combine2d.core.cost_function import create_cost_func
from combine2d.core.inversion import InversionDirectory
from combine2d.core import data_logging
from combine2d.core.table_creation import create_case_table
import salem
from oggm import cfg
import matplotlib.colors as colors
from combine2d.core.visualization import MidpointNormalize, truncate_colormap, \
    imshow_ic, plot_glacier_contours, add_colorbar, get_axes_coords

cfg.initialize()

basedir = '/home/philipp/HR_01'
output_dir = '/home/philipp/HR_01'
file_extension = 'pdf'

case = test_cases.Trikora
figsize = (4.5, 3)
for case in [test_cases.BordenHR]:  # [test_cases.Borden, test_cases.Giluwe]:
    gdir = NonRGIGlacierDirectory(case, basedir)

    spinup_surf = salem.GeoTiff(gdir.get_filepath('spinup_dem')).get_vardata()
    reference_surf = salem.GeoTiff(gdir.get_filepath('ref_dem')).get_vardata()
    bed_2d = salem.GeoTiff(gdir.get_filepath('dem')).get_vardata()

    ref_ice_mask = np.load(gdir.get_filepath('ref_ice_mask'))
    ref_it = np.load(gdir.get_filepath('ref_ice_thickness'))
    spinup_it = np.load(gdir.get_filepath('spinup_ice_thickness'))
    masked_ice_thick_end = np.ma.masked_array(ref_it,
                                              mask=np.logical_not(ref_ice_mask))
    #masked_ice_thick_start = np.ma.masked_array(spinup_it,
    #                                            mask=np.logical_not(ref_ice_mask))
    masked_reference_surf = np.ma.masked_array(reference_surf,
                                               mask=np.logical_not(ref_ice_mask))

    #plt.ioff()

    cmap = plt.get_cmap('terrain')
    terrain_cmap = truncate_colormap(cmap, 0.3, 0.8)
    # ---------------------------------------------------------------
    # plot true bed height
    fig = plt.figure(figsize=figsize)
    ax = fig.add_axes(get_axes_coords(case))
    im_b = imshow_ic(ax, bed_2d, case, cmap=terrain_cmap, ticks='scalebar')
    cbar = add_colorbar(fig, ax, im_b)
    cbar.set_label('bed elevation A.S.L (m)')
    #plt.title('Bed of case {:s}, dx={:d}m'.format(case.name, case.dx))
    fname = '{:s}_bed.{:s}'.format(case.name, file_extension)
    #plt.tight_layout()
    plt.savefig(os.path.join(output_dir, fname))
    plt.close(fig)

    cmap = plt.get_cmap('Blues_r')
    cut_gray_cmap = truncate_colormap(cmap, 0.3, 0.9)

    fig = plt.figure(figsize=figsize)
    ax = fig.add_axes(get_axes_coords(case))
    im_b = imshow_ic(ax, bed_2d, case, cmap=terrain_cmap, ticks='scalebar')
    #plt.title('Ice surface height, {:s}, dx={:d}m, t={:d}a'.format(
    #    case.name, case.dx, y))
    im_i = imshow_ic(ax, masked_reference_surf, case, cmap=cut_gray_cmap,
                     ticks='scalebar')
    cbar = add_colorbar(fig, ax, im_i)
    cbar.set_label('ice surface elevation A.S.L. (m)')
    plot_glacier_contours(ax, ref_ice_mask, case) #, linestyles='solid')
    fname = '{:s}_surf_height.{:s}'.format(case.name, file_extension)
    #plt.tight_layout()
    plt.savefig(os.path.join(output_dir, fname))
    plt.close(fig)

    cmap = plt.get_cmap('gist_heat')
    it_cmap = truncate_colormap(cmap, 0.05, 0.9)
    if not np.all(np.equal(ref_it, spinup_it)):
        print('not in equilibrium! consider also plotting spinup')
    fig = plt.figure(figsize=figsize)
    ax = fig.add_axes(get_axes_coords(case))
    im_it = imshow_ic(ax, masked_ice_thick_end, case, cmap=it_cmap, ticks='scalebar')
    cbar = add_colorbar(fig, ax, im_it)
    cbar.set_label('ice thickness (m)')
    fname = '{:s}_ice_thickness.{:s}'.format(case.name, file_extension)
    plot_glacier_contours(ax, ref_ice_mask, case)
    #plt.show()
    #plt.tight_layout()
    plt.savefig(os.path.join(output_dir, fname))
    plt.close(fig)

    #For evaluation
    gradients = np.gradient(bed_2d, case.dx)
    gradients = np.sqrt(gradients[0] ** 2 + gradients[1] ** 2)
    angle = np.rad2deg(np.arctan(gradients))
    print(np.max(angle))
    print(np.min(angle))

    #plt.ion()

#inner_mask = torch.zeros(ice_mask.shape)
#inner_mask[1:-1, 1:-1] = torch.conv2d(torch.tensor([[ice_mask]], dtype=torch.float), torch.ones((1, 1, 3,3))) == 9
#plt.figure()
#plt.imshow(ice_mask - inner_mask)
#plt.show()

ext: py

max_stars_repo_name: phigre/cobi

max_issues_repo_name: phigre/cobi

max_forks_repo_name: phigre/COBBI

reason: import numpy


text:
from __future__ import print_function
import os
import pickle

import torch
import numpy
from data import get_test_loader
import time
import numpy as np
from vocab import Vocabulary  # NOQA
from model import CGMN, order_sim
from collections import OrderedDict

class AverageMeter(object):
    """Computes and stores the average and current value"""

    def __init__(self):
        self.reset()

    def reset(self):
        self.val = 0
        self.avg = 0
        self.sum = 0
        self.count = 0

    def update(self, val, n=0):
        self.val = val
        self.sum += val * n
        self.count += n
        self.avg = self.sum / (.0001 + self.count)

    def __str__(self):
        """String representation for logging
        """
        # for values that should be recorded exactly e.g. iteration number
        if self.count == 0:
            return str(self.val)
        # for stats
        return '%.4f (%.4f)' % (self.val, self.avg)

class LogCollector(object):
    """A collection of logging objects that can change from train to val"""

    def __init__(self):
        # to keep the order of logged variables deterministic
        self.meters = OrderedDict()

    def update(self, k, v, n=0):
        # create a new meter if previously not recorded
        if k not in self.meters:
            self.meters[k] = AverageMeter()
        self.meters[k].update(v, n)

    def __str__(self):
        """Concatenate the meters in one log line
        """
        s = ''
        for i, (k, v) in enumerate(self.meters.iteritems()):
            if i > 0:
                s += '  '
            s += k + ' ' + str(v)
        return s

    def tb_log(self, tb_logger, prefix='', step=None):
        """Log using tensorboard
        """
        for k, v in self.meters.iteritems():
            tb_logger.log_value(prefix + k, v.val, step=step)

def encode_data(model, data_loader, log_step=10, logging=print):
    """Encode all images and captions loadable by `data_loader`
    """
    batch_time = AverageMeter()
    val_logger = LogCollector()

    # switch to evaluate mode
    model.val_start()

    end = time.time()

    # numpy array to keep all the embeddings
    img_embs = None
    cap_embs = None
    for i, (images, captions, lengths, ids, depend, bboxes, Iou, caption_label, caption_mask) in enumerate(data_loader):
        # make sure val logger is used
        model.logger = val_logger

        # compute the embeddings
        img_emb, cap_emb, _ , _ = model.forward_emb(images, captions, lengths, depend, bboxes, Iou,
                                             volatile=True)

        # initialize the numpy arrays given the size of the embeddings
        if img_embs is None:
            img_embs = np.zeros((len(data_loader.dataset), img_emb.size(1)))
            cap_embs = np.zeros((len(data_loader.dataset), cap_emb.size(1)))

        # preserve the embeddings by copying from gpu and converting to numpy
        img_embs[ids] = img_emb.data.cpu().numpy().copy()
        cap_embs[ids] = cap_emb.data.cpu().numpy().copy()

        del images, captions, lengths, ids, depend, bboxes, Iou, caption_label, caption_mask
    return img_embs, cap_embs

def evalrank(model_path, data_path=None, split='dev', fold5=False):
    """
    Evaluate a trained model on either dev or test. If `fold5=True`, 5 fold
    cross-validation is done (only for MSCOCO). Otherwise, the full data is
    used for evaluation.
    """
    # load model and options
    checkpoint = torch.load(model_path)
    opt = checkpoint['opt']

    if data_path is not None:
        opt.data_path = data_path

    # load vocabulary used by the model
    with open(os.path.join(opt.vocab_path,
                           '%s_vocab.pkl' % opt.data_name), 'rb') as f:
        vocab = pickle.load(f)
    opt.vocab_size = len(vocab)

    # construct model
    model = CGMN(opt)
    # load model state
    model.load_state_dict(checkpoint['model'])

    #opt.data_name = 'coco_precomp'

    print('Loading dataset')
    data_loader = get_test_loader(split, opt.data_name, vocab, opt.crop_size,
                                  opt.batch_size, opt.workers, opt)

    print('Computing results...')
    start1 = time.time()
    img_embs, cap_embs = encode_data(model, data_loader)
    start2 = time.time()

    print('Images: %d, Captions: %d' %
          (img_embs.shape[0] / 5, cap_embs.shape[0]))

    if not fold5:
        # no cross-validation, full evaluation
        r, rt = i2t(img_embs, cap_embs, measure=opt.measure, return_ranks=True)
        ri, rti = t2i(img_embs, cap_embs,
                      measure=opt.measure, return_ranks=True)
        end = time.time()
        print("time1", end- start1)
        print("time2", end- start2)
        ar = (r[0] + r[1] + r[2]) / 3
        ari = (ri[0] + ri[1] + ri[2]) / 3
        rsum = r[0] + r[1] + r[2] + ri[0] + ri[1] + ri[2]
        print("rsum: %.1f" % rsum)
        print("Average i2t Recall: %.1f" % ar)
        print("Image to text: %.1f %.1f %.1f %.1f %.1f" % r)
        print("Average t2i Recall: %.1f" % ari)
        print("Text to image: %.1f %.1f %.1f %.1f %.1f" % ri)
    else:
        # 5fold cross-validation, only for MSCOCO
        results = []
        for i in range(5):
            r, rt0 = i2t(img_embs[i * 5000:(i + 1) * 5000],
                         cap_embs[i * 5000:(i + 1) *
                                  5000], measure=opt.measure,
                         return_ranks=True)
            print("Image to text: %.1f, %.1f, %.1f, %.1f, %.1f" % r)
            ri, rti0 = t2i(img_embs[i * 5000:(i + 1) * 5000],
                           cap_embs[i * 5000:(i + 1) *
                                    5000], measure=opt.measure,
                           return_ranks=True)
            if i == 0:
                rt, rti = rt0, rti0
            print("Text to image: %.1f, %.1f, %.1f, %.1f, %.1f" % ri)
            ar = (r[0] + r[1] + r[2]) / 3
            ari = (ri[0] + ri[1] + ri[2]) / 3
            rsum = r[0] + r[1] + r[2] + ri[0] + ri[1] + ri[2]
            print("rsum: %.1f ar: %.1f ari: %.1f" % (rsum, ar, ari))
            results += [list(r) + list(ri) + [ar, ari, rsum]]

        print("-----------------------------------")
        print("Mean metrics: ")
        mean_metrics = tuple(np.array(results).mean(axis=0).flatten())
        print("rsum: %.1f" % (mean_metrics[12]))
        print("Average i2t Recall: %.1f" % mean_metrics[10])
        print("Image to text: %.1f %.1f %.1f %.1f %.1f" %
              mean_metrics[:5])
        print("Average t2i Recall: %.1f" % mean_metrics[11])
        print("Text to image: %.1f %.1f %.1f %.1f %.1f" %
              mean_metrics[5:10])

    torch.save({'rt': rt, 'rti': rti}, 'ranks.pth.tar')

def i2t(images, captions, npts=None, measure='cosine', return_ranks=False):
    """
    Images->Text (Image Annotation)
    Images: (5N, K) matrix of images
    Captions: (5N, K) matrix of captions
    """
    if npts is None:
        npts = images.shape[0] / 5
    index_list = []

    ranks = numpy.zeros(npts)
    top1 = numpy.zeros(npts)
    for index in range(npts):

        # Get query image
        im = images[5 * index].reshape(1, images.shape[1])

        # Compute scores
        if measure == 'order':
            bs = 100
            if index % bs == 0:
                mx = min(images.shape[0], 5 * (index + bs))
                im2 = images[5 * index:mx:5]
                d2 = order_sim(torch.Tensor(im2).cuda(),
                               torch.Tensor(captions).cuda())
                d2 = d2.cpu().numpy()
            d = d2[index % bs]
        else:
            d = numpy.dot(im, captions.T).flatten()
        inds = numpy.argsort(d)[::-1]
        index_list.append(inds[0])

        # Score
        rank = 1e20
        for i in range(5 * index, 5 * index + 5, 1):
            tmp = numpy.where(inds == i)[0][0]
            if tmp < rank:
                rank = tmp
        ranks[index] = rank
        top1[index] = inds[0]

    # Compute metrics
    r1 = 100.0 * len(numpy.where(ranks < 1)[0]) / len(ranks)
    r5 = 100.0 * len(numpy.where(ranks < 5)[0]) / len(ranks)
    r10 = 100.0 * len(numpy.where(ranks < 10)[0]) / len(ranks)
    medr = numpy.floor(numpy.median(ranks)) + 1
    meanr = ranks.mean() + 1
    if return_ranks:
        return (r1, r5, r10, medr, meanr), (ranks, top1)
    else:
        return (r1, r5, r10, medr, meanr)

def t2i(images, captions, npts=None, measure='cosine', return_ranks=False):
    """
    Text->Images (Image Search)
    Images: (5N, K) matrix of images
    Captions: (5N, K) matrix of captions
    """
    if npts is None:
        npts = images.shape[0] / 5
    ims = numpy.array([images[i] for i in range(0, len(images), 5)])

    ranks = numpy.zeros(5 * npts)
    top1 = numpy.zeros(5 * npts)
    for index in range(npts):

        # Get query captions
        queries = captions[5 * index:5 * index + 5]

        # Compute scores
        if measure == 'order':
            bs = 100
            if 5 * index % bs == 0:
                mx = min(captions.shape[0], 5 * index + bs)
                q2 = captions[5 * index:mx]
                d2 = order_sim(torch.Tensor(ims).cuda(),
                               torch.Tensor(q2).cuda())
                d2 = d2.cpu().numpy()

            d = d2[:, (5 * index) % bs:(5 * index) % bs + 5].T
        else:
            d = numpy.dot(queries, ims.T)
        inds = numpy.zeros(d.shape)
        for i in range(len(inds)):
            inds[i] = numpy.argsort(d[i])[::-1]
            ranks[5 * index + i] = numpy.where(inds[i] == index)[0][0]
            top1[5 * index + i] = inds[i][0]

    # Compute metrics
    r1 = 100.0 * len(numpy.where(ranks < 1)[0]) / len(ranks)
    r5 = 100.0 * len(numpy.where(ranks < 5)[0]) / len(ranks)
    r10 = 100.0 * len(numpy.where(ranks < 10)[0]) / len(ranks)
    medr = numpy.floor(numpy.median(ranks)) + 1
    meanr = ranks.mean() + 1
    if return_ranks:
        return (r1, r5, r10, medr, meanr), (ranks, top1)
    else:
        return (r1, r5, r10, medr, meanr)

max_stars_repo_name: cyh-sj/CGMN

max_issues_repo_name: cyh-sj/CGMN

max_forks_repo_name: cyh-sj/CGMN


text:
import logging
import operator
import os
import sys
from collections import namedtuple, OrderedDict
from copy import copy

import time

import IPython
from functools import partial

import numpy as np

import torch
import torch.nn as nn
import torch.utils
import torch.nn.functional as F
import torchvision.datasets as dset
import torch.backends.cudnn as cudnn
from tensorboardX import SummaryWriter

import search_policies.cnn.utils
from search_policies.cnn.search_space.nas_bench.util import change_model_spec
from ..search_space.nas_bench.model import NasBenchNet
from search_policies.cnn.nao_policy.controller import NAO, NAO_Nasbench
import search_policies.cnn.nao_policy.utils as nao_utils
import search_policies.cnn.nao_policy.utils_for_nasbench as nao_nasbench_utils
from search_policies.cnn.nao_policy.model import NASNetworkCIFAR
from search_policies.cnn.nao_policy.model_search import NASWSNetworkCIFAR

from search_policies.cnn.search_space.nas_bench.sampler import obtain_full_model_spec, obtain_random_spec
from search_policies.cnn import model as model_module
import search_policies.cnn.procedures as procedure_ops
import utils as project_utils

from search_policies.cnn.search_space.nas_bench.nasbench_api_v2 import NASBench_v2, ModelSpec_v2
from visualization.plot_rank_change import process_rank_data_nasbench
from visualization.process_data import tensorboard_summarize_list
import gc

Rank = namedtuple('Rank', 'valid_acc valid_obj geno_id gt_rank')
from ..random_policy.nasbench_weight_sharing_policy import NasBenchWeightSharingPolicy
from .model_search_nasbench import NasBenchNetSearchNAO
from search_policies.cnn.search_space.search_space_utils import sequence_arch_to_model_spec
from ..procedures.train_search_procedure import nao_model_validation_nasbench
from ..cnn_general_search_policies import CNNSearchPolicy

class NAOOriginalSearch(CNNSearchPolicy):
    # TODO This is not yet supported. please run the official code for 10 times. and parse the data manually.
    def evaluate(self, epoch, data_source, fitnesses_dict=None, train_queue=None):
        pass
    def op_sampler(self, model, architect, args):
        pass
    def random_sampler(self, model, architect, args):
        pass
    def validate_model(self, current_model, data_source, current_geno_id, current_genotype, batch_size=10):
        pass

class NAONasBenchSearch(NasBenchWeightSharingPolicy):

    top_K_complete_evaluate = 100

    # nao_search_config
    def wrap_nao_search_config(self):
        for k, v in self.args.nao_search_config.__dict__.items():
            self.args.__dict__[k] = v

    def initialize_run(self, sub_dir_path=None):
        args = self.args
        utils = project_utils
        if not self.args.continue_train:
            self.sub_directory_path = 'WeightSharingNasBenchNetRandom-{}_SEED_{}'.format(self.args.save, self.args.seed)
            self.exp_dir = os.path.join(self.args.main_path, self.sub_directory_path)
            utils.create_exp_dir(self.exp_dir)
        if self.args.visualize:
            self.viz_dir_path = utils.create_viz_dir(self.exp_dir)

        if self.args.tensorboard:
            self.tb_dir = self.exp_dir
            tboard_dir = os.path.join(self.args.tboard_dir, self.sub_directory_path)
            self.writer = SummaryWriter(tboard_dir)

        if self.args.debug:
            torch.autograd.set_detect_anomaly(True)

        # Set logger.
        self.logger = utils.get_logger(
            "train_search",
            file_handler=utils.get_file_handler(os.path.join(self.exp_dir, 'log.txt')),
            level=logging.INFO if not args.debug else logging.DEBUG
        )
        logging.info(f"setting random seed as {args.seed}")
        utils.torch_random_seed(args.seed)
        logging.info('gpu number = %d' % args.gpus)
        logging.info("args = %s", args)

        criterion = nn.CrossEntropyLoss().cuda()
        eval_criterion = nn.CrossEntropyLoss().cuda()
        self.eval_loss = eval_criterion

        train_transform, valid_transform = utils._data_transforms_cifar10(args.cutout_length if args.cutout else None)
        train_data = dset.CIFAR10(root=args.data, train=True, download=True, transform=train_transform)
        valid_data = dset.CIFAR10(root=args.data, train=True, download=True, transform=valid_transform)
        test_data = dset.CIFAR10(root=args.data, train=False, download=True, transform=valid_transform)

        num_train = len(train_data)
        indices = list(range(num_train))
        split = int(np.floor(args.nao_search_config.ratio * num_train))

        train_queue = torch.utils.data.DataLoader(
            train_data, batch_size=args.batch_size,
            sampler=torch.utils.data.sampler.SubsetRandomSampler(indices[:split]),
            pin_memory=True, num_workers=2)

        valid_queue = torch.utils.data.DataLoader(
            valid_data, batch_size=args.nao_search_config.child_eval_batch_size,
            sampler=torch.utils.data.sampler.SubsetRandomSampler(indices[split:num_train]),
            pin_memory=True, num_workers=2)

        test_queue = torch.utils.data.DataLoader(
            test_data, batch_size=args.evaluate_batch_size,
            shuffle=False, pin_memory=True, num_workers=8)

        return train_queue, valid_queue, test_queue, criterion, eval_criterion

    def initialize_model(self):
        """
        Initialize model, may change across different model.
        :return:
        """
        args = self.args
        # over ride the model_fn
        self.train_fn = None
        self.eval_fn = nao_model_validation_nasbench

        if self.args.search_space == 'nasbench':
            self.model_fn = NasBenchNetSearchNAO
            self.fixmodel_fn = NasBenchNet
            model = self.model_fn(args)
            utils = nao_nasbench_utils

            nao = NAO_Nasbench(
                args.controller_encoder_layers,
                args.controller_encoder_vocab_size,
                args.controller_encoder_hidden_size,
                args.controller_encoder_dropout,
                args.controller_encoder_length,
                args.controller_source_length,
                args.controller_encoder_emb_size,
                args.controller_mlp_layers,
                args.controller_mlp_hidden_size,
                args.controller_mlp_dropout,
                args.controller_decoder_layers,
                args.controller_decoder_vocab_size,
                args.controller_decoder_hidden_size,
                args.controller_decoder_dropout,
                args.controller_decoder_length,
                args=args,
            )
        else:
            utils = nao_utils
            self.model_fn = NASWSNetworkCIFAR
            self.fixmodel_fn = NASNetworkCIFAR
            model = self.model_fn(10, args.child_layers, args.child_nodes, args.child_channels, args.child_keep_prob, args.child_drop_path_keep_prob,
                           args.child_use_aux_head, args.steps)

            nao = NAO(
                args.controller_encoder_layers,
                args.controller_encoder_vocab_size,
                args.controller_encoder_hidden_size,
                args.controller_encoder_dropout,
                args.controller_encoder_length,
                args.controller_source_length,
                args.controller_encoder_emb_size,
                args.controller_mlp_layers,
                args.controller_mlp_hidden_size,
                args.controller_mlp_dropout,
                args.controller_decoder_layers,
                args.controller_decoder_vocab_size,
                args.controller_decoder_hidden_size,
                args.controller_decoder_dropout,
                args.controller_decoder_length,
            )

        nao = nao.cuda()
        logging.info("Encoder-Predictor-Decoder param size = %fMB", utils.count_parameters_in_MB(nao))

        self.controller = nao

        if args.gpus > 0:
            if self.args.gpus == 1:
                model = model.cuda()
                self.parallel_model = model
            else:
                self.model = model
                self.parallel_model = nn.DataParallel(self.model).cuda()
                # IPython.embed(header='checking replicas and others.')
        else:
            self.parallel_model = model
        # rewrite the pointer
        model = self.parallel_model
        logging.info("param size = %fMB", utils.count_parameters_in_MB(model))

        optimizer = torch.optim.SGD(
            model.parameters(),
            args.child_lr_max,
            momentum=0.9,
            weight_decay=args.child_l2_reg,
        )

        # scheduler as Cosine.
        scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, args.child_epochs, args.child_lr_min)

        return model, optimizer, scheduler, nao

    def child_arch_pool_prob(self, child_arch_pool):
        args = self.args
        if args.child_sample_policy == 'params':
            child_arch_pool_prob = []
            print('num is %d', len(child_arch_pool))
            for arch in child_arch_pool:
                # just to count the parameters and use as prob, kind of a biased sampling.
                # use model hash to query.
                if self.args.search_space == 'nasbench':
                    tmp_model = self.fixmodel_fn(3, self.process_arch(arch), args.nasbench_config)
                else:
                    tmp_model = self.fixmodel_fn(args, 10, args.child_layers, args.child_nodes, args.child_channels,
                                                args.child_keep_prob, args.child_drop_path_keep_prob,
                                                args.child_use_aux_head, args.steps, arch)
                child_arch_pool_prob.append(self.utils.count_parameters_in_MB(tmp_model))
                del tmp_model
        else:
            child_arch_pool_prob = None
        return child_arch_pool_prob

    def run(self):
        args = self.args
        self.utils = nao_nasbench_utils if args.search_space == 'nasbench' else nao_utils
        utils = self.utils
        self.nao_search_config = args.nao_search_config
        self.wrap_nao_search_config()
        train_queue, valid_queue, test_queue, train_criterion, eval_criterion = self.initialize_run()

        args.steps = int(np.ceil(45000 / args.child_batch_size)) * args.child_epochs
        if args.child_arch_pool is not None:
            logging.info('Architecture pool is provided, loading')
            with open(args.child_arch_pool) as f:
                archs = f.read().splitlines()
                archs = list(map(self.utils.build_dag, archs))
                child_arch_pool = archs
        elif os.path.exists(os.path.join(self.exp_dir, 'arch_pool')):
            logging.info('Architecture pool is founded, loading')
            with open(os.path.join(self.exp_dir, 'arch_pool')) as f:
                archs = f.read().splitlines()
                archs = list(map(self.utils.build_dag, archs))
                child_arch_pool = archs
        else:
            child_arch_pool = None

        child_eval_epochs = eval(args.child_eval_epochs)

        # build the functions.
        args = self.args

        model, optimizer, scheduler, nao = self.initialize_model()
        fitness_dict = {}
        self.optimizer = optimizer
        self.scheduler = scheduler
        # Train child model
        if child_arch_pool is None:
            logging.info('Architecture pool is not provided, randomly generating now')
            child_arch_pool = self.generate_new_arch(args.controller_seed_arch)
        child_arch_pool_prob = self.child_arch_pool_prob(child_arch_pool)
        eval_points = self.utils.generate_eval_points(child_eval_epochs, 0, args.child_epochs)
        logging.info("eval epochs = %s", eval_points)

        step = 0
        # Begin the full loop
        for epoch in range(args.epochs):
            scheduler.step()
            lr = scheduler.get_lr()[0]
            logging.info('epoch %d lr %e', epoch, lr)
            # sample an arch to train
            train_acc, train_obj, step = self.child_train(train_queue, model, optimizer, step, child_arch_pool,
                                                            child_arch_pool_prob, train_criterion)
            if self.writer:
                self.writer.add_scalar(f'train/loss', train_obj, epoch)
                self.writer.add_scalar(f'train/top_1_acc', train_acc, epoch)

            logging.info('train_acc %f', train_acc)

            if epoch not in eval_points:
                # Continue training the architectures
                continue

            # Evaluate seed archs
            valid_accuracy_list = self.child_valid(valid_queue, model, child_arch_pool, eval_criterion)

            # Output archs and evaluated error rate
            old_archs = child_arch_pool
            old_archs_perf = valid_accuracy_list

            old_archs_sorted_indices = np.argsort(old_archs_perf)[::-1]
            old_archs = [old_archs[i] for i in old_archs_sorted_indices]
            old_archs_perf = [old_archs_perf[i] for i in old_archs_sorted_indices]
            with open(os.path.join(self.exp_dir, 'arch_pool.{}'.format(epoch)), 'w') as fa:
                with open(os.path.join(self.exp_dir, 'arch_pool.perf.{}'.format(epoch)), 'w') as fp:
                    with open(os.path.join(self.exp_dir, 'arch_pool'), 'w') as fa_latest:
                        with open(os.path.join(self.exp_dir, 'arch_pool.perf'), 'w') as fp_latest:
                            for arch, perf in zip(old_archs, old_archs_perf):
                                arch = self.process_archname(arch)
                                fa.write('{}\n'.format(arch))
                                fa_latest.write('{}\n'.format(arch))
                                fp.write('{}\n'.format(perf))
                                fp_latest.write('{}\n'.format(perf))

            if epoch == args.child_epochs:
                break

            # Train Encoder-Predictor-Decoder
            logging.info('Training Encoder-Predictor-Decoder')
            min_val = min(old_archs_perf)
            max_val = max(old_archs_perf)
            encoder_target = [(i - min_val) / (max_val - min_val) for i in old_archs_perf]
            encoder_input = self.process_arch_to_seq(old_archs)
            if args.controller_expand is not None:
                train_encoder_input, train_encoder_target, valid_encoder_input, valid_encoder_target = \
                    self.expand_controller(encoder_input, encoder_target)
            else:
                train_encoder_input = encoder_input
                train_encoder_target = encoder_target
                valid_encoder_input = encoder_input
                valid_encoder_target = encoder_target

            logging.info('Train data: {}\tValid data: {}'.format(len(train_encoder_input), len(valid_encoder_input)))

            # gerenrate NAO dataset.
            nao_train_dataset = utils.NAODataset(train_encoder_input, train_encoder_target, True,
                                                 swap=True if args.controller_expand is None else False)
            nao_valid_dataset = utils.NAODataset(valid_encoder_input, valid_encoder_target, False)
            nao_train_queue = torch.utils.data.DataLoader(
                nao_train_dataset, batch_size=args.controller_batch_size, shuffle=True, pin_memory=True)
            nao_valid_queue = torch.utils.data.DataLoader(
                nao_valid_dataset, batch_size=args.controller_batch_size, shuffle=False, pin_memory=True)
            nao_optimizer = torch.optim.Adam(nao.parameters(), lr=args.controller_lr,
                                             weight_decay=args.controller_l2_reg)

            # train the sampler.
            for nao_epoch in range(1, args.controller_epochs + 1):
                nao_loss, nao_mse, nao_ce = self.nao_train(nao_train_queue, nao, nao_optimizer)
                logging.info("epoch %04d train loss %.6f mse %.6f ce %.6f", nao_epoch, nao_loss, nao_mse, nao_ce)
                if nao_epoch % 100 == 0:
                    pa, hs = self.nao_valid(nao_valid_queue, nao)
                    logging.info("Evaluation on valid data")
                    logging.info('epoch %04d pairwise accuracy %.6f hamming distance %.6f', epoch, pa, hs)
                    self.writer.add_scalar(f'valid/hamming_distance', hs, epoch)
                    self.writer.add_scalar(f'valid/pairwise_acc', pa, epoch)

            # Generate new archs
            new_archs = []
            max_step_size = 50
            predict_step_size = 0
            top100_archs = self.process_arch_to_seq(old_archs[:100])
            nao_infer_dataset = utils.NAODataset(top100_archs, None, False)
            nao_infer_queue = torch.utils.data.DataLoader(
                nao_infer_dataset, batch_size=len(nao_infer_dataset), shuffle=False, pin_memory=True)
            while len(new_archs) < args.controller_new_arch:
                predict_step_size += 1
                logging.info('Generate new architectures with step size %d', predict_step_size)
                new_arch = self.nao_infer(nao_infer_queue, nao, predict_step_size, direction='+')
                for arch in new_arch:
                    if arch not in encoder_input and arch not in new_archs:
                        new_archs.append(arch)
                    if len(new_archs) >= args.controller_new_arch:
                        break
                logging.info('%d new archs generated now', len(new_archs))
                if predict_step_size > max_step_size:
                    break
            # new_archs = list(map(lambda x: utils.parse_seq_to_arch(x, 2), new_archs))
            new_archs = self.process_seq_to_arch(new_archs)
            num_new_archs = len(new_archs)
            logging.info("Generate %d new archs", num_new_archs)
            # replace bottom archs
            if args.controller_replace:
                new_arch_pool = old_archs[:len(old_archs) - (num_new_archs + args.controller_random_arch)] + \
                                new_archs + self.generate_new_arch(args.controller_random_arch)
            # discard all archs except top k
            elif args.controller_discard:
                new_arch_pool = old_archs[:100] + new_archs + self.generate_new_arch(args.controller_random_arch)
            # use all
            else:
                new_arch_pool = old_archs + new_archs + self.generate_new_arch(args.controller_random_arch)
            logging.info("Totally %d architectures now to train", len(new_arch_pool))

            child_arch_pool = new_arch_pool
            with open(os.path.join(self.exp_dir, 'arch_pool'), 'w') as f:
                for arch in new_arch_pool:
                    f.write('{}\n'.format(self.process_archname(arch)))

            child_arch_pool_prob = self.child_arch_pool_prob(child_arch_pool)

            if epoch % self.args.save_every_epoch == 0:
                project_utils.save_checkpoint(model, optimizer, epoch, self.exp_dir)

        # add later, return the model specs that is evaluated across the time.
        # Process the ranking in the end, return the best of training.
        fitness_dict = self.evaluate(epoch, test_queue,
                                     fitnesses_dict=fitness_dict,
                                     arch_pool=child_arch_pool,
                                     train_queue=train_queue,
                                     criterion=eval_criterion)
        project_utils.save_checkpoint(model, optimizer, epoch, self.exp_dir)
        self.save_results(epoch, rank_details=True)
        ep_k = [k for k in self.ranking_per_epoch.keys()][-1]
        best_id = self.ranking_per_epoch[ep_k][-1][1].geno_id
        return best_id, self.nasbench_model_specs[best_id]

    def child_train(self, train_queue, model, optimizer, global_step, arch_pool, arch_pool_prob, criterion):
        utils = self.utils
        objs = search_policies.cnn.utils.AverageMeter()
        top1 = search_policies.cnn.utils.AverageMeter()
        top5 = search_policies.cnn.utils.AverageMeter()
        model.train()
        for step, (input, target) in enumerate(train_queue):
            if self.args.debug:
                if step > 10:
                    print("Break after 10 batch")
                    break
            input = input.cuda().requires_grad_()
            target = target.cuda()

            optimizer.zero_grad()

            # sample an arch to train
            arch = utils.sample_arch(arch_pool, arch_pool_prob)
            arch_l = arch
            arch = self.process_arch(arch)
            logits, aux_logits = model(input, arch, global_step, bn_train=False)
            global_step += 1
            loss = criterion(logits, target)
            if aux_logits is not None:
                aux_loss = criterion(aux_logits, target)
                loss += 0.4 * aux_loss
            loss.backward()
            nn.utils.clip_grad_norm_(model.parameters(), self.args.child_grad_bound)
            optimizer.step()

            prec1, prec5 = utils.accuracy(logits, target, topk=(1, 5))
            n = input.size(0)
            objs.update(loss.data, n)
            top1.update(prec1.data, n)
            top5.update(prec5.data, n)

            if (step + 1) % 100 == 0:
                logging.info('Train %03d loss %e top1 %f top5 %f', step + 1, objs.avg, top1.avg, top5.avg)
                logging.info('Arch: %s', self.process_archname(arch_l))

        return top1.avg, objs.avg, global_step

    def child_valid(self,valid_queue, model, arch_pool, criterion):
        valid_acc_list = []
        with torch.no_grad():
            model.eval()
            for i, arch in enumerate(arch_pool):
                # for step, (inputs, targets) in enumerate(valid_queue):
                inputs, targets = next(iter(valid_queue))
                inputs = inputs.cuda()
                targets = targets.cuda()
                arch_l = arch
                arch = self.process_arch(arch)
                logits, _ = model(inputs, arch, bn_train=True)
                loss = criterion(logits, targets)

                prec1, prec5 = self.utils.accuracy(logits, targets, topk=(1, 5))
                valid_acc_list.append(prec1.data / 100)

                if (i + 1) % 100 == 0:
                    logging.info('Valid arch %s\n loss %.2f top1 %f top5 %f', self.process_archname(arch_l),
                                 loss, prec1, prec5)

        return valid_acc_list

    def nao_train(self, train_queue, model, optimizer):
        args = self.args
        objs = search_policies.cnn.utils.AverageMeter()
        mse = search_policies.cnn.utils.AverageMeter()
        nll = search_policies.cnn.utils.AverageMeter()
        model.train()
        for step, sample in enumerate(train_queue):
            encoder_input = sample['encoder_input']
            encoder_target = sample['encoder_target']
            decoder_input = sample['decoder_input']
            decoder_target = sample['decoder_target']

            encoder_input = encoder_input.cuda()
            encoder_target = encoder_target.cuda().requires_grad_()
            decoder_input = decoder_input.cuda()
            decoder_target = decoder_target.cuda()

            optimizer.zero_grad()
            predict_value, log_prob, arch = model(encoder_input, decoder_input)
            loss_1 = F.mse_loss(predict_value.squeeze(), encoder_target.squeeze())
            loss_2 = F.nll_loss(log_prob.contiguous().view(-1, log_prob.size(-1)), decoder_target.view(-1))
            loss = args.controller_trade_off * loss_1 + (1 - args.controller_trade_off) * loss_2
            loss.backward()
            torch.nn.utils.clip_grad_norm_(model.parameters(), args.controller_grad_bound)
            optimizer.step()

            n = encoder_input.size(0)
            objs.update(loss.data, n)
            mse.update(loss_1.data, n)
            nll.update(loss_2.data, n)

        return objs.avg, mse.avg, nll.avg

    @staticmethod
    def nao_valid(queue, model):
        pa = search_policies.cnn.utils.AverageMeter()
        hs = search_policies.cnn.utils.AverageMeter()
        with torch.no_grad():
            model.eval()
            for step, sample in enumerate(queue):
                encoder_input = sample['encoder_input']
                encoder_target = sample['encoder_target']
                decoder_target = sample['decoder_target']

                encoder_input = encoder_input.cuda()
                encoder_target = encoder_target.cuda()
                decoder_target = decoder_target.cuda()

                predict_value, logits, arch = model(encoder_input)
                n = encoder_input.size(0)
                pairwise_acc = nao_utils.pairwise_accuracy(encoder_target.data.squeeze().tolist(),
                                                       predict_value.data.squeeze().tolist())
                hamming_dis = nao_utils.hamming_distance(decoder_target.data.squeeze().tolist(),
                                                     arch.data.squeeze().tolist())
                pa.update(pairwise_acc, n)
                hs.update(hamming_dis, n)
        return pa.avg, hs.avg

    @staticmethod
    def nao_infer(queue, model, step, direction='+'):
        new_arch_list = []
        model.eval()
        for i, sample in enumerate(queue):
            encoder_input = sample['encoder_input']
            encoder_input = encoder_input.cuda()
            model.zero_grad()
            new_arch = model.generate_new_arch(encoder_input, step, direction=direction)
            new_arch_list.extend(new_arch.data.squeeze().tolist())
        return new_arch_list

    def expand_controller(self, encoder_input, encoder_target):
        args = self.args
        dataset = list(zip(encoder_input, encoder_target))
        n = len(dataset)
        split = int(n * args.ratio)
        np.random.shuffle(dataset)
        encoder_input, encoder_target = list(zip(*dataset))
        train_encoder_input = list(encoder_input[:split])
        train_encoder_target = list(encoder_target[:split])
        valid_encoder_input = list(encoder_input[split:])
        valid_encoder_target = list(encoder_target[split:])
        if args.search_space == 'nasbench':
            for _ in range(args.controller_expand - 1):
                for src, tgt in zip(encoder_input[:split], encoder_target[:split]):
                    train_encoder_input.append(src)
                    train_encoder_target.append(tgt)

        else:
            for _ in range(args.controller_expand - 1):
                # TODO what is controller expand?????
                for src, tgt in zip(encoder_input[:split], encoder_target[:split]):
                    a = np.random.randint(0, args.child_nodes)
                    b = np.random.randint(0, args.child_nodes)
                    src = src[:4 * a] + src[4 * a + 2:4 * a + 4] + \
                          src[4 * a:4 * a + 2] + src[4 * (a + 1):20 + 4 * b] + \
                          src[20 + 4 * b + 2:20 + 4 * b + 4] + src[20 + 4 * b:20 + 4 * b + 2] + \
                          src[20 + 4 * (b + 1):]
                    train_encoder_input.append(src)
                    train_encoder_target.append(tgt)

        return train_encoder_input, train_encoder_target, valid_encoder_input, valid_encoder_target

    def process_arch(self, arch):
        if self.args.search_space == 'nasbench':
            matrix, ops = nao_nasbench_utils.parse_arch_to_model_spec_matrix_op(arch, self.args.child_nodes)
            model_spec = ModelSpec_v2(matrix, ops)
            return model_spec
        else:
            return arch

    def process_arch_to_seq(self, old_archs):
        if self.args.search_space =='nasbench':
            encoder_input =list(map(lambda x: self.utils.parse_arch_to_seq(x, 2, self.args.child_nodes), old_archs))
        else:
            encoder_input = list(
                map(lambda x: self.utils.parse_arch_to_seq(x[0], 2) + self.utils.parse_arch_to_seq(x[1], 2), old_archs))

        return encoder_input

    def process_seq_to_arch(self, old_archs):
        if self.args.search_space =='nasbench':
            encoder_input =list(map(lambda x: self.utils.parse_seq_to_arch(x, 2, self.args.child_nodes), old_archs))
        else:
            encoder_input = list(
                map(lambda x: self.utils.parse_seq_to_arch(x[0], 2) + self.utils.parse_seq_to_arch(x[1], 2), old_archs))

        return encoder_input

    def process_archname(self, arch):
        if self.args.search_space == 'nasbench':
            return ' '.join(map(str, arch))
        else:
            return ' '.join(map(str, arch[0] + arch[1]))

    def generate_new_arch(self, num_new):
        num_ops = 3 if self.args.search_space == 'nasbench' else 5
        child_arch_pool = self.utils.generate_arch(num_new, self.args.child_nodes, num_ops)
        return child_arch_pool

    def evaluate(self, epoch, data_source, arch_pool=None, fitnesses_dict=None, train_queue=None, criterion=None):
        """
        Full evaluation of all possible models.
        :param epoch:
        :param data_source:
        :param fitnesses_dict: Store the model_spec_id -> accuracy
        :return:
        """

        fitnesses_dict = fitnesses_dict or {}
        total_avg_acc = 0
        total_avg_obj = 0

        # rank dict for the possible solutions
        model_specs_rank = {}
        model_specs_rank_before = {}
        queries = {}
        # as backup
        ind = 0
        eval_result = {}
        # let us sample 200 architecture to evaluate. # just keep the top K.
        clean_arch_pool = self.clean_arch_pool(arch_pool)[:self.top_K_complete_evaluate]

        while ind < len(clean_arch_pool):
            # get this id
            if self.args.debug and ind > 10:
                break

            arch = clean_arch_pool[ind]
            new_model_spec = self.process_arch(clean_arch_pool[ind])
            ind += 1  # increment this.
            try:
                model_spec_id = self.nasbench_hashs.index(new_model_spec.hash_spec())
            except Exception as e:
                logging.error(e)
                continue

            query = {'test accuracy':self.search_space.nasbench.perf_rank[model_spec_id]}

            # selecting the current subDAG in our DAG to train
            change_model_spec(self.parallel_model, new_model_spec)
            # Reset the weights.
            # evaluate before train
            self.logger.info('evaluate the model spec id: {}'.format(model_spec_id))
            _avg_val_acc, _avg_val_acc5, _avg_val_obj = self.child_test(data_source, self.parallel_model, arch, criterion=criterion)
            eval_result[model_spec_id] = _avg_val_acc, _avg_val_obj

            logging.info("Query: {}".format(query))
            # update the total loss.
            total_avg_acc += _avg_val_acc
            total_avg_obj += _avg_val_obj

            # saving the particle fit in our dictionaries
            fitnesses_dict[model_spec_id] = _avg_val_acc
            ms_hash = self.nasbench_hashs[model_spec_id]
            model_specs_rank[ms_hash] = Rank(_avg_val_acc, _avg_val_obj, model_spec_id,
                                              self.search_space.rank_by_mid[model_spec_id])
            queries[ms_hash] = query
            gc.collect()

        # save the ranking, according to their GENOTYPE but not particle id
        rank_gens = sorted(model_specs_rank.items(), key=operator.itemgetter(1))

        self.ranking_per_epoch[epoch] = rank_gens
        self.eval_result[epoch] = eval_result
        # IPython.embed(header="Check evaluation result")

        self.logger.info('VALIDATION RANKING OF PARTICLES')
        for pos, elem in enumerate(rank_gens):
            self.logger.info(f'particle gen id: {elem[1].geno_id}, acc: {elem[1].valid_acc}, obj {elem[1].valid_obj}, '
                             f'hash: {elem[0]}, pos {pos}')

        if self.writer:
            # process data into list.
            accs_after, objs_after = zip(*eval_result.values())
            tensorboard_summarize_list(accs_after, writer=self.writer, key='neweval_after/acc', step=epoch, ascending=False)
            tensorboard_summarize_list(objs_after, writer=self.writer, key='neweval_after/obj', step=epoch)

        return fitnesses_dict

    def process_nasbench(self):
        super(NAONasBenchSearch, self).process_nasbench(only_hash=False)

    def child_test(self, test_queue, model, arch, criterion, verbose=True):
        utils = self.utils
        objs = search_policies.cnn.utils.AverageMeter()
        top1 = search_policies.cnn.utils.AverageMeter()
        top5 = search_policies.cnn.utils.AverageMeter()
        model.eval()
        # arch_l = arch
        arch = self.process_arch(arch)
        with torch.no_grad():
            for step, (input, target) in enumerate(test_queue):
                if self.args.debug:
                    if step > 10:
                        print("Break after 10 batch")
                        break
                input = input.cuda()
                target = target.cuda()
                logits, _ = model(input, arch, bn_train=False)
                loss = criterion(logits, target)

                prec1, prec5 = utils.accuracy(logits, target, topk=(1, 5))
                n = input.size(0)
                objs.update(loss.item(), n)
                top1.update(prec1.item(), n)
                top5.update(prec5.item(), n)

                if step % self.args.report_freq == 0 and step > 0 and verbose:
                    logging.info('test | step %03d | loss %e | acc %f | acc-5 %f', step, objs.avg, top1.avg,
                                 top5.avg)

        return top1.avg, top5.avg, objs.avg

    def clean_arch_pool(self, arch_pool):
        new_arch_pool = []
        for i in arch_pool:
            if not i in new_arch_pool:
                new_arch_pool.append(i)

        return new_arch_pool

class NAONasBenchGroundTruthPolicy(NAONasBenchSearch):

    def child_train(self, train_queue, model, optimizer, global_step, arch_pool, arch_pool_prob, criterion):
        utils = self.utils
        model.train()
        for step, (input, target) in enumerate(train_queue):
            if self.args.debug:
                if step > 10:
                    print("Break after 10 batch")
                    break

            # sample an arch to train
            arch = utils.sample_arch(arch_pool, arch_pool_prob)
            global_step += 1
            arch_l = arch
            try:
                arch = self.process_arch(arch_l)
                r = self.search_space.nasbench.hash_rank.index(arch.hash_spec())
            except ValueError as e:
                continue

            global_step += 1

        return .0, .0, global_step

    def child_test(self, test_queue, model, arch, criterion, verbose=True):
        try:
            if not hasattr(arch, 'hash_spec'):
                arch = self.process_arch(arch)
            r = self.search_space.nasbench.hash_rank.index(arch.hash_spec())
        except ValueError as e:
            return 0., 0., 0.
        valid_acc = self.search_space.nasbench.perf_rank[r][0]
        return valid_acc, 0., 0.

    def child_valid(self, valid_queue, model, arch_pool, criterion):
        valid_acc_list = []

        for i, arch in enumerate(arch_pool):
            # for step, (inputs, targets) in enumerate(valid_queue):
            arch_l = arch
            arch = self.process_arch(arch)
            try:
                r = self.search_space.nasbench.hash_rank.index(arch.hash_spec())
                valid_acc = self.search_space.nasbench.perf_rank[r][0]
                valid_acc_list.append(valid_acc)
            except ValueError as e:
                valid_acc_list.append(0.)

        return valid_acc_list


text:
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec

colorings = []
for i, (name, hex) in enumerate(matplotlib.colors.cnames.items()):
    colorings.append(np.array(tuple(int(hex.lstrip("#")[i:i + 2], 16) for i in (0, 2, 4))) / 255.0)
colorings = np.array(colorings)
colorings = colorings[np.argsort(colorings.sum(1))][:-30][::5]

def visualize_temporal_clustering(tclust, **kwargs):
    fig = plt.figure(figsize=(7.5, 1.5))
    gs = GridSpec(1, 1, height_ratios=[1.])
    ax = fig.add_subplot(gs[0, 0])
    ax.imshow(colorings[tclust][None, :, :], interpolation="nearest", aspect="auto")
    ax.set_xticklabels([])
    ax.set_xticks([])
    ax.set_yticks([])
    ax.set_title("Visualization of Temporal Clustering")
    plt.tight_layout()
    #     plt.savefig(kwargs['checkpoint_path'] + 'viz_temp_clsts' + kwargs['extension'] + '.png', type='png')
    plt.show()

def visualize_temporal_clusterings(gt, pred, **kwargs):
    print (list(zip(gt, pred)))
    fig = plt.figure(figsize=(7.5, 1.5))
    gs = GridSpec(2, 1, height_ratios=[.5, .5])
    ax = fig.add_subplot(gs[0, 0])
    ax.imshow(colorings[gt][None, :, :], interpolation="nearest",aspect="auto")
    ax.set_xticklabels([])
    ax.set_xticks([])
    ax.set_yticks([])
    ax.set_title("Ground Truth Temporal Clustering")

    ax = fig.add_subplot(gs[1, 0])
    ax.imshow(colorings[pred][None, :, :],interpolation="nearest", aspect="auto")
    ax.set_xticklabels([])
    ax.set_xticks([])
    ax.set_yticks([])
    ax.set_title("Proposed Temporal Clustering")

    plt.tight_layout()
    plt.savefig(kwargs['log'] + 'viz_temp_clsts' + kwargs['extension'] + '.png', type='png')
    plt.close()
    # plt.show()

def visualize_many_temporal_clusterings(gt_list, pred_list, multiple_time_series=True, labels=None, **kwargs):
    assert (len(gt_list) == len(pred_list))
    num_seqs = len(gt_list)
    # if multiple_time_series and num_seqs == 2:
    #     grid_spec_factor = 3
    if multiple_time_series:# and num_seqs != 2:
        grid_spec_factor = 2 * num_seqs
    elif not multiple_time_series:
        grid_spec_factor = num_seqs + 1
    fig = plt.figure(figsize=(7.5, 0.65 * grid_spec_factor))
    gs = GridSpec(grid_spec_factor, 1, height_ratios=[1. / grid_spec_factor] * (grid_spec_factor))

    for i, (gt, pred) in enumerate(zip(gt_list, pred_list)):
        if (multiple_time_series) or (
            not multiple_time_series and i == 0):
            ax = fig.add_subplot(gs[2 * i, 0])
            ax.imshow(colorings[gt][None, :, :], interpolation="nearest", aspect="auto")
            ax.set_xticklabels([])
            ax.set_xticks([])
            ax.set_yticks([])
            if multiple_time_series:
                ax.set_title("Ground Truth Temporal Clustering (Sequence %d)" % (i + 1), fontsize=14)
            else:
                ax.set_title("Ground Truth Temporal Clustering", fontsize=14)

        if multiple_time_series:
            ax = fig.add_subplot(gs[2 * i + 1, 0])
        else:
            ax = fig.add_subplot(gs[i + 1, 0])
        ax.imshow(colorings[pred][None, :, :], interpolation="nearest", aspect="auto")
        ax.set_xticklabels([])
        ax.set_xticks([])
        ax.set_yticks([])
        if multiple_time_series:
            ax.set_title("Proposed Temporal Clustering (Sequence %d)" % (i + 1), fontsize=14)
        else:
            if labels is None:
                ax.set_title("Proposed Temporal Clustering", fontsize=14)
            else:
                ax.set_title("Proposed Temporal Clustering (%s)" % (labels[i]), fontsize=14)

    plt.tight_layout()
    plt.savefig(kwargs['log'] + '_viz' + kwargs['extension'] + '.png', type='png')
    plt.close()
    # plt.show()


text:
# Dimensionamento de seções retangulares à Torção combinada com Flexão e Esforço Cortante
#
# Chamar biblioteca matemática
import numpy as np
# Inserir sub-rotina tensão
def tensao(esl):
    #'
    #'Calcula a tensao no aço
    #'es = módulo de elasticidade do aço em kN/cm2
    #'esl = deformação de entrada
    #'fyd = tensão de escoamento de cálculo em kN/cm2
    #'tsl = tensão de saída em kN/cm2
    #'
    #'Trabalhando com deformação positiva
    ess = np.abs(esl)
    eyd = fyd / es
    if (ess < eyd):
        tsl = es * ess
    else:
        tsl = fyd
    #'Trocando o sinal se necessário
    if (esl < 0):
        tsl = -tsl
    return tsl
# ENTRADA DE DADOS
#
fck = float(input('Resistência característica à compressão do concreto em MPa = '))
fyk = float(input('Tensão de escoamento característica do aço em MPa = '))
es = float(input('Módulo de elasticidade do aço em GPa = '))
gamac = float(input('Coeficiente parcial de segurança para o concreto = '))
gamas = float(input('Coeficiente parcial de segurança para o aço = '))
gamaf = float(input('Coeficiente parcial de segurança para o para o momento fletor = '))
bduct = float(input('Coeficiente beta de redistribuição de momentos = '))
b = float(input('Largura da seção transversal em cm = '))
h = float(input('Altura da seção transversal em cm = '))
dl = float(input("Distância d' em cm = "))
amk = float(input('Momento fletor de serviço em kNm = '))
vk = float(input('Esforço cortante de serviço em kN = '))
tk = float(input('Momento torsor de serviço em kNm = '))
#
# FIM DA ENTRADA DE DADOS
#
# INÍCIO DOS CÁLCULOS
#
# Parâmetros do diagrama retangular
if fck <= 50:
    alamb = 0.8
    alfac = 0.85
    eu = 3.5
    qlim = 0.8 * bduct - 0.35
else:
    alamb = 0.8 - (fck - 50) / 400
    alfac = 0.85 * (1 - (fck - 50) / 200)
    eu = 2.6 + 35 * ((90 - fck) / 100) ** 4
    qlim = 0.8 * bduct - 0.45
# Conversão de unidades: transformando para kN e cm
amk = 100 * amk
tk = 100 * tk
es = 100 * es
# Conversão de unidades: transformando para kN e cm
fck = fck / 10
fyk = fyk / 10
# Resistências de cálculo
fcd = fck / gamac
tcd = alfac * fcd
fyd = fyk / gamas
# Esforços solicitantes de cálculo
amd = gamaf * amk
vd = gamaf * vk
td = gamaf * tk
# Altura útil
d = h - dl
# Parâmetro geométrico
delta = dl / d
#
# Dimensionamento à Flexão Simples
#
# Momento limite
amilim = alamb * qlim * (1 - 0.5 * alamb * qlim)
# Momento reduzido solicitante
ami = amd / (b * d * d * tcd)
#
if (ami <= amilim):
    # Armadura simples
    qsi = (1 - np.sqrt(1 - 2 * ami)) / alamb
    aas = alamb * qsi * b * d * tcd / fyd
    asl = 0
else:
    # Armadura dupla
    #
    # Evitando armadura dupla no domínio 2
    qsia = eu / (eu + 10)
    if (qlim < qsia):
        #'
        #'Está resultando armadura dupla no domínio 2.
        #'Colocar mensagem para o usuário aumentar as dimensões da seção transversal e parar o processamento
        #'
        print('Resultou armadura dupla no domínio 2.')
        print('Aumente as dimensões da seção transversal.')
        #
        # Eliminando o caso em que qlim<delta
        # Se isto ocorrer, a armadura de compressão estará tracionada
        #            '
    if (qlim <= delta):
        #'
        #'Colocar mensagem para o usuário aumentar as dimensões da seção transversal e parar o processamento
        #'
        print('Aumente as dimensões da seção transversal.')
    #'
    #'Deformação da armadura de compressão
    esl = eu * (qlim - delta) / qlim
    esl = esl / 1000
    #'Tensão na armadura de compressão
    #'Chamar sub-rotina
    tsl = tensao(es, esl, fyd)
    asl = (ami - amilim) * b * d * tcd / ((1 - delta) * tsl)
    aas = (alamb * qlim + (ami - amilim) / (1 - delta)) * b * d * tcd / fyd
#'
#'Armadura mínima
a = 2 / 3
fyd = 10 * fyd
if (fck <= 50):
    romin = 0.078 * (fck ** a) / fyd
else:
    romin = 0.5512 * np.log(1 + 0.11 * fck) / fyd
if (romin < 0.0015):
    romin = 0.0015
#        '
asmin = romin * b * h
if (aas < asmin):
    aas = asmin
#'
#'Dimensionamento ao Esforço Cortante e Torção
#'
#'Verificação do esmagamento das bielas considerando a superposição das tensões
#'
#'Parcela devida ao esforço cortante
bw = b
#'Tensão convencional de cisalhamento
twd = vd / (bw * d)
#'Passando para MPa
twd = 10 * twd
#'Tensão de cisalhamento última
fcd = 10 * fcd
av = 1 - fck / 250
twu = 0.27 * av * fcd
#'
#'Parcela devida ao momento torçor
#'
#'Parâmetros da seção vazada equivalente
#'Ver Capítulo 1 do Volume 4 de Curso de Concreto Armado
#'Com referência às Figuras 1.2.1 e 1.2.2
#'t0=espessura da parede da seção vazada
#'ae=área limitada pela linha média
#'up=perímetro da linha média
#'
c1 = dl
t0 = b * h / (2 * (b + h))
if (t0 >= 2 * c1):
    #'  Caso 1: Fig.1.2.1
    t = t0
    ae = (b - t) * (h - t)
    up = 2 * (b + h - 2 * t)
else:
    #'  Caso 2: Fig.1.2.2
    t = t0
    tmax = b - 2 * c1
    if (t > tmax):
        t = tmax
    ae = (b - 2 * c1) * (h - 2 * c1)
    up = 2 * (b + h - 4 * c1)
#'Tensão convencional de cisalhamento
ttd = td / (2 * ae * t)
#'Passando para MPa
ttd = 10 * ttd
#'Tensão de cisalhamento última
ttu = 0.25 * av * fcd
#'
#'Combinação das tensões e verificação
soma = ttd / ttu + twd / twu
if (soma > 1):
    print('Esmagamento da biela de compressão.')
    print('Aumente as dimensões da seção transversal.')
#'
#'Espaçamento máximo dos estribos
#'
if (soma <= 0.67):
    smax = 0.6 * d
    if (smax > 30):
        smax = 30
    else:
        smax = 0.3 * d
    if (smax > 20):
        smax = 20
#'
#'Dimensionamento das armaduras para o esforço cortante
#
#'Tensão Talc de redução da armadura
#'Se gamac=1.4 irão resultar as expressões (7.4.6) e (7.4.7) do Volume 1 de Curso de Concreto Armado
#'
if (fck <= 50):
    a = 2 / 3
    tc = 0.126 * (fck ^ a) / gamac
else:
    tc = 0.8904 * np.log(1 + 0.11 * fck) / gamac
#'
#'Tensão Tald para cálculo da armadura
#'
tald = 1.11 * (twd - tc)
if (tald < 0):
    tald = 0
#'
#'Limitação da tensão de escoamento do aço conforme a NBR-6118
#'
if (fyd > 435):
    fyd = 435
#'
#'Cálculo da armadura
aswv = 100 * bw * tald / fyd
#'
#'Dimensionamento das armaduras para o momento torçor
#'
fyd = fyd / 10
aswt = 100 * td / (2 * ae * fyd)
aslt = td * up / (2 * ae * fyd)
#'
#'Cálculo da armadura mínima:
#'A tensão fyk deve ser menor ou igual a 500 MPa
fykmax = fyk
if (fykmax > 500):
    fykmax = 500
#'
#'Resistência média à tração do concreto
#'
if (fck <= 50):
    a = 2 / 3
    fctm = 0.3 * (fck ** a)
else:
    fctm = 2.12 * np.log(1 + 0.11 * fck)
#'
#'Taxa mínima de armadura (ver equação (1.4.5) do Volume 4)
rowmin = 0.2 * fctm / fykmax
#'
#'Superposição dos estribos
asw = aswv + 2 * aswt
aswmin = rowmin * 100 * bw
if (asw < aswmin):
    asw = aswmin
#'
#'Armadura longitudinal mínima da torção
#'
aslmin = 0.5 * rowmin * up * bw
if (aslt < aslmin):
    aslt = aslmin
#'
#'Convertendo as saída para duas casas decimais
aswv = round(aswv, 3)
aswt = round(aswt, 3)
asw = round(asw, 3)
aas = round(aas, 3)
asl = round(asl, 3)
aslt = round(aslt, 3)
#'Convertendo o espaçamento máximo dos estribos para
#'uma casa decimal
smax = round(smax, 0)
#'
#'Mostrando os resultados nas caixas de texto
#'
print('A área de armadura transversal devido o esforço cortante é',aswv,'cm²/m.')
print('A área de armadura transversal devido ao momento torsor é',aswt,'cm²/m.')
print('A área de armadura transversal é',asw,'cm²/m.')
print('O espaçamento máximo é de',smax,'cm.')
print('A área de armadura longitudinal é',aas,'cm².')
print('A área de armadura longitudinal devido ao momento fletor é',asl,'cm².')
print('A área de armadura longitudinal devido ao momento torsor é',aslt,'cm².')

max_stars_repo_name: mwmoura/Concreto-armado

max_issues_repo_name: mwmoura/Concreto-armado

max_forks_repo_name: mwmoura/Concreto-armado


text:
#!/usr/bin/env python
# coding=utf-8
from __future__ import division
import numpy as np
import copy
import math
import _tips

KKWModel = [
    {'k':2.55, 'vp':14.0, 'pa1':0.2},
    {'p':0.04, 'pa2':0.052},
    {'p':0.055, 'pa2':0.085},
    {'p':0.04, 'pa':0.052, 'beta':0.05},
    {'p':0.04, 'beta':0.0},
    {'d1':2.5, 'k':2.55, 'p':0.04, 'pa':0.052}
]

#不作为类,用作为结构体,记录车的各种参数
class Car(object):
    def __init__(self):
        self.name = 'default'               #车类名称,用于统计
        self.length = 1.0                   #车身长度
        self.safedistance = 0.0             #最小车距
        self.slowacc = 0.5                  #慢加速度/s
        self.acc = 1.0                      #加速度/s
        self.negacc = 1.0                   #减速度/s
        self.view = 0                       #司机视野距离
        self.speed = 0.0                    #当前速度
        self.locate = 0.0                   #当前所在位置
        self.lane = 0                       #当前所在车道
        self.height = 0.0                   #汽车高度,暂时没用
        self.bn = False                     #刹车灯
        self.tst = 0                        #敏感时间
        self.stoped = False                 #上一个时刻受到了阻挡后刹车的标记
        self.changeflag = False

class Road(object):
    'Road && Cars'

    def __init__(self, carbox, vmax, length, lanes=1,
                 entercars=0, enterflag=False, connectroad=None, exitflag=False, roadname='default'):
        self.carbox = carbox                    #道路上所有车辆及其具体状态和参数
        self.entercars = entercars              #已进入此路的车辆数
        self.leavecars = np.zeros(lanes)        #离开此路的车辆数
        self.vmax = float(vmax)                 #道路最大车速
        self.length = float(length)             #道路长度
        self.lanes = int(lanes)                 #车道数,默认为单车道
        self.endcars = np.array([])             #list的长度表示有多少车辆需要进入其他道路,键值为其速度
        self.enterflag = enterflag              #标记此道是否是入口
        self.exitflag = exitflag                #标记此道是否是出口

        self.changeswitch = False               #是否打开换道功能
        self.alpha = 0.6                        #减速概率的alpha因子,不能随意修改,除非你知道自己在干什么
        self.beta = 0.2                         #减速概率的beta因子,同上
        self.autoAdderSwitch = False            #是否自动添加车辆
        self.autoAdderByTime = False            #是否按时间自动添加车辆,与前一个Flag冲突
        self.autoAdderBox = None                #自动添加车辆的初始速度
        self.connectroad = connectroad          #连接的公路(入口),默认值为空
        self.autoAddTime = 0                    #用户定义的自动添加车辆的时间间隔
        self.timeCounter = 0                    #系统内部用于自动添加车辆的时间计数器
        self.wholeTime = 0                      #总的运行时间
        self.stableP = 0.4                      #固定减速因子,一旦设定,那么alpha和beta就会失效
        self.waitLine = []                      #等待添加的车辆列队
        self.pers = None
        self.roadname = roadname
    def __iter__(self):
        self.iterindex = -1
        return self

    def next(self):
        self.iterindex += 1
        if self.iterindex >= self.lanes:
            raise StopIteration
        return self.carbox[self.iterindex]

    def shape(self):
        output = []
        for lane in self.carbox:
            output.append(len(lane))
        return output

    def __len__(self):
        output = 0
        for lane in self.carbox:
            output += len(lane)
        return output

    #标记线内的为public func
    #-----------------------------------------------------
    def get_cars_locate(self):
        output = []
        for lane in self.carbox:
            output.append(np.array([car.locate for car in lane]))
        return output

    def get_cars_v(self):
        output = []
        for lane in self.carbox:
            output.append(np.array([car.speed for car in lane]))
        return output

    def get_mean_speed(self):
        carsvbox = self.get_cars_v()
        output = np.array([])
        counter = 0
        adder = 0.0
        for lane in carsvbox:
            if lane.size != 0:
                value = lane.mean()
                counter += 1
                output = np.append(output, value)
                adder += value
            else:
                output = np.append(output, -1)
        if counter != 0:
            whole = adder/counter
        else:
            whole = None
        return output, whole

    def __view_cars(self, car, viewBox, offset=0.0):
        tempLocate = np.array([])
        for locate in viewBox:
            tempLocate = np.append(tempLocate, locate.speed)
        temp = car.locate + car.view - tempLocate - offset
        temp = temp[temp >= 0]
        return temp.size

    #考虑视野距离计算实时随机减速概率
    def __pcounter(self, carsNum, car):
        A = (float(carsNum)/car.view)**self.alpha
        B = (car.speed/self.vmax)**self.beta
        return A*B

    def set_alpha_beta(self, alpha, beta):
        self.alpha = alpha
        self.beta = beta

    def set_stabel_p(self, p):
        self.stableP = p

    def get_cars(self):
        return self.carbox

    def get_road_lanes(self):
        return self.lanes

    def get_road_length(self):
        return self.length

    def get_road_vmax(self):
        return self.vmax

    def get_leave_cars(self):
        return self.leavecars

    def get_exec_time(self):
        return self.wholeTime

    def get_cars_num(self):
        output = np.zeros(self.lanes)
        for i in xrange(self.lanes):
            output[i] = len(self.carbox[i])
        return output

    #=====================模型=========================

    #慢启动规则
    def __TT(self, car, nextCar, pt):
        if car.speed == 0:
            if nextCar != None:
                if (car.length + nextCar.length)/2 +car.safedistance < nextCar.locate - car.locate \
                     <= (car.length + nextCar.length) + car.safedistance*2:
                    return 1.0 - pt
            else:
                return None
        else:
            return None

    def __BJH(self, flag, ps):
        if flag:
            return 1.0 - ps
        else:
            return 0

    def __VDR(self, flag, p0):
        if flag == False:
            return self.stableP
        else:
            return p0

    #减速规则
    def __VE(self, car, nextCar, next2Car):
        dn = (car.length + nextCar.length)/2 + car.safedistance
        dnc = (nextCar.length + next2Car.length)/2 + nextCar.safedistance
        vc = min(self.vmax - car.acc, nextCar.speed, max(0, dnc - nextCar.acc))
        car.speed = min(car.speed + car.acc, dn + vc)

class ExecRoad(Road):
    def __init__(self, carbox, vmax, length, lanes=1,
                 entercars=0, enterflag=False, connectroad=None, exitflag=False, roadname='default'):
        super(ExecRoad, self).__init__(carbox, vmax, length, lanes, \
                entercars, enterflag, connectroad, exitflag, roadname)

        self.set_MCD_para()
        self.execRule = self.__NS

        self.TTFlag = False
        self.TTPt = 0

        self.BJHFlag = False
        self.BJHPs = 0
        self.BJHflag = False

        self.VDRFlag = False
        self.VDRP0 = 0

        self.VEFlag = False
        self.insertpostion = 0.0
        self.nextlanemethod = 'simple'

        self.headcountflag = True
        self.headfont = [0]*self.lanes
        self.head = []
        for i in xrange(self.lanes):
            self.head.append([])

    def __str__(self):
        if self.connectroad != None:
            crid = str(hex(id(self.connectroad)))
        else:
            crid = str(None)
        des =   '+===================+\n' + \
                ' - 运行规则及道路HashValue：' + str(self.execRule)  + \
                '\n - 车道数:'+str(self.lanes) + \
                ' - 道路长度(m):'+str(self.length) + \
                ' - 运行时间(s):'+str(self.wholeTime) + \
                ' - 是否为入口:'+str(self.enterflag) + \
                ' - 是否为出口:'+str(self.exitflag)

        carsCounter = []
        des += '\n --------------------'
        meanspeed, whole = self.get_mean_speed()
        if whole != None:
            whole = round(whole, 3)
        for index, lane in enumerate(self.carbox):
            if meanspeed[index] != -1:
                v = round(meanspeed[index], 3)
            else:
                v = None
            carsCounter.append(len(lane))
            des +=  '\n'+' - 车道_'+str(index) + \
                    ' - 车辆数目' +':'+str(len(lane)) + \
                    ' - 平均车速：' + str(v) + \
                    ' - 已通过车辆数：' + str(self.leavecars[index])

        des +=  '\n'+' -  整体  - 车辆数目:'+str(sum(carsCounter)) + \
                ' - 平均车速：' + str(whole) + \
                ' - 已通过车辆数：' + str(sum(self.leavecars)) + \
                '\n --------------------' + \
                '\n - 连接道路：' + crid + \
                ' - 时间边界条件：' + str(self.autoAdderByTime) + \
                ' - 循环边界条件：' + str(self.autoAdderSwitch) + \
                '\n+===================+\n'
        return des

    def set_exec_rule(self, rule):
        if rule == '__NS':
            self.execRule = self.__NS
        elif rule == '__CD':
            self.execRule = self.__CD
        elif rule == '__MCD':
            self.execRule = self.__MCD
        elif rule == '__KKW':
            self.execRule = self.__KKW
        else:
            raise KeyError('No that exec rule')

    def get_head_t(self):
        return self.head

    def set_MCD_para(self, h=6, gap=7, pb=0.94, p0=0.5, \
                    pd=0.1, tc=10):
        self.h = h
        self.gap = gap
        self.pb = pb
        self.p0 = p0
        self.pd = pd
        self.tc = tc

    def set_TT(self, switch, TTPt=0.75):
        self.TTFlag = switch
        if switch == True:
            self.TTPt = TTPt

    def set_BJH(self, switch, BJHPs=0.75):
        self.BJHFlag = switch
        if switch == True:
            self.BJHPS = BJHPs

    def set_VDR(self, switch, VDRP0=0.75):
        self.VDRFlag = switch
        if switch == True:
            self.VDRP0 = VDRP0

    def set_VE(self, switch):
        self.VEFlag = switch

    #最基础的__NS模型
    def __NS(self, car, nextCar, para):
        #step1:加速
        if self.TTFlag is True:
            tempP = self.__TT(car, nextCar, self.TTPt)
            if tempP == None or np.random.random() < tempP:
                car.speed = min(car.speed + car.acc, self.vmax)

        else:
            car.speed = min(car.speed + car.acc, self.vmax)

        if self.BJHFlag is True:
            tempP = self.__BJH(car.stoped, self.BJHPs)
            if np.random.random() < tempP:
                car.speed = 0
        if self.BJHFlag or self.VDRFlag:
            car.stoped = False

        #step2:减速
        if nextCar != None:
            dn = (car.length+nextCar.length)/2 + car.safedistance
            distance = nextCar.locate - car.locate
        else:
            dn = 0.0
            distance = car.speed*2

        if car.speed + dn >= distance:
            d = max(0, distance - dn)
            car.speed = min(car.speed, d)
            if (self.VDRFlag or self.BJHFlag) and car.speed == 0:
                car.stoped = True

        #step3:随机慢化
        if self.VDRFlag is True:
            tempP = self.__VDR(car.stoped, self.VDRP0)
            if np.random.random() < tempP:
                car.speed = max(car.speed - car.negacc, 0)
        elif np.random.random() < self.stableP:
            car.speed = max(car.speed - car.negacc, 0)

        #step4:运动
        return car.speed

    #舒适驾驶模型
    def __CD(self, car, nextCar, next2Car):
        ts = min(car.speed, self.h)
        if nextCar != None:
            nextCarbn = nextCar.bn
            dn = nextCar.locate - car.locate - (car.length + nextCar.length)/2 - car.safedistance
        else:
            nextCarbn = 0
            dn = ts*car.speed + 1
        if car.speed != 0:
            th = dn/car.speed
        else:
            th = ts + 1
        #step1:确定随机慢化概率p
        if nextCarbn == 1 and th < ts:
            p = self.pb
        elif car.speed == 0:
            p = self.p0
        else:
            p = self.pd
        nextbn = 0
        #step2:加速
        if (nextCarbn == 0 and car.bn == 0) or (th >= ts):
            nextv = min(car.speed + car.acc, self.vmax)
        else:
            nextv = car.speed
        #step3:减速
        if nextCar == None:
            deff = nextv + 1
        else:
            if next2Car == None:
                dnc = nextCar.speed + 1
            else:
                dnc = next2Car.locate - nextCar.locate - (nextCar.length + next2Car.length)/2 \
                     - nextCar.safedistance
            vanti = min(dnc, nextCar.speed)
            deff = max(dn + max(vanti - self.gap, 0), 0)

        nextv = min(deff, nextv)
        if nextv < car.speed:
            nextbn = 1
        #step4:慢化
        if np.random.random() <= p:
            nextv = max(nextv - car.negacc, 0)
            if p == self.pb:
                nextbn = 1
        #step5:更新速度
        return nextv

    #改进的__CD模型
    def __MCD(self, car, nextCar, next2Car):
        ts = min(car.speed, self.h)
        if nextCar != None:
            nextCarbn = nextCar.bn
            dn = nextCar.locate - car.locate - (car.length + nextCar.length)/2 - car.safedistance
        else:
            nextCarbn = 0
            dn = ts*car.speed + 1
        if car.speed != 0:
            th = dn/car.speed
        else:
            th = ts + 1

        #step1:确定随机慢化概率
        if nextCarbn == 1 and th < ts:
            p = self.pb
        elif car.speed == 0 and car.tst >= self.tc:
            p = self.p0
        else:
            p = self.pd

        #step2:加速
        if (nextCarbn == 0 or th >= ts) and car.speed > 0:
            nextv = min(car.speed + car.acc, self.vmax)
        elif car.speed == 0:
            nextv = min(car.speed + car.slowacc, self.vmax)
        else:
            nextv = car.speed

        #step3:减速
        if nextCar == None:
            deff = nextv + 1
        else:
            if next2Car == None:
                dnc = nextCar.speed + 1
            else:
                dnc = next2Car.locate - nextCar.locate - (nextCar.length + next2Car.length)/2 \
                - nextCar.safedistance
            vanti = min(dnc, nextCar.speed)
            deff = max(dn + max(vanti - self.gap, 0), 0)

        nextv = min(deff, nextv)

        #step4:慢化
        if np.random.random() <= p:
            nextv = max(nextv - car.negacc, 0)

        #step5:确定刹车灯状态bnc
        if nextv < car.speed:
            nextbn = 1
        elif nextv > car.speed:
            nextbn = 0
        else:
            nextbn = car.bn

        #step6:确定tst
        if nextv > 0:
            car.tst = 0
        else:
            car.tst += 1

        #step7:位置更新
        return nextv

    def __KKW(self, car, nextCar, para, model = KKWModel):
        #参数确定
        #paras needs:vfree,d,p0
        dn = (car.length + nextCar.length)/2 + car.safedistance
        gn = nextCar.locate - car.locate - dn

        #request paras:k,p0,p,pa1,pa2,vp
        if self.modelKind == 1:
            D = model['d'] + model['k']*car.speed*tao
            if car.speed > 0:
                pb = model['p']
            else:
                pb = model['p0']

            if car.speed < vp:
                pa = model['pa1']
            else:
                pa = model['pa2']

        #request paras:beta,p0
        elif self.modelKind == 2:
            D = model['d'] + car.speed*tao + model['beta']\
                *np.power(car.speed, 2)/(car.acc*2)
            if car.speed > 0:
                pb = model['p']
            else:
                pb = model['p0']

        #request paras:pa=0,beta,p0,p
        elif self.modelKind == 3:
            D = model['d'] + car.speed*tao + model['beta']\
                    *np.power(car.speed, 2)/(car.acc<<1)
            if 0 < car.speed < model['vfree']:
                pb = model['p']
            elif car.speed == 0:
                pb = model['p0']
            elif car.speed == model['vfree']:
                pb = 0

        #request paras:d1<d,k,p0,p,pa
        elif self.modelKind == 4:
            D = model['d1'] + model['k']*car.speed*tao
            if car.speed > 0:
                pb = model['p']
            else:
                pb = model['p0']
        else:
            raise KeyError(tips.INFO('Unkonw modelKind', 'RED'))

        vsafe = gn/self.tao

        #随机过程
        if gn > D - dn:
            vdes = car.speed + car.acc*self.tao
        else:
            vdes = car.speed + car.acc*self.tao*np.sign(nextCar.speed - car.speed)

        vc = max(0, min(vfree, vsafe, vdes))

        #确定过程
        rand = np.random.random()
        if rand < pb:
            era = -1
        elif pb <= rand < pb + pa:
            era = 1
        else:
            era = 0
        car.speed = max(0, min(vc + car.acc*tao*era, vc + car.acc*tao, vfree, vsafe))

        return car.speed

    def reflush_status(self):
        self.__timer()
        # 换道
        if self.changeswitch is True:
            changebox = []
            for lane in self.carbox:
                it = iter(lane)
                while True:
                    try:
                        opcar = next(it)
                        try:
                            nextCar = next(it)
                        except StopIteration:
                            nextCar = None
                        if self.__change_lane(opcar, nextCar) is True:
                            changebox.append(opcar)
                    except StopIteration:
                        break

            for car in changebox:
                car.changeflag = False

        # 并行更新
        for lane in xrange(0, self.lanes):
            tempVSaver = []
            tempLocateSaver = []
            if len(self.carbox[lane]) == 0:
                continue
            if len(self.carbox[lane]) >= 2:
                for i in xrange(0, len(self.carbox[lane]) - 1):
                    opcar = self.carbox[lane][i]
                    opcar.lane = lane
                    nextCar = self.carbox[lane][i+1]
                    try:
                        next2Car = self.carbox[lane][i+2]
                    except:
                        next2Car = None
                    speed = self.execRule(opcar, nextCar, next2Car)
                    tempVSaver.append(speed)
                    tempLocateSaver.append(opcar.locate + speed)
            #最前的车单独计算
            opcar = self.carbox[lane][-1]
            opcar.lane = lane
            nextCar = None
            next2Car = None

            # 连接处的前方车辆判断
            if self.connectroad != None:
                oplane = self.__get_next_enter_lane(opcar.lane)
                info = self.connectroad.get_cars()[oplane]

                if len(info) == 0:
                    pass
                else:
                    insertindex = 0
                    for car in info:
                        if car.locate > self.insertpostion:
                            break
                        else:
                            insertindex += 1
                    num = len(info[insertindex:])
                    if num == 0:
                        pass
                    elif num == 1:
                        nextCar = copy.deepcopy(info[insertindex])
                        nextCar.locate += (self.length - self.insertpostion)
                    elif num > 1:
                        nextCar = copy.deepcopy(info[insertindex])
                        nextCar.locate += (self.length - self.insertpostion)

                        next2Car = copy.deepcopy(info[insertindex+1])
                        next2Car.locate += (self.length - self.insertpostion)

            speed = self.execRule(opcar, nextCar, next2Car)
            tempVSaver.append(speed)
            tempLocateSaver.append(opcar.locate + speed)

            endcars = []
            for i in xrange(len(tempVSaver)):
                opcar = self.carbox[lane][i]
                opcar.speed = tempVSaver[i]
                opcar.locate = tempLocateSaver[i]
                if opcar.locate >= self.length:
                    endcars.append(opcar)

            # 计算时间车头距的指标
            if self.headcountflag is True:
                foo = len(endcars)
                if foo > 1:
                    for i in xrange(foo-1):
                        self.head[lane].append(0)
                    self.headfont[lane] = self.wholeTime
                elif foo == 1:
                    self.head[lane].append(self.wholeTime - self.headfont[lane])
                    self.headfont[lane] = self.wholeTime

            for opcar in endcars:
                opcar.locate -= self.length
                self.leavecars[lane] += 1
                #如果出口连接了其他的道路,则自动将离开的车加入其入口
                if self.connectroad != None:
                    opcar.locate += self.insertpostion
                    if self.nextlanemethod == 'simple':
                        self.connectroad.add_car(opcar, opcar.lane)
                    elif self.nextlanemethod == 'left':
                        self.connectroad.add_car(opcar, 0)
                    elif self.nextlanemethod == 'right':
                        self.connectroad.add_car(opcar, self.connectroad.get_road_lanes()-1)

                #如果需要自动添加车辆,每离开一辆车就自动在起始初添加一辆车(一般用于入口)
                if self.autoAdderSwitch == True:
                    if self.pers == None:
                        if len(self.carbox[lane]) == 0 or \
                                self.carbox[lane][0].locate > self.autoAdder[0].length:
                            self.add_car(self.autoAdder[0], opcar.lane)
                    else:
                        dice = np.random.random()
                        upper = 0.0
                        lower = 0.0
                        for i in xrange(len(self.pers)):
                            upper += self.pers[i]
                            if lower <= dice < upper:
                                if len(self.carbox[lane]) == 0 or \
                                    self.carbox[lane][0].locate > self.autoAdder[i].length:
                                    self.add_car(self.autoAdder[i], opcar.lane)
                                break
                            lower += self.pers[i]
                self.carbox[lane].remove(opcar)

        self.__reflush_wait_line()

        #如果有需要,按时间添加车辆的LOOP
        if self.autoAdderByTime == True:
            if self.autoAddTime == self.__timer(get=True):
                self.__timer(reset=True)
                for i in xrange(self.nums):
                    #TODO:添加其他lane-method
                    oplane = int(np.random.random()*self.lanes)
                    if self.pers == None:
                        if len(self.carbox[oplane]) == 0 or \
                                self.carbox[oplane][0].locate > self.autoAdder[0].length:
                            self.add_car(self.autoAdder[0], oplane)
                    else:
                        dice = np.random.random()
                        upper = 0.0
                        lower = 0.0
                        for i in xrange(len(self.pers)):
                            upper += self.pers[i]
                            if lower <= dice < upper:
                                if len(self.carbox[oplane]) == 0 or \
                                    self.carbox[oplane][0].locate > self.autoAdder[i].length:
                                    self.add_car(self.autoAdder[i], oplane)
                                break
                            lower += self.pers[i]

    def __reflush_wait_line(self):
        oplane = 0
        while(len(self.waitLine) != 0):
            opcar = self.waitLine[0]
            newcar = copy.deepcopy(opcar)
            if newcar.lane == oplane:
                self.carbox[oplane].insert(0, newcar)
                self.waitLine.remove(opcar)
            elif newcar.lane > self.lanes:
                oplane = np.random.random()*self.lanes
                self.carbox[oplane].insert(0, newcar)
                self.waitLine.remove(opcar)
            else:
                pass

            if oplane < self.lanes:
                oplane += 1
            else:
                oplane = 0

    def __change_lane(self, opcar, nextCar, Pignore=None):
        dis = self.vmax + opcar.safedistance + opcar.length
        #判断是否需要换道
        if opcar.changeflag is True or opcar.lane - 1 < 0 or opcar.lane + 1 >= self.lanes \
            or nextCar == None or nextCar.locate - opcar.locate > dis:
            return False
        if Pignore != None:
            if np.random.random() > Pignore:
                return False
        carsLocate = self.get_cars_locate()
        insertIndex = 0
        # 左道优先
        oplane = opcar.lane - 1
        carsDistance = opcar.locate - carsLocate[oplane]
        carsInBound = carsDistance[abs(carsDistance) <= dis]
        negflag = False
        if carsInBound.size == 0:
            for index, offset in enumerate(carsDistance):
                if offset > 0:
                    insertIndex = index + 1
                else:
                    insertIndex = index
                    break

            opcar.changeflag = True
            self.carbox[oplane].insert(insertIndex, opcar)
            self.carbox[opcar.lane].remove(opcar)
            opcar.lane = oplane
            return True

        # 右道
        oplane = opcar.lane + 1
        carsDistance = opcar.locate - carsLocate[oplane]
        carsInBound = carsDistance[abs(carsDistance) <= dis]
        if carsInBound.size == 0:
            insertIndex = carsDistance.size
            for index, offset in enumerate(carsDistance):
                if offset > 0:
                    insertIndex = index + 1
                else:
                    insertIndex = index
                    break
            opcar.changeflag = True
            self.carbox[oplane].insert(insertIndex, opcar)
            self.carbox[opcar.lane].remove(opcar)
            return True

        return False

    def add_car(self, car, lane):
        car = copy.deepcopy(car)    #深复制一个对象(新建一辆车)
        car.lane = lane
        self.entercars += 1
        self.waitLine.append(car)

    #清空离开道路车辆数的计数
    def reLeave(self):
        self.leavecars = np.zeros(self.lanes)

    #自动添加车辆(每离开一辆就添加一辆)
    def cycle_boundary_condition(self, switch, carTemplateBox, pers=None):
        if self.autoAdderByTime != True:
            self.pers = pers
            self.autoAdderSwitch = switch
            self.autoAdder = carTemplateBox
        else:
            print 'Set add car automatic failed,there alreadly existed another mode'

    #按时间间隔添加车辆,与前一个冲突
    def time_boundary_condition(self, switch, carTemplateBox, pers=None, timeStep=1, nums=1, method = 'random'):
        if self.autoAdderSwitch != True:
            self.pers = pers
            self.autoAdderByTime = switch
            self.autoAdder = carTemplateBox
            self.nums = nums
            self.timeboundmethod = method
            if timeStep > 0:
                self.autoAddTime = timeStep
            else:
                print 'timeStep must bigger than ZERO'
        else:
            print 'Set add car automatic by time failed,there alreadly existed another mode'

    def set_connect_to(self, road, insertpostion=0):
        self.connectroad = road
        self.insertpostion = insertpostion

    #---------------------------------------------------
    def __timer(self, get=False, reset=False):
        if get == True:
            return self.timeCounter
        if reset == True:
            self.timeCounter = 0
        else:
            self.wholeTime += 1
            self.timeCounter += 1

    def __get_next_enter_lane(self, oplane):
        if self.nextlanemethod == 'simple':
            if oplane >= self.connectroad.lanes:
                return self.connectroad.lanes - 1
            else:
                return oplane
        elif self.nextlanemethod == 'right':
            return self.connectroad.lanes - 1
        elif self.nextlanemethod == 'left':
            return 0
        else:
            raise KeyError(_tips.INFO('No such method', 'RED'))

    def set_next_lane_method(self, method):
        self.nextlanemethod = method

def init_empty_road(lanes):
    if lanes <= 0 :
        raise _tips.INFO('InitFailed: lanes must greater than ZERO!', 'RED')
    output = []
    for i in xrange(lanes):
        output.append([])
    return output

#在指定长度上初始化指定数量的车辆,可以指定分布,默认线性均匀分布
def init_cars_distributed(length, carTemplateBox, carsNum=None, lanes=1, dis='normal', pers=None):

    output = []
    if length <= 0:
        raise ValueError(_tips.INFO('InitFailed: Road length must greater than ZERO!', 'RED'))
    if carsNum <= 0 and carsNum != None:
        raise ValueError(_tips.INFO('InitFailed: Cars num must greater than ZERO! ', 'RED'))

    #if type(carTemplateBox) != list or type(carTemplateBox[0]) != type(Car):
    #    raise 'InitFailed: Unkonw car template type'

    # 最密填充
    if dis == 'maxium':
        if len(carTemplateBox) == 1 and pers == None:
            for lane in xrange(lanes):
                adder = 0.0
                temp = []
                while adder <= length:
                    newCar = copy.deepcopy(carTemplateBox[0])
                    newCar.locate = adder
                    newCar.lane = lane
                    adder += (newCar.length + newCar.safedistance)
                    temp.append(newCar)
                output.append(temp)
            return output
        elif len(carTemplateBox) == len(pers):
            if sum(pers) != 1.0:
                raise ValueError(_tips.INFO('InitFailed: sum of per must be 1.0', 'RED'))
            for lane in xrange(lanes):
                adder = 0.0
                temp = []
                while adder <= length:
                    dice = np.random.random()
                    upper = 0.0
                    lower = 0.0
                    for i in xrange(len(pers)):
                        upper += pers[i]
                        if lower <= dice < upper:
                            newCar = copy.deepcopy(carTemplateBox[i])
                            break
                        lower += pers[i]
                    newCar.locate = adder
                    newCar.lane = lane
                    adder += (newCar.length + newCar.safedistance)
                    temp.append(newCar)
                output.append(temp)
            return output
        else:
            raise KeyError(_tips.INFO("InitFailed: len(carTemplateBox) != len(pers)", 'RED'))
    # 均匀填充
    elif dis == 'normal':
        output = []
        for i in xrange(lanes):
            output.append([])
        if len(carTemplateBox) == 1 and pers == None:
            adder = 0.0
            oplane = 0

            while adder <= length:
                newCar = copy.deepcopy(carTemplateBox[0])
                newCar.locate = adder
                newCar.lane = oplane
                if oplane+1 < lanes:
                    oplane += 1
                else:
                    oplane = 0
                adder += (newCar.length + newCar.safedistance*2)
                output[oplane].append(newCar)
            return output
        elif len(carTemplateBox) == len(pers):
            if sum(pers) != 1.0:
                raise ValueError(_tips.INFO('InitFailed: sum of per must be 1.0', 'RED'))
            adder = 0.0
            oplane = 0
            while adder <= length:
                dice = np.random.random()
                upper = 0.0
                lower = 0.0
                for i in xrange(len(pers)):
                    upper += pers[i]
                    if lower <= dice < upper:
                        newCar = copy.deepcopy(carTemplateBox[i])
                        break
                    lower += pers[i]
                newCar.locate = adder
                newCar.lane = oplane
                if oplane+1 < lanes:
                    oplane += 1
                else:
                    oplane = 0
                adder += (newCar.length + newCar.safedistance*2)
                output[oplane].append(newCar)
            return output
        else:
            raise KeyError(_tips.INFO("InitFailed: len(carTemplateBox) != len(pers)", 'RED'))
    else:
        raise KeyError(_tips.INFO('No such method', 'RED'))