text:
#
# All parameter and variables names are appended
# with unit where appropriate.
#  _g  = grams
#  _gpm3   = grams per meter cubed (mg/L)
#  _m3pmin = meters cubed per minute
#
from pyomo.environ import *

def define_model(SCENARIO_SUMMARY, BOOSTER_CANDIDATES, CONTROLLER_NODES, IMPACTS, WQM_HEADERS, POPULATION_DOSAGE, DELTA_INDEX, OBJECTIVE_TERMS, SCENARIO_SCALING, max_stations, pd_threshold):
    model = ConcreteModel()

    # number of minutes for each timestep
    model.P_MINUTES_PER_TIMESTEP = WQM_HEADERS.P_MINUTES_PER_TIMESTEP
    # all the nodes including tanks and reservoirs
    model.S_NODES = WQM_HEADERS.S_NODES
    # all time steps
    model.S_TIMES = WQM_HEADERS.S_TIMES

    # The set points considered in the problem as well
    # as the objective function weights - IMPACTS.dat
    model.S_SPACETIME = Set(initialize=list(IMPACTS.P_IMPACT.keys()))
    # mass dosed (grams)
    model.P_IMPACT = IMPACTS.P_IMPACT

    model.S_DELTA_INDEX = Set(initialize=DELTA_INDEX.S_DELTA_INDEX)

    # Node population and usage data
    # A default=0 "Param"
    model.S_NZP_NODES = Set(initialize=POPULATION_DOSAGE.S_NZP_NODES, ordered=True)
    model.P_NODE_POPULATION = dict((n,0) for n in model.S_NZP_NODES)
    model.P_NODE_POPULATION.update(POPULATION_DOSAGE.P_NODE_POPULATION)
    # A default=0 "Param"
    model.P_VOLUME_INGESTED_m3 = dict(((n,t),0)
                                      for n in model.S_NZP_NODES
                                      for t in model.S_TIMES)
    model.P_VOLUME_INGESTED_m3.update(POPULATION_DOSAGE.P_VOLUME_INGESTED_m3)
    model.P_DOSE_THRESHOLD_g = pd_threshold

    # The set of booster nodes affecting a space-time point, i.e,
    # a sparse representation of the Z-thresh matrix - CONTROLLER_NODES.dat
    model.S_CONTROLLER_BOOSTERS = CONTROLLER_NODES.S_CONTROLLER_BOOSTERS

    # The set of candidate booster nodes - BOOSTER_CANDIDATES.dat
    model.S_BOOSTER_CANDIDATES = Set(initialize=BOOSTER_CANDIDATES.S_BOOSTER_CANDIDATES)

    # Maximum number of booster stations allowed - set in run file
    model.P_MAX_STATIONS = max_stations

    # Auxiliary data not needed to solve the problem - SCENARIO_SUMMARY.dat
    # This parameter could be different from the the size of the set
    # S_SCENARIOS. It represents the actual number of scenarios, before any
    # possible aggregation, that is used to compute expected value.
    model.S_SCENARIOS = Set(initialize=list(SCENARIO_SUMMARY.P_WEIGHT.keys()))
    model.P_WEIGHT = SCENARIO_SUMMARY.P_WEIGHT

    model.P_INJECTION_SCALING = SCENARIO_SCALING.P_INJECTION_SCALING
    # relax max dose computation by some floating point tolerance
    model.EPS = 1e-6

    # A default=0 "Param"
    model.P_MAX_DOSE_g = dict(((n,s),0)
                              for n in model.S_NZP_NODES
                              for s in model.S_SCENARIOS)
    model.P_MAX_DOSE_g.update(POPULATION_DOSAGE.P_MAX_DOSE_g)

    # A default=0 "Param"
    model.P_ALWAYS_DOSED_g = dict(((n,s),0)
                              for n in model.S_NZP_NODES
                              for s in model.S_SCENARIOS)
    model.P_ALWAYS_DOSED_g.update(SCENARIO_SUMMARY.P_ALWAYS_DOSED_g)

    # A default=[] "Set"
    model.S_REDUCED_MAP = dict(((n,s),[])
                              for n in model.S_NZP_NODES
                              for s in model.S_SCENARIOS)
    model.S_REDUCED_MAP.update(OBJECTIVE_TERMS.S_REDUCED_MAP)

    #model variables
    model.delta = Var(model.S_DELTA_INDEX, bounds=(0,1))
    model.y_booster = Var(model.S_BOOSTER_CANDIDATES, within=Binary)
    # Dose consumed
    model.dose_g = Var(model.S_NZP_NODES,model.S_SCENARIOS,within=NonNegativeReals, initialize=0.0)
    # Dose above threshold binary var
    model.z_dosed = Var(model.S_NZP_NODES,model.S_SCENARIOS,within=Binary,initialize=0)

    def PD_obj_rule(m):
        return sum(m.P_WEIGHT[s]*m.z_dosed[n,s]*m.P_NODE_POPULATION[n] \
                   for n in m.S_NZP_NODES for s in m.S_SCENARIOS)
    model.POPULATION_DOSED = Objective(rule=PD_obj_rule)

    # Dose over all timesteps
    def total_dose_rule(m,n,s):
        return (m.dose_g[n,s] - m.P_ALWAYS_DOSED_g[n,s] - \
                sum(m.P_IMPACT[n,s,i]*m.delta[i] \
                    for i in m.S_REDUCED_MAP[n,s]), 0.0)
    model.TOTAL_DOSE = Constraint(model.S_NZP_NODES, model.S_SCENARIOS, rule=total_dose_rule)

    # Dose above thresold Big-M constraint
    def dose_bigM_rule_upper(m,n,s):
        return m.dose_g[n,s] <= \
            m.z_dosed[n,s]*(m.P_MAX_DOSE_g[n,s]*(1+m.EPS) - m.P_DOSE_THRESHOLD_g*m.P_INJECTION_SCALING[s]) + \
            m.P_DOSE_THRESHOLD_g*m.P_INJECTION_SCALING[s]
    model.DOSE_BIGM_upper = Constraint(model.S_NZP_NODES, model.S_SCENARIOS, rule=dose_bigM_rule_upper)

    # If this node/time is effected by active booster then allow delta to go to its LB.
    def reaction_rule(m,i):
        return (1.0,m.delta[i]+sum(m.y_booster[b] for b in m.S_CONTROLLER_BOOSTERS[i]),None)
    model.REACTION = Constraint(model.S_DELTA_INDEX, rule=reaction_rule)

    # Only P_MAX_STATIONS number of booster stations allowed.
    def booster_node_rule(m):
        return (None,summation(m.y_booster),m.P_MAX_STATIONS)
    model.BOOSTER_NODE = Constraint(rule=booster_node_rule)

    return model

def create_solution_function(results_filename, objective_type):
    def postprocess(options=None,instance=None,results=None):
        #instance.load(results)
        solution = {}
        solution['booster ids'] = [i for i in instance.S_BOOSTER_CANDIDATES if instance.y_booster[i].value > 0.9]
        if objective_type == 'MC':
            solution['expected mass consumed grams'] = value(instance.MASS_CONSUMED_g)
        elif objective_type == 'PD':
            solution['expected population dosed'] = value(instance.POPULATION_DOSED)
        else:
            assert False

        import yaml
        with open(results_filename,'w') as f:
            yaml.dump(solution,f)
        for (n,s) in instance.dose_g:
            if instance.dose_g[n,s]() > value(instance.P_MAX_DOSE_g[n,s]):
                print instance.dose_g.cname(True), instance.dose_g[n,s](), value(instance.P_MAX_DOSE_g[n,s])
    return postprocess

max_stars_repo_name: USEPA/Water-Security-Toolkit

max_issues_repo_name: USEPA/Water-Security-Toolkit

max_forks_repo_name: USEPA/Water-Security-Toolkit

reason: from pyomo


text:
#Author=Vivek Kumar Jaiswal
#This program takes a Photo and returns the lanes found in the picture.

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

#Canny Function is to convert the image to B/W and to draw the outlines of the lanes.
def canny(image):
    gray = cv.cvtColor(image, cv.COLOR_RGB2GRAY)
    blur = cv.GaussianBlur(gray, (5,5),0)
    canny= cv.Canny(blur, 50,150)
    return canny

#To draw the lanes from the lines image
def display_lines(img,lines):
    line_image = np.zeros_like(img)
    if lines is not None:
        for line in lines:
           # for x1, y1, x2, y2 in line:
            x1,y1,x2,y2 = line.reshape(4)
            cv.line(line_image,(x1,y1),(x2,y2),(255,0,0),10)
    return line_image

#Specify the particular area of interest
def region_of_interest(image):
    height=image.shape[0]
    polygons = np.array([
    [(200,height), (1100, height), (550, 250)]
    ])
    mask=np.zeros_like(image)
    cv.fillPoly(mask, polygons, 255)
    masked_image=cv.bitwise_and(image,mask)
    return masked_image

def make_coordinate(image, parameters):
    slope, intercept = parameters
    y1 = image.shape[0]
    y2 = int (y1*3/5)
    x1 = int ((y1-intercept)/slope)
    x2 = int ((y2-intercept)/slope)
    return np.array([x1,y1,x2,y2])

def average_lane_slope(image, lines):
    left_lane=[]
    right_lane=[]
    for line in lines:
        for x1, y1, x2, y2 in line:
            parameters = np.polyfit((x1,x2),(y1,y2),1 )
            slope=parameters[0]
            intercept=parameters[1]
            if slope < 0 :
                left_lane.append((slope,intercept))
            else:
                right_lane.append((slope,intercept))

    left_lane_average=np.average(left_lane, axis=0)
    right_lane_average=np.average(right_lane, axis=0)
    left_line=make_coordinate(image, left_lane_average)
    right_line=make_coordinate(image, right_lane_average)
    return np.array([left_line, right_line])

cap = cv.VideoCapture("test2.mp4")
while (cap.isOpened()):
    _, frame =cap.read()
    canny_image=canny(frame)
    cropped_image=region_of_interest(canny_image)
    lines=cv.HoughLinesP(cropped_image, 2, np.pi/180, 100, np.array([]), minLineLength=40, maxLineGap=5)
    averaged_line=average_lane_slope(frame,lines)
    line_image = display_lines(frame, averaged_line)
    combo_image=cv.addWeighted(frame, 0.8, line_image, 1, 1)
    cv.imshow('result', combo_image)
    if cv.waitKey(1) & 0xFF == ord('q'):
        break
cap.release()
cv.destroyAllWindows()

ext: py

max_stars_repo_name: curio-code/Lane-Detection

max_issues_repo_name: curio-code/Lane-Detection

max_forks_repo_name: curio-code/Lane-Detection

reason: import numpy


text:
import csv
import os.path

import matplotlib
import numpy as np
from matplotlib import pyplot as plt

matplotlib.rcParams.update({'font.size': 15})

n_trial = 5
top_k = 1
batch_size = 4000
max_step = np.inf
max_reward = np.inf
min_reward = -np.inf

exp_name = 'CartpoleNd'
exp_param = 'D1K05A05Ec10'
extra_name = ''
prepath = "../" + exp_name + "/Data/AST/Lexington/" + exp_param
plot_path = "../" + exp_name + "/Data/Plot/top" + str(top_k) + "/"
policies = [
    # "TRPO",\
    "MCTSRS",\
    # "MCTSAS",\
    # "MCTSBV",\
    # "GAP100T20K3Step1.0Fmean","GASMP100T20K3Step1.0Fmean",\
    # "GAP500T20K3Step1.0Fmean","GASMP500T20K3Step1.0Fmean",\
]
plot_name = exp_name + '_' + exp_param + 'avgtop' + str(top_k) + 'trial' + str(n_trial) + extra_name

plts = []
legends = []
fig = plt.figure(figsize=(10, 10))

for (policy_index, policy) in enumerate(policies):
    print(policy)

    for trial in range(n_trial):
        file_path = prepath + '/' + policy + '/' + str(trial) + '/process.csv'
        if os.path.exists(file_path):
            print(trial)
            steps = []
            rewards = []
            with open(file_path) as csv_file:
                if '\0' in open(file_path).read():
                    print("you have null bytes in your input file")
                    csv_reader = csv.reader(x.replace('\0', '') for x in csv_file)
                else:
                    csv_reader = csv.reader(csv_file, delimiter=',')

                for (i, row) in enumerate(csv_reader):
                    if i == 0:
                        entry_dict = {}
                        for index in range(len(row)):
                            entry_dict[row[index]] = index
                    else:
                        # print(row[entry_dict["StepNum"]])
                        if int(row[entry_dict["StepNum"]]) > max_step:
                            break
                        if int(row[entry_dict["StepNum"]]) % batch_size == 0:
                            steps.append(int(row[entry_dict["StepNum"]]))
                            avg_top = 0.0
                            for k in range(top_k):
                                avg_top += np.clip(float(row[entry_dict["reward " + str(k)]]), min_reward, max_reward)
                            avg_top /= top_k
                            rewards.append(avg_top)
            plot, = plt.plot(steps, rewards)
            # plot, = plt.plot(steps,np.mean(np.exp(Rewards),0))
            # plot,_,_ = plt.errorbar(steps,np.mean(Rewards,0),yerr=np.std(Rewards,0)/np.sqrt(n_trial),errorevery=10)
            plts.append(plot)
            legends.append(policy + '_' + str(trial))

plt.legend(plts, legends)
plt.xlabel('Step Number')
plt.ylabel('Top ' + str(top_k) + ' Reward')
fig.savefig(plot_path + plot_name)
plt.close(fig)

max_stars_repo_name: hdelecki/AdaptiveStressTestingToolbox

max_issues_repo_name: hdelecki/AdaptiveStressTestingToolbox

max_forks_repo_name: hdelecki/AdaptiveStressTestingToolbox


text:
# -*- coding: utf-8 -*-

"""
    Utilities to deal with the PageXMl 2D objects using shapely

    Copyright Xerox(C) 2018 JL. Meunier

    Developed  for the EU project READ. The READ project has received funding
    from the European Union�s Horizon 2020 research and innovation programme
    under grant agreement No 674943.

"""

import shapely.geometry as geom
from shapely.prepared import prep
from shapely.ops import cascaded_union
from rtree import index

import numpy as np

from xml_formats.PageXml import MultiPageXml

class ShapeLoader:

    @classmethod
    def getCoordsString(cls, o, bFailSafe=False):
        """
        Produce the usual content of the "Coords" attribute, e.g.:
            "3162,1205 3162,1410 126,1410 126,1205 3162,1205"
        may raise an exception
        """
        try:
            lt2 = o.exterior.coords  # e.g. [(0.0, 0.0), (1.0, 1.0), (1.0, 0.0)]
        except:
            if bFailSafe:
                try:
                    lt2 = o.coords
                except:
                    return ""
            else:
                lt2 = o.coords
        return " ".join("%d,%d" % (a,b) for a,b in lt2)

    @classmethod
    def contourObject(cls, lNd):
        """
        return the stringified list of coordinates of the contour
        for the list of PageXml node.
            e.g. "3162,1205 3162,1410 126,1410 126,1205 3162,1205"
        return "" upon error

        if bShapelyObjecy is True, then return the Shapely object
        raise an Exception upon error
        """
        lp = []
        for nd in lNd:
            try:
                lp.append(ShapeLoader.node_to_Polygon(nd))
            except:
                pass

        o = cascaded_union([p if p.is_valid else p.convex_hull for p in lp ])
        return o

    @classmethod
    def minimum_rotated_rectangle(cls, lNd, bShapelyObject=False):
        """
        return the stringified list of coordinates of the minimum rotated
        rectangle for the list of PageXml node.
            e.g. "3162,1205 3162,1410 126,1410 126,1205 3162,1205"
        return "" upon error

        if bShapelyObjecy is True, then return the Shapely object
        raise an Exception upon error
        """
        contour = cls.contourObject(lNd)
        o = contour.minimum_rotated_rectangle
        return o if bShapelyObject else cls.getCoordsString(o, bFailSafe=True)

    @classmethod
    def convex_hull(cls, lNd, bShapelyObject):
        """
        return the stringified list of coordinates of the minimum rotated
        rectangle for the list of PageXml node.
            e.g. "3162,1205 3162,1410 126,1410 126,1205 3162,1205"
        return "" upon error

        if bShapelyObjecy is True, then return the Shapely object
        raise an Exception upon error
        """
        contour = cls.contourObject(lNd)
        o = contour.convex_hull
        return o if bShapelyObject else cls.getCoordsString(o, bFailSafe=True)

    @classmethod
    def node_to_Point(cls, nd):
        """
        Find the points attribute (either in the DOM node itself or in a
        children Coord node)
        Parse the points series as a LineString
        Return its centroid
        """
        return cls._shapeFromNodePoints(nd, geom.LineString).centroid

    @classmethod
    def node_to_LineString(cls, nd):
        """
        Find the points attribute (either in the DOM node itself or in a
        children Coord node)
        Parse the points series
        Return a LineString shapely object
        """
        return cls._shapeFromNodePoints(nd, geom.LineString)

    @classmethod
    def node_to_SingleLine(cls, nd):
        """
        Find the points attribute (either in the DOM node itself or in a
        children Coord node)
        Parse the points series
        Do a linear regression to create a single-segment LineString
        Return a LineString shapely object with a single segment
        """
        o = cls._shapeFromNodePoints(nd, geom.LineString)
        if len(o.coords) == 2:
            # speed-up
            return o
        else:
            return cls.LinearRegression(o)

    @classmethod
    def node_to_Polygon(cls, nd, bValid=True):
        """
        Find the points attribute (either in the DOM node itself or in a
        children Coord node)
        Parse the points series
        Return a Polygon shapely object
        """
        p = cls._shapeFromNodePoints(nd, geom.Polygon)
        if bValid and not p.is_valid:
            # making sure it is a valid shape
            p = p.buffer(0)
        return p

    @classmethod
    def children_to_LineString(cls, node, name, fun=None):
        """
        do a MultiPageXml.getChildByName from a node to get some nodes
            e.g. "SeparatorRegion"
        construct a shapely LineString from the coordinates of each node
            e.g.  <SeparatorRegion orient="horizontal 373.8 0.006" row="1">
                <Coords points="3324,392 3638,394"/>
              </SeparatorRegion>
        if fun is given applies fun, with arguments: shape, current_node
        return the list of shape objects in same order as retrived by getChildByName
        """
        return cls._doShape_getChildByName(node, name
                                           , geom.LineString
                                           , fun)

    @classmethod
    def children_to_LinearRing(cls, node, name, fun=None):
        """
        do a MultiPageXml.getChildByName from a node to get some nodes
            e.g. "SeparatorRegion"
        construct a shapely LinearRing from the coordinates of each node
            e.g.  <SeparatorRegion orient="horizontal 373.8 0.006" row="1">
                <Coords points="3324,392 3638,394"/>
              </SeparatorRegion>
        if fun is given applies fun, with arguments: shape, current_node
        return the list of shape objects in same order as retrived by getChildByName
        """
        return cls._doShape_getChildByName(node, name
                                           , geom.LinearRing
                                           , fun)

#     @classmethod
#     def LinearRegression_bad(cls, oLineString, step=10):
#         """
#         make a single-segment LineString out of the input LineString
#         do a LinearRegression on a subsampling of the LineString
#         """
#         lCoord = list(oLineString.coords)
#         lX, lY = [], []
#         x0, y0 = lCoord.pop(0)
#         xx00 = x0
#         for x1, y1 in lCoord:
#             try:
#                 a = (y1 - y0) / (x1 - x0)
#                 #for x in range(x0, x1, step):
#                 x = x0
#                 while x < x1:
#                     y = y0 + (x - x0) * a
#                     lX.append(x)
#                     lY.append(y)
#                     x += step
#             except ZeroDivisionError:
#                 # vertical segment?
#                 try:
#                     a = (x1 - x0) / (y1 - y0)
#                     while y < y1:
#                         x = x0 + (y - y0) * a
#                         lX.append(x)
#                         lY.append(y)
#                         y += step
#                 except:
#                     pass # empty segment
#             x0, y0 = x1, y1
#         lX.append(x0)
#         lY.append(y0)
#         z = np.polyfit(np.array(lX), np.array(lY), 1)
#         y0 = round(z[1] + z[0] * xx00, 2)
#         y1 = round(z[1] + z[0] * x0, 2)
#
#         return geom.LineString([(xx00, y0), (x0, y1)])

    @classmethod
    def LinearRegression(cls, oLineString):
        """
        make a single-segment LineString out of the input LineString
        do a LinearRegression of the LineString segments
        """
        return geom.LineString(cls._LinearRegression(oLineString.coords))

    @classmethod
    def _LinearRegression(cls, lCoords):
        """
        weighted LinearRegression of the segments
        """
        XY = np.array(lCoords)
        # Norm of each segment
        Norm = np.linalg.norm(np.roll(XY, -1, axis=0) - XY, axis=1)
        Norm[-1] = 0
        # a point gets the sum of norm of the adjacent segment (1 at each end)
        W = Norm + np.roll(Norm, 1)
        W = np.sqrt(W / W.sum())
        z = np.polyfit(XY[:,0], XY[:,1], 1, w=W)
        x0, x1 = XY[0,0], XY[-1,0]
        y0 = round(z[1] + z[0] * x0, 2)
        y1 = round(z[1] + z[0] * x1, 2)
        return ((x0, y0), (x1, y1))

    @classmethod
    def _shapeFromPoints(cls, sPoints, ShapeClass):
        """
        Parse a string containing a space-separated list of points, like:
        "3466,3342 3512,3342 3512,3392 3466,3392"
        returns a shape of given class
        """
        # line = LineString([(0, 0), (1, 1)])
        return ShapeClass(tuple(float(_v) for _v in _sPair.split(','))
                            for _sPair in sPoints.split(' '))

    @classmethod
    def _shapeFromNodePoints(cls, nd, ShapeClass):
        """
        Find the Coords child of the node and parse its points
         e.g. <SeparatorRegion orient="horizontal 373.8 0.006" row="1">
                <Coords points="3324,392 3638,394"/>
              </SeparatorRegion>
        returns a shape of given class
        """
        sPoints = nd.get('points')
        if sPoints is None:
            sPoints  = MultiPageXml.getChildByName(nd, 'Coords')[0].get('points')
        return cls._shapeFromPoints(sPoints, ShapeClass)

    @classmethod
    def _doShape_getChildByName(cls, node, name, ShapeClass, fun=None):
        """
        do a MultiPageXml.getChildByName from a node to get some nodes
            e.g. "SeparatorRegion"
        construct a shape of given Shapely class from the coordinates of each node
            e.g.  <SeparatorRegion orient="horizontal 373.8 0.006" row="1">
                <Coords points="3324,392 3638,394"/>
              </SeparatorRegion>
        if fun is given applies fun, with arguments: shape, current_node
        return the list of shape objects in same order as retrived by getChildByName
        """
        lO = []
        for _nd in MultiPageXml.getChildByName(node, name):
            try:
                o = cls._shapeFromNodePoints(_nd, ShapeClass)
            except Exception as e:
                print('ERROR: cannot load this element "%s"' % str(_nd))
                print('  because "%s"' % e)
                continue
            if not fun is None: fun(o, _nd)
            lO.append(o)

        return lO

class ShapePartition:
    """
    Given a list of shapely objects, deal with partition of those objects
    """
    CollectionClass = geom.collection
    INF = 99999 # INFINITY...

    def __init__(self, lo):
        """
        Initialize the list of objects
        """
        self.lo = lo
        self.idx = index.Index()

        # Populate R-tree index with bounds of grid cells
        for pos, o in enumerate(self.lo):
            self.idx.insert(pos, o.bounds)

    def isValidCut(self, oLine):
        """
        Does this line passes between the objects?
        """
        prepO = prep(oLine)
        for pos in self.idx.intersection(oLine.bounds):
            if prepO.intersects(self.lo[pos]): return False
        return True

    def isValidRibbonCut(self, oLine, h):
        """
        Does this ribbon of height h passes between the objects?
        """
        (xa, ya), (xb, yb) = oLine.coords
        oRibbon = geom.Polygon([  (xa, ya)    , (xb, yb)
                                , (xb, yb + h), (xa, ya + h)])
        prepO = prep(oRibbon)
        for pos in self.idx.intersection(oRibbon.bounds):
            if prepO.intersects(self.lo[pos]): return False
        return True

    def getObjectAboveLineByIds(self, oLine):
        """
        return a tuple of the index of the objects above the line
        The index is based on the initial list of objects passed to __init__
        """
        xa, ya = oLine.coords[0]
        xb, yb = oLine.coords[-1]
        if xa > xb: xa, ya, xb, yb = xb, yb, xa, ya
        half_plan = geom.Polygon([(xa, -self.INF) , (xb, -self.INF)
                                , (xb, yb)      , (xa, ya)
                                ])
        bounds = half_plan.bounds
        half_plan_prep = prep(half_plan) # speed up!!
        return tuple(pos for pos in self.idx.intersection(bounds)
                        if half_plan_prep.intersects(self.lo[pos]))
        # NOTE: intersects is better than contains because some Baseline may go beyond page limit...

    def getObjectBelowLineByIds(self, oLine):
        """
        return a tuple of the index of the objects below the line
        The index is based on the initial list of objects passed to __init__
        """
        xa, ya = oLine.coords[0]
        xb, yb = oLine.coords[-1]
        if xa > xb: xa, ya, xb, yb = xb, yb, xa, ya
        half_plan = geom.Polygon([(xa, +self.INF) , (xb, +self.INF)
                                , (xb, yb)      , (xa, ya)
                                ])
        bounds = half_plan.bounds
        half_plan_prep = prep(half_plan) # speed up!!
        return tuple(pos for pos in self.idx.intersection(bounds)
                        if half_plan_prep.intersects(self.lo[pos]))
        # NOTE: intersects is better than contains because some Baseline may go beyond page limit...

    def getObjectLeftOfLineByIds(self, oLine):
        """
        return a tuple of the index of the objects on left of the line
        The index is based on the initial list of objects passed to __init__
        """
        xa, ya = oLine.coords[0]
        xb, yb = oLine.coords[-1]
        if ya > yb: xa, ya, xb, yb = xb, yb, xa, ya
        half_plan = geom.Polygon([(-self.INF, ya) , (-self.INF, yb)
                                , (xb, yb)      , (xa, ya)
                                ])
        bounds = half_plan.bounds
        half_plan_prep = prep(half_plan) # speed up!!
        return tuple(pos for pos in self.idx.intersection(bounds)
                        if half_plan_prep.intersects(self.lo[pos]))
        # NOTE: intersects is better than contains because some Baseline may go beyond page limit...

    def getObjectRightOfLineByIds(self, oLine):
        """
        return a tuple of the index of the objects on left of the line
        The index is based on the initial list of objects passed to __init__
        """
        xa, ya = oLine.coords[0]
        xb, yb = oLine.coords[-1]
        if ya > yb: xa, ya, xb, yb = xb, yb, xa, ya
        half_plan = geom.Polygon([(+self.INF, ya) , (+self.INF, yb)
                                , (xb, yb)      , (xa, ya)
                                ])
        bounds = half_plan.bounds
        half_plan_prep = prep(half_plan) # speed up!!
        return tuple(pos for pos in self.idx.intersection(bounds)
                        if half_plan_prep.intersects(self.lo[pos]))

    def getObjects(self, lId):
        """
        Return the list of corresponding objects
        """
        return [self.lo[pos] for pos in lId]

    def getObjectAboveLine(self, oLine):
        """
        Given a list of objects above the given line
        """
        return tuple(self.lo[pos] for pos in self.getObjectAboveLineByIds(oLine))

    def getObjectBelowLine(self, oLine):
        """
        Given a list of objects below the given line
        """
        return tuple(self.lo[pos] for pos in self.getObjectBelowLineByIds(oLine))

    def getObjectOnLeftOfLine(self, oLine):
        """
        Given a list of objects on left of the given line
        """
        return tuple(self.lo[pos] for pos in self.getObjectLeftOfLineByIds(oLine))

    def getObjectOnRightOfLine(self, oLine):
        """
        Given a list of objects on left of the given line
        """
        return tuple(self.lo[pos] for pos in self.getObjectRightOfLineByIds(oLine))

    def free(self):
        """
        disposal of any internal resource of self
        """
        del self.lo, self.idx

class PolygonPartition(ShapePartition):
    """
    Partition of LineString objects
    """
    CollectionClass = geom.MultiPolygon

    def __init__(self, lo):
        """
        Initialize the list of objects
        """
        ShapePartition.__init__(self, lo)

# -----------------------------------------------------------------------
def test_ShapeLoader():
    o = ShapeLoader._shapeFromPoints("0,0 0,9", geom.LineString)
    assert o.length == 9
    assert o.area == 0.0

def test_ShapeLoader_Coords():
    s = "3162,1205 3162,1410 126,1410 3162,1205"
    o = ShapeLoader._shapeFromPoints(s, geom.Polygon)
    assert ShapeLoader.getCoordsString(o) == s

# -----------------------------------------------------------------------
def test_ShapePartition_object_above(capsys):
        with capsys.disabled():

            for cls in [ShapePartition, PolygonPartition]:
                b1 = geom.Polygon([(1,2), (2,2), (2,3), (1,3)])
                b2 = geom.Polygon([(3,7), (4,7), (4,8), (3,8)])
                o = cls([b1,b2])

                l0 = geom.LineString([(0,0), (10,0)])
                assert o.getObjectAboveLineByIds(l0) == ()
                assert o.getObjectAboveLine(l0) == ()

                l1 = geom.LineString([(0,6), (10,5)])
                assert o.getObjectAboveLineByIds(l1) == (0,)
                assert o.getObjectAboveLine(l1) == (b1,)

                l2 = geom.LineString([(0,60), (10,50)])
                assert o.getObjectAboveLineByIds(l2) == (0,1)
                assert o.getObjectAboveLine(l2) == (b1, b2)

                l3 = geom.LineString([(0,8), (10,7)])
                # above if intersect with half-plan
                assert o.getObjectAboveLineByIds(l3) == (0,1)
                assert o.getObjectAboveLine(l3) == (b1,b2)

                o.free()

def test_ShapePartition_cut():

    for cls in [ShapePartition, PolygonPartition]:
        b1 = geom.Polygon([(1,2), (2,2), (2,3), (1,3)])
        b2 = geom.Polygon([(3,7), (4,7), (4,8), (3,8)])
        o = cls([b1,b2])

        assert o.isValidCut(geom.LineString([(0,0), (0,50)]))
        assert o.isValidCut(geom.LineString([(0,0), (50,0)]))
        assert o.isValidCut(geom.LineString([(0,4), (50,4)]))
        assert o.isValidCut(geom.LineString([(0,40), (50,40)]))
        assert o.isValidCut(geom.LineString([(2.5,40), (2.5,40)]))
        assert o.isValidCut(geom.LineString([(0,10), (5,0)]))

        assert not o.isValidCut(geom.LineString([(0,0), (3,5)]))
        assert not o.isValidCut(geom.LineString([(0,0), (5,10)]))

def test_ShapePartition_cut_ribbon():

    for cls in [ShapePartition, PolygonPartition]:
        b1 = geom.Polygon([(1,2), (2,2), (2,3), (1,3)])
        b2 = geom.Polygon([(3,7), (4,7), (4,8), (3,8)])
        o = cls([b1,b2])

        # height of 0 => same as before
        h = 0
        assert o.isValidRibbonCut(geom.LineString([(0,0), (0,50)]), h)
        assert o.isValidRibbonCut(geom.LineString([(0,0), (50,0)]), h)
        assert o.isValidRibbonCut(geom.LineString([(0,4), (50,4)]), h)
        assert o.isValidRibbonCut(geom.LineString([(0,40), (50,40)]), h)
        assert o.isValidRibbonCut(geom.LineString([(2.5,40), (2.5,40)]), h)
        assert o.isValidRibbonCut(geom.LineString([(0,10), (5,0)]), h)

        assert not o.isValidRibbonCut(geom.LineString([(0,0), (3,5)]), h)
        assert not o.isValidRibbonCut(geom.LineString([(0,0), (5,10)]), h)

        # heigt of 1 => same
        h = 1
        assert o.isValidRibbonCut(geom.LineString([(0,0), (0,50)]), h)
        assert o.isValidRibbonCut(geom.LineString([(0,0), (50,0)]), h)
        assert o.isValidRibbonCut(geom.LineString([(0,4), (50,4)]), h)
        assert o.isValidRibbonCut(geom.LineString([(0,40), (50,40)]), h)
        assert o.isValidRibbonCut(geom.LineString([(2.5,40), (2.5,40)]), h)
        assert o.isValidRibbonCut(geom.LineString([(0,10), (5,0)]), h)

        assert not o.isValidRibbonCut(geom.LineString([(0,0), (3,5)]), h)
        assert not o.isValidRibbonCut(geom.LineString([(0,0), (5,10)]), h)

        # heigt of 1 => Noo
        h = 10
        assert o.isValidRibbonCut(geom.LineString([(0,0), (0,50)]), h)
        assert not o.isValidRibbonCut(geom.LineString([(0,0), (50,0)]), h)
        assert not o.isValidRibbonCut(geom.LineString([(0,4), (50,4)]), h)
        assert o.isValidRibbonCut(geom.LineString([(0,40), (50,40)]), h)
        assert o.isValidRibbonCut(geom.LineString([(2.5,40), (2.5,40)]), h)
        assert not o.isValidRibbonCut(geom.LineString([(0,10), (5,0)]), h)

        assert not o.isValidRibbonCut(geom.LineString([(0,0), (3,5)]), h)
        assert not o.isValidRibbonCut(geom.LineString([(0,0), (5,10)]), h)

def test_LineStringToLine(capsys):
    "1113,1281 1318,1274 1320,1324 1115,133"

#     # OLD BAD EMPIRICAL METHOD
#     with capsys.disabled():
#         for step in [1, 2, 10]:
#             o05 = geom.LineString([(0,0), (5,5)])
#             o = ShapeLoader.LinearRegression_bad(o05, step)
#             assert o05 == o, str(o)
#
#             o39 = geom.LineString([(3,2), (9,10)])
#             o = ShapeLoader.LinearRegression_bad(o39, step)
#             assert o39 == o, str(o)
#
#             o08 = geom.LineString([(0,0), (5,5), (8,8)])
#             o = ShapeLoader.LinearRegression_bad(o08, step)
#             assert o == geom.LineString([(0,0), (8,8)]), str(o)
#
#         o10 = geom.LineString([(0,0), (5,5), (10,0)])
#         o = ShapeLoader.LinearRegression_bad(o10, 1)
#         assert o == geom.LineString([(0,2.27), (10,2.27)]), str(o)
#         o = ShapeLoader.LinearRegression_bad(o10, 0.001)
#         assert o == geom.LineString([(0,2.5), (10,2.5)]), str(o)
#
#         oBL = geom.LineString([(1734,654),(2013,640),(2197,646),(2439,611)])
#         o = ShapeLoader.LinearRegression_bad(oBL)
#         assert o == geom.LineString([(1734,655.64), (2439,623.28)]), str(o)
#
#         oBL = geom.LineString([(10,10),(20,10),(20,20),(30,20)])
#         o = ShapeLoader.LinearRegression_bad(oBL, 0.001)
#         assert o == geom.LineString([(10,7.5), (30,22.5)]), str(o)

    # GOOD METHOD
    with capsys.disabled():
        o05 = geom.LineString([(0,0), (5,5)])
        o = ShapeLoader.LinearRegression(o05)
        assert o05 == o, str(o)

        o39 = geom.LineString([(3,2), (9,10)])
        o = ShapeLoader.LinearRegression(o39)
        assert o39 == o, str(o)

        o08 = geom.LineString([(0,0), (5,5), (8,8)])
        o = ShapeLoader.LinearRegression(o08)
        assert o == geom.LineString([(0,0), (8,8)]), str(o)

        o10 = geom.LineString([(0,0), (5,5), (10,0)])
        o = ShapeLoader.LinearRegression(o10)
        assert o == geom.LineString([(0,2.5), (10,2.5)]), str(o)

        oBL = geom.LineString([(10,10),(20,10),(20,20),(30,20)])
        o = ShapeLoader.LinearRegression(oBL)
        assert o == geom.LineString([(10,10), (30,20)]), str(o)

        oBL = geom.LineString([(1734,654),(2013,640),(2197,646),(2439,611)])
        o = ShapeLoader.LinearRegression(oBL)
        assert o == geom.LineString([(1734,657), (2439,622.21)]), str(o)

max_stars_repo_name: Transkribus/TranskribusDU

max_issues_repo_name: Transkribus/TranskribusDU

max_forks_repo_name: Transkribus/TranskribusDU


text:
# PyZX - Python library for quantum circuit rewriting
#        and optimization using the ZX-calculus
# Copyright (C) 2018 - Aleks Kissinger and John van de Wetering

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#    http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import unittest
import sys
if __name__ == '__main__':
    sys.path.append('..')
    sys.path.append('.')

try:
    import numpy as np
    from pyzx.tensor import tensorfy, compare_tensors
except ImportError:
    np = None

from pyzx.circuit import Circuit
from pyzx.simulate import replace_magic_states

@unittest.skipUnless(np, "numpy needs to be installed for this to run")
class TestSimulate(unittest.TestCase):

    def test_magic_state_decomposition_is_correct(self):
        c = Circuit(6)
        for i in range(6):
            c.add_gate("T",i)
        g = c.to_graph()
        gsum = replace_magic_states(g)
        self.assertTrue(np.allclose(g.to_tensor(),gsum.to_tensor()))

if __name__ == '__main__':
    unittest.main()

max_stars_repo_name: mnm-team/pyzx-heuristics

max_issues_repo_name: mnm-team/pyzx-heuristics

max_forks_repo_name: mnm-team/pyzx-heuristics


text:
# Copyright 2018 The TensorFlow Probability Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ============================================================================
"""Tests for the LKJ distribution."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

# Dependency imports
from absl.testing import parameterized
import numpy as np
import tensorflow as tf
import tensorflow_probability as tfp

from tensorflow_probability.python.distributions.internal import statistical_testing as st
from tensorflow_probability.python.internal import assert_util
from tensorflow_probability.python.internal import test_util as tfp_test_util
from tensorflow.python.framework import test_util  # pylint: disable=g-direct-tensorflow-import,

tfd = tfp.distributions

def _det_ok_mask(x, det_bounds, input_output_cholesky=False):
  if input_output_cholesky:
    logdet = 2.0 * tf.reduce_sum(
        input_tensor=tf.math.log(tf.linalg.diag_part(x)), axis=[-1])
  else:
    _, logdet = tf.linalg.slogdet(x)

  return tf.cast(tf.exp(logdet) > det_bounds, dtype=x.dtype)

# Each leaf entry here is a confidence interval for the volume of some
# set of correlation matrices.  To wit, k-by-k correlation matrices
# whose determinant is at least d appear as volume_bounds[k][d].
# These particular confidence intervals were estimated by the
# Clopper-Pearson method applied to 10^7 rejection samples, with an
# error probability of 5e-7.  This computation may be performed by
# executing the correlation_matrix_volumes program with argument
# --num_samples 1e7.  Doing so took about 45 minutes on a standard
# workstation.
volume_bounds = {
    3: {0.01: (04.8334339757361420, 4.845866340472709),
        0.25: (02.9993127232473036, 3.011629093880439),
        0.30: (02.6791373340121916, 2.691146382760893),
        0.35: (02.3763254004846030, 2.3879545568875358),
        0.40: (02.0898224112869355, 2.1010041316917913),
        0.45: (01.8202389505755674, 1.8309117190894892)},
    4: {0.01: (10.983339932556953, 11.060156130783517),
        0.25: (03.4305021152837020, 3.4764695469900464),
        0.30: (02.6624323207206930, 2.703204389589173),
        0.35: (02.0431263321809440, 2.0790437132708752),
        0.40: (01.5447440594930320, 1.5761221057556805),
        0.45: (01.1459065289947180, 1.1730410135527702)},
    5: {0.01: (19.081135276668707, 19.523821224876603),
        0.20: (02.8632254471072285, 3.0376848112309776),
        0.25: (01.8225680180604158, 1.9623522646052605),
        0.30: (01.1299612119639912, 1.2406126830051296),
        0.35: (00.6871928383147943, 0.7740705901566753),
        0.40: (00.4145900446719042, 0.482655106057178)}}

@test_util.run_all_in_graph_and_eager_modes
@parameterized.parameters(np.float32, np.float64)
class LKJTest(parameterized.TestCase, tf.test.TestCase):

  def testNormConst2D(self, dtype):
    expected = 2.
    # 2x2 correlation matrices are determined by one number between -1
    # and 1, so the volume of density 1 over all of them is 2.
    answer = self.evaluate(tfd.LKJ(2, dtype([1.]))._log_normalization())
    self.assertAllClose(answer, np.log([expected]))

  def testNormConst3D(self, dtype):
    expected = np.pi**2 / 2.
    # 3x3 correlation matrices are determined by the three
    # lower-triangular entries.  In addition to being between -1 and
    # 1, they must also obey the constraint that the determinant of
    # the resulting symmetric matrix is non-negative.  The post
    # https://psychometroscar.com/the-volume-of-a-3-x-3-correlation-matrix/
    # derives (with elementary calculus) that the volume of this set
    # (with respect to Lebesgue^3 measure) is pi^2/2.  The same result
    # is also obtained by Rousseeuw, P. J., & Molenberghs,
    # G. (1994). "The shape of correlation matrices." The American
    # Statistician, 48(4), 276-279.
    answer = self.evaluate(tfd.LKJ(3, dtype([1.]))._log_normalization())
    self.assertAllClose(answer, np.log([expected]))

  def _testSampleLogProbExact(self,
                              concentrations,
                              det_bounds,
                              dim,
                              means,
                              num_samples=int(1e5),
                              dtype=np.float32,
                              target_discrepancy=0.1,
                              input_output_cholesky=False,
                              seed=42):
    # For test methodology see the comment in
    # _testSampleConsistentLogProbInterval, except that this test
    # checks those parameter settings where the true volume is known
    # analytically.
    concentration = np.array(concentrations, dtype=dtype)
    det_bounds = np.array(det_bounds, dtype=dtype)
    means = np.array(means, dtype=dtype)
    # Add a tolerance to guard against some of the importance_weights exceeding
    # the theoretical maximum (importance_maxima) due to numerical inaccuracies
    # while lower bounding the determinant. See corresponding comment in
    # _testSampleConsistentLogProbInterval.
    high_tolerance = 1e-6

    testee_lkj = tfd.LKJ(
        dimension=dim,
        concentration=concentration,
        input_output_cholesky=input_output_cholesky,
        validate_args=True)
    x = testee_lkj.sample(num_samples, seed=seed)
    importance_weights = (
        tf.exp(-testee_lkj.log_prob(x)) * _det_ok_mask(x, det_bounds,
                                                       input_output_cholesky))
    importance_maxima = (1. / det_bounds) ** (concentration - 1) * tf.exp(
        testee_lkj._log_normalization())

    chk1 = st.assert_true_mean_equal_by_dkwm(
        importance_weights, low=0., high=importance_maxima + high_tolerance,
        expected=means, false_fail_rate=1e-6)
    chk2 = assert_util.assert_less(
        st.min_discrepancy_of_true_means_detectable_by_dkwm(
            num_samples,
            low=0.,
            high=importance_maxima + high_tolerance,
            false_fail_rate=1e-6,
            false_pass_rate=1e-6), dtype(target_discrepancy))
    self.evaluate([chk1, chk2])

  def testSampleConsistentLogProb2(self, dtype):
    concentrations = np.array([
        1.00, 1.30, 1.50, 1.70, 1.90, 2.00, 2.10, 2.50, 3.00])
    det_bounds = np.array([
        0.01, 0.25, 0.30, 0.40, 0.50, 0.50, 0.50, 0.70, 0.70])
    exact_volumes = 2 * np.sqrt(1. - det_bounds)

    for input_output_cholesky in [True, False]:
      self._testSampleLogProbExact(
          concentrations,
          det_bounds,
          2,
          exact_volumes,
          num_samples=int(1.1e5),
          dtype=dtype,
          input_output_cholesky=input_output_cholesky,
          target_discrepancy=0.05,
          seed=tfp_test_util.test_seed())

  def _testSampleConsistentLogProbInterval(self,
                                           concentrations,
                                           det_bounds,
                                           dim,
                                           num_samples=int(1e5),
                                           dtype=np.float32,
                                           input_output_cholesky=False,
                                           false_fail_rate=1e-6,
                                           target_discrepancy=0.1,
                                           seed=42):
    # Consider the set M of dim x dim correlation matrices whose
    # determinant exceeds some bound (rationale for bound forthwith).
    # - This is a (convex!) shape in dim * (dim - 1) / 2 dimensions
    #   (because a correlation matrix is determined by its lower
    #   triangle, and the main diagonal is all 1s).
    # - Further, M is contained entirely in the [-1,1] cube,
    #   because no correlation can fall outside that interval.
    #
    # We have two different ways to estimate the volume of M:
    # - Importance sampling from the LKJ distribution
    # - Importance sampling from the uniform distribution on the cube
    #
    # This test checks that these two methods agree.  However, because
    # the uniform proposal leads to many rejections (thus slowness),
    # those volumes are computed offline and the confidence intervals
    # are presented to this test procedure in the "volume_bounds"
    # table.
    #
    # Why place a lower bound on the determinant?  Because for eta > 1,
    # the density of LKJ approaches 0 as the determinant approaches 0.
    # However, the test methodology requires an upper bound on the
    # improtance weights produced.  Rejecting matrices with too-small
    # determinant (from both methods) allows me to supply that bound.
    #
    # I considered several alternative regions whose volume I might
    # know analytically (without having to do rejection).
    # - Option a: Some hypersphere guaranteed to be contained inside M.
    #   - Con: I don't know a priori how to find a radius for it.
    #   - Con: I still need a lower bound on the determinants that appear
    #     in this sphere, and I don't know how to compute it.
    # - Option b: Some trapezoid given as the convex hull of the
    #   nearly-extreme correlation matrices (i.e., those that partition
    #   the variables into two strongly anti-correclated groups).
    #   - Con: Would have to dig up n-d convex hull code to implement this.
    #   - Con: Need to compute the volume of that convex hull.
    #   - Con: Need a bound on the determinants of the matrices in that hull.
    # - Option c: Same thing, but with the matrices that make a single pair
    #   of variables strongly correlated (or anti-correlated), and leaves
    #   the others uncorrelated.
    #   - Same cons, except that there is a determinant bound (which
    #     felt pretty loose).
    lows = [dtype(volume_bounds[dim][db][0]) for db in det_bounds]
    highs = [dtype(volume_bounds[dim][db][1]) for db in det_bounds]
    concentration = np.array(concentrations, dtype=dtype)
    det_bounds = np.array(det_bounds, dtype=dtype)
    # Due to possible numerical inaccuracies while lower bounding the
    # determinant, the maximum of the importance weights may exceed the
    # theoretical maximum (importance_maxima). We add a tolerance to guard
    # against this. An alternative would have been to add a threshold while
    # filtering in _det_ok_mask, but that would affect the mean as well.
    high_tolerance = 1e-6

    testee_lkj = tfd.LKJ(
        dimension=dim,
        concentration=concentration,
        input_output_cholesky=input_output_cholesky,
        validate_args=True)
    x = testee_lkj.sample(num_samples, seed=seed)
    importance_weights = (
        tf.exp(-testee_lkj.log_prob(x)) * _det_ok_mask(x, det_bounds,
                                                       input_output_cholesky))
    importance_maxima = (1. / det_bounds) ** (concentration - 1) * tf.exp(
        testee_lkj._log_normalization())
    check1 = st.assert_true_mean_in_interval_by_dkwm(
        samples=importance_weights,
        low=0.,
        high=importance_maxima + high_tolerance,
        expected_low=lows,
        expected_high=highs,
        false_fail_rate=false_fail_rate)
    check2 = assert_util.assert_less(
        st.min_discrepancy_of_true_means_detectable_by_dkwm(
            num_samples,
            low=0.,
            high=importance_maxima + high_tolerance,
            false_fail_rate=false_fail_rate,
            false_pass_rate=false_fail_rate), dtype(target_discrepancy))
    self.evaluate([check1, check2])

  def testSampleConsistentLogProbInterval3(self, dtype):
    # The hardcoded volume boundaries are (5e-7)-confidence intervals
    # of a rejection sampling run.  Ergo, I only have 5e-7 probability
    # mass left for the false fail rate of the test so the aggregate
    # false fail probability is 1e-6.
    concentrations = [
        1.00, 1.30, 1.50, 1.70, 1.90, 2.00, 2.10, 2.50, 3.00]
    det_bounds = [
        0.01, 0.25, 0.25, 0.30, 0.35, 0.35, 0.35, 0.40, 0.45]

    for input_output_cholesky in [True, False]:
      self._testSampleConsistentLogProbInterval(
          concentrations,
          det_bounds,
          3,
          dtype=dtype,
          input_output_cholesky=input_output_cholesky,
          false_fail_rate=5e-7,
          target_discrepancy=0.11,
          seed=tfp_test_util.test_seed())

  def testSampleConsistentLogProbInterval4(self, dtype):
    # The hardcoded volume boundaries are (5e-7)-confidence intervals
    # of a rejection sampling run.  Ergo, I only have 5e-7 probability
    # mass left for the false fail rate of the test so the aggregate
    # false fail probability is 1e-6.
    concentrations = [
        1.00, 1.30, 1.50, 1.70, 1.90, 2.00, 2.10, 2.50, 3.00]
    det_bounds = [
        0.01, 0.25, 0.25, 0.30, 0.35, 0.35, 0.35, 0.40, 0.45]
    for input_output_cholesky in [True, False]:
      self._testSampleConsistentLogProbInterval(
          concentrations,
          det_bounds,
          4,
          dtype=dtype,
          input_output_cholesky=input_output_cholesky,
          false_fail_rate=5e-7,
          target_discrepancy=0.22,
          seed=tfp_test_util.test_seed())

  def testSampleConsistentLogProbInterval5(self, dtype):
    # The hardcoded volume boundaries are (5e-7)-confidence intervals
    # of a rejection sampling run.  Ergo, I only have 5e-7 probability
    # mass left for the false fail rate of the test so the aggregate
    # false fail probability is 1e-6.
    concentrations = [
        1.00, 1.30, 1.50, 1.70, 1.90, 2.00, 2.10, 2.50, 3.00]
    det_bounds = [
        0.01, 0.20, 0.20, 0.25, 0.30, 0.30, 0.30, 0.35, 0.40]

    for input_output_cholesky in [True, False]:
      self._testSampleConsistentLogProbInterval(
          concentrations,
          det_bounds,
          5,
          dtype=dtype,
          input_output_cholesky=input_output_cholesky,
          false_fail_rate=5e-7,
          target_discrepancy=0.41,
          seed=tfp_test_util.test_seed())

  def testDimensionGuard(self, dtype):
    testee_lkj = tfd.LKJ(
        dimension=3, concentration=dtype([1., 4.]), validate_args=True)
    with self.assertRaisesRegexp(ValueError, 'dimension mismatch'):
      testee_lkj.log_prob(tf.eye(4))

  def testZeroDimension(self, dtype):
    testee_lkj = tfd.LKJ(
        dimension=0, concentration=dtype([1., 4.]), validate_args=True)
    results = testee_lkj.sample(sample_shape=[4, 3])
    self.assertEqual(results.shape, [4, 3, 2, 0, 0])

  def testOneDimension(self, dtype):
    testee_lkj = tfd.LKJ(
        dimension=1, concentration=dtype([1., 4.]), validate_args=True)
    results = testee_lkj.sample(sample_shape=[4, 3])
    self.assertEqual(results.shape, [4, 3, 2, 1, 1])

  def testMean(self, dtype):
    testee_lkj = tfd.LKJ(dimension=3, concentration=dtype([1., 3., 5.]))
    num_samples = 20000
    results = testee_lkj.sample(sample_shape=[num_samples])
    mean = testee_lkj.mean()
    self.assertEqual(mean.shape, [3, 3, 3])
    check1 = st.assert_true_mean_equal_by_dkwm(
        samples=results, low=-1., high=1.,
        expected=mean,
        false_fail_rate=1e-6)
    check2 = assert_util.assert_less(
        st.min_discrepancy_of_true_means_detectable_by_dkwm(
            num_samples,
            low=-1.,
            high=1.,
            # Smaller false fail rate because of different batch sizes between
            # these two checks.
            false_fail_rate=1e-7,
            false_pass_rate=1e-6),
        # 4% relative error
        0.08)
    self.evaluate([check1, check2])

class LKJTestGraphOnly(tf.test.TestCase):

  def testDimensionGuardDynamicShape(self):
    if tf.executing_eagerly():
      return
    testee_lkj = tfd.LKJ(
        dimension=3, concentration=[1., 4.], validate_args=True)
    with self.assertRaisesOpError('dimension mismatch'):
      self.evaluate(
          testee_lkj.log_prob(
              tf.compat.v1.placeholder_with_default(tf.eye(4), shape=None)))

if __name__ == '__main__':
  tf.test.main()

max_stars_repo_name: nagachika/probability

max_issues_repo_name: nagachika/probability

max_forks_repo_name: nagachika/probability


text:
# coding: utf-8
# Copyright (c) Facebook, Inc. and its affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

""" Dataset for object bounding box regression.
An axis aligned bounding box is parameterized by (cx,cy,cz) and (dx,dy,dz)
where (cx,cy,cz) is the center point of the box, dx is the x-axis length of the box.
"""
import os
import sys
import numpy as np
from torch.utils.data import Dataset
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
ROOT_DIR = os.path.dirname(BASE_DIR)
sys.path.append(ROOT_DIR)
sys.path.append(os.path.join(ROOT_DIR, 'utils'))
import pc_util
from model_util_scannet import rotate_aligned_boxes

from model_util_scannet import ScannetDatasetConfig, ScannetDatasetConfig_md40
DC = None
SDC = ScannetDatasetConfig()
SDC_md40 = ScannetDatasetConfig_md40()
MAX_NUM_OBJ = 64
MEAN_COLOR_RGB = np.array([109.8, 97.2, 83.8])

class ScannetDetectionDataset(Dataset):

    def __init__(self, split_set='train', data_path="scannet_train_detection_data_md40", num_points=20000,
        use_color=False, use_height=False, augment=False, center_jitter=0):

        global DC
        if data_path == "scannet_train_detection_data":
            DC = SDC
        else:
            DC = SDC_md40

        self.center_jitter = center_jitter

        self.data_path = os.path.join(BASE_DIR, data_path)
        all_scan_names = list(set([os.path.basename(x)[0:18] if x.startswith('scene_aug') \
            else os.path.basename(x)[0:12] for x in os.listdir(self.data_path)]))

        if split_set == 'all':
            self.scan_names = all_scan_names
        elif split_set in ['train', 'val', 'test']:
            split_filenames = os.path.join(ROOT_DIR, 'scannet/meta_data',
                'scannetv2_{}.txt'.format(split_set))
            with open(split_filenames, 'r') as f:
                self.scan_names = f.read().splitlines()
            # remove unavailiable scans
            num_scans = len(self.scan_names)
            self.scan_names = [sname for sname in self.scan_names \
                if sname in all_scan_names]
            print('kept {} scans out of {}'.format(len(self.scan_names), num_scans))
            num_scans = len(self.scan_names)
        elif split_set == 'train_aug':
            split_filenames = os.path.join(ROOT_DIR, 'scannet/meta_data',
                'scannetv2_train.txt'.format(split_set))
            with open(split_filenames, 'r') as f:
                self.scan_names = f.read().splitlines()
            # remove unavailiable scans
            self.scan_names = [sname for sname in all_scan_names \
                if sname in self.scan_names or 'aug' in sname]
            num_scans = len(self.scan_names)
            print('kept {} scans out of {}'.format(len(self.scan_names), num_scans))
            num_scans = len(self.scan_names)
        else:
            print('illegal split name')
            return

        self.num_points = num_points
        self.use_color = use_color
        self.use_height = use_height
        self.augment = augment
        if self.center_jitter != 0 and 'obj' not in self.data_path:
            #self.delta = (np.random.rand(self.__len__(), MAX_NUM_OBJ, 3) - 0.5) * self.center_jitter
            #np.save('annotation_error.npy', self.delta)
            #sys.exit(0)
            self.delta = np.load('scannet/annotation_error.npy')
        elif self.center_jitter != 0 and 'obj' in self.data_path:
            self.delta = (np.random.rand(self.__len__(), MAX_NUM_OBJ, 3) - 0.5) * self.center_jitter
        else:
            self.delta = np.zeros((self.__len__(), MAX_NUM_OBJ, 3))
        # np.array([(np.random.rand()-0.5)*self.center_jitter, (np.random.rand()-0.5)*self.center_jitter, (np.random.rand()-0.5)*self.center_jitter]) * size_gts

    def __len__(self):
        return len(self.scan_names)

    def __getitem__(self, idx):
        """
        Returns a dict with following keys:
            point_clouds: (N,3+C)
            center_label: (MAX_NUM_OBJ,3) for GT box center XYZ
            sem_cls_label: (MAX_NUM_OBJ,) semantic class index
            angle_class_label: (MAX_NUM_OBJ,) with int values in 0,...,NUM_HEADING_BIN-1
            angle_residual_label: (MAX_NUM_OBJ,)
            size_classe_label: (MAX_NUM_OBJ,) with int values in 0,...,NUM_SIZE_CLUSTER
            size_residual_label: (MAX_NUM_OBJ,3)
            box_label_mask: (MAX_NUM_OBJ) as 0/1 with 1 indicating a unique box
            point_votes: (N,3) with votes XYZ
            point_votes_mask: (N,) with 0/1 with 1 indicating the point is in one of the object's OBB.
            scan_idx: int scan index in scan_names list
            pcl_color: unused
        """

        scan_name = self.scan_names[idx]
        mesh_vertices = np.load(os.path.join(self.data_path, scan_name)+'_vert.npy')
        instance_labels = np.load(os.path.join(self.data_path, scan_name)+'_ins_label.npy')
        semantic_labels = np.load(os.path.join(self.data_path, scan_name)+'_sem_label.npy')
        instance_bboxes = np.load(os.path.join(self.data_path, scan_name)+'_bbox.npy')

        if not self.use_color:
            point_cloud = mesh_vertices[:,0:3] # do not use color for now
            pcl_color = mesh_vertices[:,3:6]
        else:
            point_cloud = mesh_vertices[:,0:6]
            point_cloud[:,3:] = (point_cloud[:,3:]-MEAN_COLOR_RGB)/256.0

        if self.use_height:
            floor_height = np.percentile(point_cloud[:,2],0.99)
            height = point_cloud[:,2] - floor_height
            point_cloud = np.concatenate([point_cloud, np.expand_dims(height, 1)],1)

        # ------------------------------- LABELS ------------------------------
        target_bboxes = np.zeros((MAX_NUM_OBJ, 6))
        target_bboxes_mask = np.zeros((MAX_NUM_OBJ))
        angle_classes = np.zeros((MAX_NUM_OBJ,))
        angle_residuals = np.zeros((MAX_NUM_OBJ,))
        size_classes = np.zeros((MAX_NUM_OBJ,))
        size_residuals = np.zeros((MAX_NUM_OBJ, 3))
        size_gts = np.zeros((MAX_NUM_OBJ, 3))

        point_cloud, choices = pc_util.random_sampling(point_cloud,
            self.num_points, return_choices=True)
        instance_labels = instance_labels[choices]
        semantic_labels = semantic_labels[choices]

        pcl_color = pcl_color[choices]

        target_bboxes_mask[0:instance_bboxes.shape[0]] = 1
        target_bboxes[0:instance_bboxes.shape[0],:] = instance_bboxes[:,0:6]

        # ------------------------------- DATA AUGMENTATION ------------------------------
        if self.augment:
            if np.random.random() > 0.5:
                # Flipping along the YZ plane
                point_cloud[:,0] = -1 * point_cloud[:,0]
                target_bboxes[:,0] = -1 * target_bboxes[:,0]

            if np.random.random() > 0.5:
                # Flipping along the XZ plane
                point_cloud[:,1] = -1 * point_cloud[:,1]
                target_bboxes[:,1] = -1 * target_bboxes[:,1]

            # Rotation along up-axis/Z-axis
            rot_angle = (np.random.random()*np.pi/18) - np.pi/36 # -5 ~ +5 degree
            rot_mat = pc_util.rotz(rot_angle)
            point_cloud[:,0:3] = np.dot(point_cloud[:,0:3], np.transpose(rot_mat))
            target_bboxes = rotate_aligned_boxes(target_bboxes, rot_mat)

        # compute votes *AFTER* augmentation
        # generate votes
        # Note: since there's no map between bbox instance labels and
        # pc instance_labels (it had been filtered
        # in the data preparation step) we'll compute the instance bbox
        # from the points sharing the same instance label.
        point_votes = np.zeros([self.num_points, 3])
        point_votes_mask = np.zeros(self.num_points)
        for i_instance in np.unique(instance_labels):
            # find all points belong to that instance
            ind = np.where(instance_labels == i_instance)[0]
            # find the semantic label
            if semantic_labels[ind[0]] in DC.nyu40ids:
                x = point_cloud[ind,:3]
                center = 0.5*(x.min(0) + x.max(0))
                point_votes[ind, :] = center - x
                point_votes_mask[ind] = 1.0
        point_votes = np.tile(point_votes, (1, 3)) # make 3 votes identical

        class_ind = [np.where(DC.nyu40ids == x)[0][0] for x in instance_bboxes[:,-1]]
        # NOTE: set size class as semantic class. Consider use size2class.
        size_classes[0:instance_bboxes.shape[0]] = class_ind
        size_residuals[0:instance_bboxes.shape[0], :] = \
            target_bboxes[0:instance_bboxes.shape[0], 3:6] - DC.mean_size_arr[class_ind,:]
        size_gts[0:instance_bboxes.shape[0], :] = target_bboxes[0:instance_bboxes.shape[0], 3:6]

        # Using center jitter to approaximate the error of human labeling
        gt_centers = target_bboxes[:,0:3]
        if self.center_jitter != 0:
            # gt_centers += np.array([np.random.rand()*0.1-0.05, np.random.rand()*0.1-0.05, np.random.rand()*0.1-0.05]) * size_gts
            # gt_centers += np.array([(np.random.rand()-0.5)*self.center_jitter, (np.random.rand()-0.5)*self.center_jitter, (np.random.rand()-0.5)*self.center_jitter]) * size_gts
            gt_centers += size_gts * self.delta[idx]

        ret_dict = {}
        ret_dict['point_clouds'] = point_cloud.astype(np.float32)
        ret_dict['center_label'] = gt_centers.astype(np.float32)
        ret_dict['center_jitter'] = (size_gts * self.delta[idx]).astype(np.float32)
        ret_dict['heading_class_label'] = angle_classes.astype(np.int64)
        ret_dict['heading_residual_label'] = angle_residuals.astype(np.float32)
        ret_dict['size_class_label'] = size_classes.astype(np.int64)
        ret_dict['size_residual_label'] = size_residuals.astype(np.float32)
        ret_dict['size_gts'] = size_gts.astype(np.float32)
        target_bboxes_semcls = np.zeros((MAX_NUM_OBJ))
        target_bboxes_semcls[0:instance_bboxes.shape[0]] = \
            [DC.nyu40id2class[x] for x in instance_bboxes[:,-1][0:instance_bboxes.shape[0]]]
        ret_dict['sem_cls_label'] = target_bboxes_semcls.astype(np.int64)
        try:
            ret_dict['cloud_label'] = np.eye(22)[ret_dict['sem_cls_label'][0:instance_bboxes.shape[0]]].max(axis=0)
        except:
            ret_dict['cloud_label'] = np.zeros(22)
        ret_dict['box_label_mask'] = target_bboxes_mask.astype(np.float32)
        ret_dict['vote_label'] = point_votes.astype(np.float32)
        ret_dict['vote_label_mask'] = point_votes_mask.astype(np.int64)
        ret_dict['scan_idx'] = np.array(idx).astype(np.int64)
        ret_dict['pcl_color'] = pcl_color
        return ret_dict

############# Visualizaion ########

def viz_votes(pc, point_votes, point_votes_mask, name=''):
    """ Visualize point votes and point votes mask labels
    pc: (N,3 or 6), point_votes: (N,9), point_votes_mask: (N,)
    """
    inds = (point_votes_mask==1)
    pc_obj = pc[inds,0:3]
    pc_obj_voted1 = pc_obj + point_votes[inds,0:3]
    pc_util.write_ply(pc_obj, 'pc_obj{}.ply'.format(name))
    pc_util.write_ply(pc_obj_voted1, 'pc_obj_voted1{}.ply'.format(name))

def viz_obb(pc, label, mask, angle_classes, angle_residuals,
    size_classes, size_residuals, name=''):
    """ Visualize oriented bounding box ground truth
    pc: (N,3)
    label: (K,3)  K == MAX_NUM_OBJ
    mask: (K,)
    angle_classes: (K,)
    angle_residuals: (K,)
    size_classes: (K,)
    size_residuals: (K,3)
    """
    oriented_boxes = []
    K = label.shape[0]
    for i in range(K):
        if mask[i] == 0: continue
        obb = np.zeros(7)
        obb[0:3] = label[i,0:3]
        heading_angle = 0 # hard code to 0
        box_size = DC.mean_size_arr[size_classes[i], :] + size_residuals[i, :]
        obb[3:6] = box_size
        obb[6] = -1 * heading_angle
        print(obb)
        oriented_boxes.append(obb)
    pc_util.write_oriented_bbox(oriented_boxes, 'gt_obbs{}.ply'.format(name))
    pc_util.write_ply(label[mask==1,:], 'gt_centroids{}.ply'.format(name))

if __name__=='__main__':
    dset = ScannetDetectionDataset(use_height=True, num_points=40000)

    count_sum = np.zeros((22, 22))
    for d in dset:
        cl = d['cloud_label']
        idx_list = []
        for i in range(22):
            if cl[i] == 1.0:
                idx_list.append(i)
        for i in idx_list:
            for j in idx_list:
                count_sum[i][j] += 1
    np.save('context_vectors.npy', count_sum)

    context_vectors = np.load('context_vectors.npy')
    cl_rate = 0.3
    # list of tuple (scene_idx, score)
    bathtub = []
    bench = []
    dresser = []
    laptop = []
    wardrobe = []
    bathtub_vector = context_vectors[0] / context_vectors[0][0]
    bathtub_vector[0] = 0
    bench_vector = context_vectors[2] / context_vectors[2][2]
    bench_vector[2] = 0
    dresser_vector = context_vectors[10] / context_vectors[10][10]
    dresser_vector[10] = 0
    laptop_vector = context_vectors[13] / context_vectors[13][13]
    laptop_vector[13] = 0
    wardrobe_vector = context_vectors[21] / context_vectors[21][21]
    wardrobe_vector[21] = 0
    for d in dset:
        cl = d['cloud_label']
        if cl[4] + cl[6] + cl[11] == 0:
            continue
        scan_name = dset.scan_names[d['scan_idx']]
        bathtub.append((scan_name, np.dot(cl, bathtub_vector) - cl_rate * sum(cl)))
        bench.append((scan_name, np.dot(cl, bench_vector) - cl_rate * sum(cl)))
        dresser.append((scan_name, np.dot(cl, dresser_vector) - cl_rate * sum(cl)))
        laptop.append((scan_name, np.dot(cl, laptop_vector) - cl_rate * sum(cl)))
        wardrobe.append((scan_name, np.dot(cl, wardrobe_vector) - cl_rate * sum(cl)))
    bathtub = sorted(bathtub, key=lambda x: x[1], reverse=True)[:40]
    bench = sorted(bench, key=lambda x: x[1], reverse=True)[:70]
    dresser = sorted(dresser, key=lambda x: x[1], reverse=True)[:15]
    laptop = sorted(laptop, key=lambda x: x[1], reverse=True)[:55]
    wardrobe = sorted(wardrobe, key=lambda x: x[1], reverse=True)[:50]
    bathtub_scan = [x[0] for x in bathtub]
    bench_scan = [x[0] for x in bench]
    dresser_scan = [x[0] for x in dresser]
    laptop_scan = [x[0] for x in laptop]
    wardrobe_scan = [x[0] for x in wardrobe]
    print([bathtub_scan, bench_scan, dresser_scan, laptop_scan, wardrobe_scan])
    np.save('scans_toadd_scarce.npy', [bathtub_scan, bench_scan, dresser_scan, laptop_scan, wardrobe_scan])

max_stars_repo_name: wyf-ACCEPT/BackToReality

max_issues_repo_name: wyf-ACCEPT/BackToReality

max_forks_repo_name: wyf-ACCEPT/BackToReality


text:
#!/usr/bin/env python

"""
This is a simple script to train an LSTM model for generating scientific
article titles.
To use default arguments, simply run in your terminal using

    python lstmtrainer.py

If you wish to use custom arguments, just run

    python lstmtrainer.py -h

to get a list of the arguments you can pass.

NOTE:
The following code is heavily based on the following keras example:
https://github.com/fchollet/keras/blob/master/examples/lstm_text_generation.py
(see contributors for credits)

"""

from __future__ import print_function
import numpy as np
import random
import os
import sys
import argparse
from keras.models import Sequential
from keras.layers import LSTM, Dense, Activation
from keras.optimizers import RMSprop

__author__ = "Jacopo Credi"
__license__ = "MIT"
__version__ = "1.4.1-rc"
__email__ = "jacopo.credi@gmail.com"

parser = argparse.ArgumentParser(description='Trains an LSTM for scientific paper titles generation.')
parser.add_argument('--dataDumpPath', dest='dump_file_path', default=os.getcwd()+'/data/dump.csv', help='Path to text corpus file. Default: "<current_working_directory>/data_dump/arxiv_dump.csv"')
parser.add_argument('--sequenceLength', dest='seq_length', type=int, default=40, help='Length of sequences to be extracted from the corpus. Default: 40')
parser.add_argument('--step', dest='step', type=int, default=3, help='Steps by which the corpus will be cut into sequences. Default: 3')
parser.add_argument('--lstmUnits', dest='lstm_units', type=int, default=128, help='Number of LSTM units. Default: 128')
parser.add_argument('--epochs', dest='epochs', type=int, default=60, help='Number of training epochs. Default: 60')
parser.add_argument('--learningRate', dest='learning_rate', type=float, default=0.01, help='Learning rate used by the RMSprop optimizer. Default: 0.01')
parser.add_argument('--batchSize', dest='batch_size', type=int, default=128, help='Mini-batch size. Default: 128')
parser.add_argument('--temperature', dest='temperature', type=float, default=0.5, help='Controls the randomness level in the generation of new sequences. Default: 0.5')
parser.add_argument('--outputSequenceLength', dest='output_seq_length', type=int, default=400, help='Length of the generated text to be displayed after each epoch. Default: 400')

args = parser.parse_args()

# retrieve dumped data
titles = []
with open(args.dump_file_path, 'r') as data_dump_file:
    for line in data_dump_file:
        titles.append(line.rstrip())

corpus = '. '.join(titles)
print('Corpus length:', len(corpus))

chars = sorted(list(set(corpus)))
print('Total chars:', len(chars))
char_indices = dict((c, i) for i, c in enumerate(chars))
indices_char = dict((i, c) for i, c in enumerate(chars))

# cut the text in semi-redundant sequences of maxlen characters
maxlen = args.seq_length
step = args.step
sequences = []
next_chars = []
for i in range(0, len(corpus) - maxlen, step):
    sequences.append(corpus[i: i + maxlen])
    next_chars.append(corpus[i + maxlen])
print('Number of sequences:', len(sequences))

print('One-hot vectorization...')
X = np.zeros((len(sequences), maxlen, len(chars)), dtype=np.bool)
y = np.zeros((len(sequences), len(chars)), dtype=np.bool)
for i, sequence in enumerate(sequences):
    for t, char in enumerate(sequence):
        X[i, t, char_indices[char]] = 1
    y[i, char_indices[next_chars[i]]] = 1

# build the model: a single LSTM
print('Build model...')
model = Sequential()
model.add(LSTM(args.lstm_units, input_shape=(maxlen, len(chars))))
model.add(Dense(len(chars)))
model.add(Activation('softmax'))

optimizer = RMSprop(lr=args.learning_rate)
model.compile(loss='categorical_crossentropy', optimizer=optimizer)

def sample(preds, temperature=1.0):
    # helper function to sample an index from a probability array
    preds = np.asarray(preds).astype('float64')
    preds = np.log(preds) / temperature
    exp_preds = np.exp(preds)
    preds = exp_preds / np.sum(exp_preds)
    probas = np.random.multinomial(1, preds, 1)
    return np.argmax(probas)

# train the model, output generated text after each epoch
for epoch in range(1, args.epochs):
    print()
    print('-' * 50)
    print('Epoch ', epoch)
    model.fit(X, y, batch_size=args.batch_size, nb_epoch=1)

    start_index = random.randint(0, len(corpus) - maxlen - 1)
    generated = ''
    sequence = corpus[start_index: start_index + maxlen]
    generated += sequence
    print('----- Generating with seed: "' + sequence + '"')
    sys.stdout.write(generated)

    for i in range(args.output_seq_length):
        x = np.zeros((1, maxlen, len(chars)))
        for t, char in enumerate(sequence):
            x[0, t, char_indices[char]] = 1.

        preds = model.predict(x, verbose=0)[0]
        next_index = sample(preds, args.temperature)
        next_char = indices_char[next_index]

        generated += next_char
        sequence = sequence[1:] + next_char

        sys.stdout.write(next_char)
        sys.stdout.flush()
print()

max_stars_repo_name: jcredi/article-titles-generator

max_issues_repo_name: jcredi/paper-titles-lstm-generator

max_forks_repo_name: jcredi/paper-titles-lstm-generator


text:
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'DataLogger.ui'
#
# Created by: PyQt5 UI code generator 5.10.1
#
# WARNING! All changes made in this file will be lost!

'''
This file is used to run the back-end of the data collected. It creates
'''

from PyQt5 import QtCore, QtGui, QtWidgets
import matplotlib
import sys
matplotlib.use("Qt5Agg")
import numpy as np
import numpy.random as random
import serial
import warnings
from serial import SerialException, portNotOpenError, Serial
import serial.tools.list_ports as list_ports
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import time
from collections import deque
import struct
from scipy.signal import butter, filtfilt, lfilter, lfilter_zi

# class Ui_DataLoggerMainWindow(object):
#     def setupUi(self, DataLoggerMainWindow):
#         DataLoggerMainWindow.setObjectName("DataLoggerMainWindow")
#         DataLoggerMainWindow.resize(1138, 732)
#         self.centralwidget = QtWidgets.QWidget(DataLoggerMainWindow)
#         self.centralwidget.setObjectName("centralwidget")
#         self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.centralwidget)
#         self.verticalLayout_3.setObjectName("verticalLayout_3")
#         self.mpl_plot = DynamicMplCanvas(self.centralwidget)
#         sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
#         sizePolicy.setHorizontalStretch(0)
#         sizePolicy.setVerticalStretch(0)
#         sizePolicy.setHeightForWidth(self.mpl_plot.sizePolicy().hasHeightForWidth())
#         self.mpl_plot.setSizePolicy(sizePolicy)
#         self.mpl_plot.setObjectName("mpl_plot")

#         # self.verticalLayout_3.addWidget(self.mpl_plot)
#         # self.horizontalLayout = QtWidgets.QHBoxLayout()
#         # self.horizontalLayout.setObjectName("horizontalLayout")
#         # self.startButton = QtWidgets.QPushButton(self.centralwidget)
#         # # self.startButton.setObjectName("startButton")
#         # # self.horizontalLayout.addWidget(self.startButton)
#         # # self.stopButton = QtWidgets.QPushButton(self.centralwidget)
#         # # self.stopButton.setObjectName("stopButton")
#         # # self.horizontalLayout.addWidget(self.stopButton)
#         # # self.saveButton = QtWidgets.QPushButton(self.centralwidget)
#         # # self.saveButton.setObjectName("saveButton")
#         # # self.horizontalLayout.addWidget(self.saveButton)
#         # spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
#         # self.horizontalLayout.addItem(spacerItem)
#         # self.verticalLayout_3.addLayout(self.horizontalLayout)
#         # DataLoggerMainWindow.setCentralWidget(self.centralwidget)
#         # self.menubar = QtWidgets.QMenuBar(DataLoggerMainWindow)
#         # self.menubar.setGeometry(QtCore.QRect(0, 0, 1138, 22))
#         # self.menubar.setObjectName("menubar")
#         # self.menuDatalogger = QtWidgets.QMenu(self.menubar)
#         # self.menuDatalogger.setObjectName("menuDatalogger")
#         # DataLoggerMainWindow.setMenuBar(self.menubar)
#         # self.statusbar = QtWidgets.QStatusBar(DataLoggerMainWindow)
#         # self.statusbar.setObjectName("statusbar")
#         # DataLoggerMainWindow.setStatusBar(self.statusbar)
#         # self.menubar.addAction(self.menuDatalogger.menuAction())

#         # self.retranslateUi(DataLoggerMainWindow)
#         # self.startButton.clicked.connect(self.mpl_plot.start)
#         # self.stopButton.clicked.connect(self.mpl_plot.stop)
#         # self.saveButton.clicked.connect(self.mpl_plot.save)
#         # QtCore.QMetaObject.connectSlotsByName(DataLoggerMainWindow)

#     def retranslateUi(self, DataLoggerMainWindow):
#         _translate = QtCore.QCoreApplication.translate
#         DataLoggerMainWindow.setWindowTitle(_translate("DataLoggerMainWindow", "MainWindow"))
#         # self.startButton.setText(_translate("DataLoggerMainWindow", "Start"))
#         # self.stopButton.setText(_translate("DataLoggerMainWindow", "Stop"))
#         # self.saveButton.setText(_translate("DataLoggerMainWindow", "Save Data"))
#         # self.menuDatalogger.setTitle(_translate("DataLoggerMainWindow", "Datalogger"))

class MplCanvas(FigureCanvas):

    def __init__(self, parent=None):
        fig = Figure()
        self.ax = fig.add_subplot(111)
        self.compute_initial_figure()
        super().__init__(fig)

        self.setParent(parent)
        FigureCanvas.setSizePolicy(self, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)

    def compute_initial_figure(self):
        pass

class DynamicMplCanvas(MplCanvas):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.parent = kwargs["parent"]

    def compute_initial_figure(self):
        self.ax.set_ylim(0,10)
        self.ax.set_facecolor("black")
        self.ax.grid(color='gray', linestyle='--')

    def update_figure(self):

        unpacked = struct.unpack("B"*len(self.parent.raw_data), self.parent.raw_data)

        if len(unpacked) > 0:

            self.parent.raw_data = b''
            i = 0
            while i < len(unpacked):
                if i%(self.parent.BUF_SIZE) == 0 and i !=self.parent.BUF_SIZE:
                    t = (unpacked[i] + unpacked[i+1]*256 + unpacked[i+2]*256**2
                        +unpacked[i+3]*256**3)/1e6
                    i += 4
                    if abs(t - self.parent.time_buffer[-1]) < 1/(self.parent.sample_rate*1.05):
                        t = self.parent.time_buffer[-1] + 1/self.parent.sample_rate
                    voltage = unpacked[i]*self.parent.proportion

                else:
                    voltage = unpacked[i]*self.parent.proportion

                    t = self.parent.time_buffer[-1] + 1/(self.parent.sample_rate)

                self.parent.time_buffer.append(t)
                self.parent.filter_buffer.append(voltage)

                i += 1

            self.ax.cla()

            if self.parent.j == 0:
                self.parent.filter_z = lfilter_zi(self.parent.butter_b, self.parent.butter_a)
            self.parent.time_buffer.popleft()
            self.parent.filter_buffer.popleft()
            if self.parent.lp_state:
                temp, self.parent.filter_z = lfilter(self.parent.butter_b, self.parent.butter_a,self.parent.filter_buffer, zi=self.parent.filter_z)
                self.parent.ydata.extend(temp)
                self.parent.filter_buffer.clear()
                self.parent.filter_buffer.append(temp[-1])
                k = 0
                while k < len(temp):
                    self.parent.results.append([self.parent.time_buffer[k], temp[k]])
                    k += 1
            else:
                self.parent.ydata.extend(self.parent.filter_buffer)
                k = 0

                while k < len(self.parent.time_buffer):
                    self.parent.results.append([self.parent.time_buffer[k], self.parent.filter_buffer[k]])
                    k += 1
                last_voltage = self.parent.filter_buffer.pop()
                self.parent.filter_buffer.clear()
                self.parent.filter_buffer.append(last_voltage)

            self.parent.xdata.extend(self.parent.time_buffer)

            last_time = self.parent.time_buffer.pop()
            self.parent.time_buffer.clear()
            self.parent.time_buffer.append(last_time)

            self.parent.j = i

            self.ax.plot(self.parent.xdata, self.parent.ydata, "y-")
            self.ax.set_xlim(-self.parent.delta+self.parent.xdata[len(self.parent.xdata)-1], self.parent.xdata[len(self.parent.xdata)-1])
            self.ax.set_ylim(0+self.parent.voltage_offset,self.parent.ylim+self.parent.voltage_offset)
            self.ax.set_facecolor("black")
            self.ax.grid(color='gray', linestyle='--')
            self.draw()

class DataCollector(QtCore.QThread):

    def __init__(self, parent):
        super().__init__()
        self.parent = parent

    def run(self):
        while True:
            if self.parent.arduino.in_waiting >= self.parent.BUF_SIZE:

                self.parent.raw_data += self.parent.arduino.read(size=self.parent.BUF_SIZE)

if __name__ == "__main__":
    ser = find_arduino()
    app = QtWidgets.QApplication(sys.argv)
    window = DataLogger()
    # ui = Ui_DataLoggerMainWindow()
    # ui.setupUi(window)
    window.show()

    arduino = find_arduino()
    if not arduino:
        err = QtWidgets.QErrorMessage()
        err.showMessage("No arduinos found! Are you sure it is connected properly?")
        # raise IOError("No Arduino")
    if len(arduino) > 1:
        warn = QtWidgets.QMessageBox()
        warn.setText("Multiple Arduinos found. Usinig the first one.")
        warn.setIcon(QtWidgets.QMessageBox.Warning)
        warn.show()

    if arduino:
        arduino = Serial(port=arduino[0], baudrate=2000000)
        window.mpl_plot.arduino = arduino

    sys.exit(app.exec_())

max_stars_repo_name: ZakEspley/ArduinoUnoDataLogger

max_issues_repo_name: ZakEspley/ArduinoUnoDataLogger

max_forks_repo_name: ZakEspley/ArduinoUnoDataLogger

reason: import numpy,from scipy


text:
# This code is licensed under the MIT License (see LICENSE file for details)

import json
from PyQt5 import Qt
import numpy
from .object_model import uniform_signaling_list
from . import image
from . import layer

class LayerList(uniform_signaling_list.UniformSignalingList):
    @classmethod
    def from_json(cls, json_str):
        prop_stack = json.loads(json_str)['layer property stack']
        layers = cls()
        for props in prop_stack:
            layers.append(layer.Layer.from_savable_properties_dict(props))
        return layers

    def to_json(self):
        return json.dumps({'layer property stack':
                            [layer.get_savable_properties_dict() for layer in self]},
            ensure_ascii=False, indent=1)

    def take_input_element(self, obj):
        if isinstance(obj, (numpy.ndarray, image.Image)):
            return layer.Layer(obj)
        elif isinstance(obj, layer.Layer):
            return obj
        else:
            raise TypeError("All inputs must be numpy.ndarray, Image, or Layer")

class LayerStack(Qt.QObject):
    """LayerStack: The owner of a LayerList (L.layers, in ascending order, with bottom layer - ie, backmost - as element 0) and selection model that is
    referenced by various other objects such as LayerStackItem, LayerTable, RisWidget, and Flipbooks.

    Signals:
    * layer_focus_changed(layer_stack, old_focused_layer, new_focused_layer): layer_stack.focused_layer changed from old_focused layer to focused_layer,
    its current value.
    * focused_image_changed(new_focused_image): The image of the currently-focused layer has changed, either because the foused layer
    itself has changed, or the image in that layer was replaced or modified in-place.

    """
    layer_focus_changed = Qt.pyqtSignal(Qt.QObject, object, object)
    focused_image_changed = Qt.pyqtSignal(object)

    def __init__(self, parent=None):
        super().__init__(parent)

        self._layers = LayerList()
        self._layers.inserting.connect(self._on_inserting_into_layers)
        self._layers.removing.connect(self._on_removing_from_layers)
        self._layers.replacing.connect(self._on_replacing_in_layers)
        self._layers.replaced.connect(self._on_replaced_in_layers)
        self.layer_focus_changed.connect(self._on_layer_focus_changed)

        self._histogram_mask = None
        self._selection_model = None
        self.auto_min_max_all_action = Qt.QAction(self)
        self.auto_min_max_all_action.setText('Auto Min/Max')
        self.auto_min_max_all_action.setCheckable(True)
        self.auto_min_max_all_action.setChecked(True)
        # From the Qt docs: The triggered signal is emitted when an action is activated by the user; for example, when the user clicks a menu option,
        # toolbar button, or presses an action's shortcut key combination, or when trigger() was called. Notably, it is not emitted when setChecked()
        # or toggle() is called.
        self.auto_min_max_all_action.triggered.connect(self._on_master_enable_auto_min_max_triggered)
        # From the Qt docs: The toggled signal is emitted whenever a checkable action changes its isChecked() status. This can be the result of a user
        # interaction, or because setChecked() was called.
        self.auto_min_max_all_action.toggled.connect(self._on_master_enable_auto_min_max_toggled)
        self.solo_layer_mode_action = Qt.QAction(self)
        self.solo_layer_mode_action.setText('Solo Current Layer')
        self.solo_layer_mode_action.setCheckable(True)
        self.solo_layer_mode_action.setChecked(False)
        self.solo_layer_mode_action.setToolTip('Show only the currently selected layer')

        self.layers.append(layer.Layer())

    @property
    def layers(self):
        return self._layers

    @layers.setter
    def layers(self, new_layers):
        num_new_layers = len(new_layers)
        num_extant_layers = len(self._layers)
        for i in range(max(num_new_layers, num_extant_layers)):
            if i >= num_new_layers:
                self._layers[i].image = None
            elif i >= num_extant_layers:
                self._layers.append(new_layers[i])
            else:
                new_layer = new_layers[i]
                if isinstance(new_layer, layer.Layer):
                    self._layers[i] = new_layer
                else:
                    self._layers[i].image = new_layer

    def set_selection_model(self, selection_model):
        assert isinstance(selection_model, Qt.QItemSelectionModel)
        if self._selection_model is not None:
            raise RuntimeError('only set selection model once, immediately after construction')
        selection_model.currentRowChanged.connect(self._on_current_row_changed)
        self._selection_model = selection_model
        self.ensure_layer_focused()

    @property
    def focused_layer_idx(self):
        sm = self._selection_model
        if self._selection_model is None:
            return None
        m = self._selection_model.model()
        midx = sm.currentIndex()
        if isinstance(m, Qt.QAbstractProxyModel):
            # Selection model is with reference to table view's model, which is a proxy model (probably an InvertingProxyModel)
            if not midx.isValid():
                return None
            midx = m.mapToSource(midx)
        if midx.isValid():
            return midx.row()

    @property
    def focused_layer(self):
        """Note: L.focused_layer is equivalent to L.layers[L.focused_layer_idx]."""
        idx = self.focused_layer_idx
        return None if idx is None else self._layers[idx]

    @focused_layer.setter
    def focused_layer(self, v):
        idx = self.focused_layer_idx
        if idx is None:
            raise IndexError('No layer is currently focused.')
        self._layers[idx] = v

    @property
    def focused_image(self):
        idx = self.focused_layer_idx
        return None if idx is None else self._layers[idx].image

    @property
    def examine_layer_mode(self):
        return self.solo_layer_mode_action.isChecked()

    @examine_layer_mode.setter
    def examine_layer_mode(self, v):
        self.solo_layer_mode_action.setChecked(v)

    @property
    def auto_min_max_all(self):
        return self.auto_min_max_all_action.isChecked()

    @auto_min_max_all.setter
    def auto_min_max_all(self, v):
        self.auto_min_max_all_action.setChecked(v)

    @property
    def histogram_mask(self):
        return self._histogram_mask

    @histogram_mask.setter
    def histogram_mask(self, r):
        for layer in self.layers:
            layer.histogram_mask = r

    def ensure_layer_focused(self):
        """If we have both a layer list & selection model and no Layer is selected & .layers is not empty:
           If there is a "current" layer, IE highlighted but not selected, select it.
           If there is no "current" layer, make .layer_stack[0] current and select it."""
        sm = self._selection_model
        if sm is None:
            return
        m = sm.model()
        if not sm.currentIndex().isValid():
            sm.setCurrentIndex(m.index(0, 0), Qt.QItemSelectionModel.SelectCurrent | Qt.QItemSelectionModel.Rows)
        if len(sm.selectedRows()) == 0:
            sm.select(sm.currentIndex(), Qt.QItemSelectionModel.SelectCurrent | Qt.QItemSelectionModel.Rows)

    def _attach_layers(self, layers):
        auto_min_max_all = self.auto_min_max_all
        for layer in layers:
            layer.histogram_mask = self.histogram_mask
            if auto_min_max_all:
                layer.auto_min_max = True
            # can connect without worrying that it's already connected because LayerList guarantees
            # that a given layer can only be in the lost
            layer.auto_min_max_changed.connect(self._on_layer_auto_min_max_changed)

    def _detach_layers(self, layers):
        for layer in layers:
            layer.auto_min_max_changed.disconnect(self._on_layer_auto_min_max_changed)

    def _on_inserting_into_layers(self, idx, inserted_layers):
        self._attach_layers(inserted_layers)

    def _on_removing_from_layers(self, idxs, removed_layers):
        self._detach_layers(removed_layers)

    def _on_replacing_in_layers(self, idxs, replaced_layers, layers):
        self._detach_layers(replaced_layers)
        self._attach_layers(layers)

    def _on_replaced_in_layers(self, idxs, old_layers, new_layers):
        if self._selection_model is None:
            return
        try:
            focused_idx = idxs.index(self.focused_layer_idx)
        except ValueError:
            return
        old_focused, new_focused = old_layers[focused_idx], new_layers[focused_idx]
        if old_focused is not new_focused:
            self.layer_focus_changed.emit(self, old_focused, new_focused)

    def _on_current_row_changed(self, midx, old_midx):
        # TODO: verify that this happens in response to signaling list removing signal and not removed signal
        if self._selection_model is None:
            return
        m = self._selection_model.model()
        if isinstance(m, Qt.QAbstractProxyModel):
            if old_midx.isValid():
                old_midx = m.mapToSource(old_midx)
            if midx.isValid():
                midx = m.mapToSource(midx)
        old_layer = self._layers[old_midx.row()] if old_midx.isValid() else None
        new_layer = self._layers[midx.row()] if midx.isValid() else None
        if new_layer is not old_layer:
            self.layer_focus_changed.emit(self, old_layer, new_layer)

    def _on_master_enable_auto_min_max_triggered(self, checked):
        # Disable auto min/max for all Layers in this LayerStack when auto min/max is explicitly deactivated but not when auto min/max is deactivated as
        # a result of assignment to a constituent Layer's min or max properties.
        if not checked:
            for layer in self.layers:
                layer.auto_min_max = False

    def _on_master_enable_auto_min_max_toggled(self, checked):
        if checked and self._layers:
            for layer in self._layers:
                layer.auto_min_max = True

    def _on_layer_auto_min_max_changed(self, layer):
        if self.auto_min_max_all and not layer.auto_min_max:
            self.auto_min_max_all = False

    def _on_layer_focus_changed(self, layer_stack, old_focused_layer, new_focused_layer):
        if old_focused_layer is not None:
            old_focused_layer.image_changed.disconnect(self._on_focused_layer_image_changed)
        if new_focused_layer is not None:
            new_focused_layer.image_changed.connect(self._on_focused_layer_image_changed)
        image = None if new_focused_layer is None else new_focused_layer.image
        self.focused_image_changed.emit(image)

    def _on_focused_layer_image_changed(self, focused_layer):
        self.focused_image_changed.emit(focused_layer.image)

max_stars_repo_name: drew-sinha/RisWidget

max_issues_repo_name: drew-sinha/RisWidget

max_forks_repo_name: drew-sinha/RisWidget


text:
import numpy as np
import sklearn
import subprocess
from sklearn import model_selection, tree

import data
import feature_selection

def ordered_difference(list1, list2):
    out_list = []
    for elt in list1:
        if elt not in list2:
            out_list.append(elt)
    return out_list

def get_bad_questions():
    f = open("../extern/manage_data/list_unnecessary_columns.txt", 'r')
    bad_questions = f.readline().split(',')
    bad_questions[-1] = bad_questions[-1][:-1]  # chop the \n off the end
    bad_questions.remove('weight')  # need weight for training
    return bad_questions

def separate_weights(X_train, column_names):
    """
    Removes the column containing weights from X_train, and returns it as
    a separate array.
    """
    weight_column_idx = column_names.index('weight')
    weights = X_train[:, weight_column_idx]
    new_X_train = np.delete(X_train, weight_column_idx, axis=1)
    return new_X_train, weights

def main():
    # grab and split data
    poll_data = data.PollDataProxy(remove_nan=True, convert_to_float=True)
    all_data, all_data_questions = poll_data.all_data_except(get_bad_questions())
    X = all_data[:, :-1]
    y = all_data[:, -1]
    X_train, X_test, y_train, y_test = model_selection.train_test_split(X, y,
                                                                        test_size=0.1,
                                                                        shuffle=True)
    X_train, weights_train = separate_weights(X_train, all_data_questions[:-1])
    X_test, weights_test = separate_weights(X_test, all_data_questions[:-1])
    print("Number of Training Samples:", len(X_train))
    print("Number of Testing Samples:", len(X_test))

    # create data dictionary and cast values to ints
    data_dict = {
        'X_train': X_train.astype(np.int32),
        'X_test': X_test.astype(np.int32),
        'y_train': y_train.astype(np.int32),
        'y_test': y_test.astype(np.int32)
    }

    # get best features
    chi2_ftsel = feature_selection.FeatureSelection(
        necess_que_file="../extern/manage_data/list_all_questions.txt",
        unnecess_que_file="../extern/manage_data/list_unnecessary_columns.txt",
        bool_necess_que=False,
        run_name="test_chi2"
    )
    ### This doesn't work anymore, data needs to not be negative for some reason
    data_ftsel_dict, ftsel_questions = chi2_ftsel.ftsel_KBest(data_dict['X_train'],
                                                              data_dict['y_train'],
                                                              data_dict['X_test'],
                                                              K=20)
    ftsel_X_train = data_ftsel_dict['X_train']
    ftsel_X_test = data_ftsel_dict['X_test']
    ftsel_y_train = data_ftsel_dict['y_train']
    ftsel_y_test = data_ftsel_dict['y_test']

    # dictionary for hyperparameter search
    param_space = {
        'criterion': ['gini', 'entropy'],
        'max_depth': [2, 3, 4, 5, 7],
        'min_samples_split': [2, 5, 10],
        'min_samples_leaf': [2, 5, 10],
        'max_leaf_nodes': [2, 4, 6, 8, 10, 12, 15],
    }

    # determine best parameters
    dt_clf = tree.DecisionTreeClassifier()
    grid_search = model_selection.GridSearchCV(dt_clf, param_space, cv=5,
                                               scoring='accuracy', verbose=1)
    grid_search.fit(ftsel_X_train, ftsel_y_train, sample_weight=weights_train)
    best_params = grid_search.best_params_
    print("Best parameters:\n{}".format(best_params))

    # train the model with the best parameters, and report test/train accuracy
    clf = tree.DecisionTreeClassifier(**best_params)
    clf.fit(ftsel_X_train, ftsel_y_train, sample_weight=weights_train)
    pred_y_test = clf.predict(ftsel_X_test)
    test_acc = sklearn.metrics.accuracy_score(pred_y_test, ftsel_y_test)
    print("Test Accuracy: {}".format(test_acc))
    pred_y_train = clf.predict(ftsel_X_train)
    train_acc = sklearn.metrics.accuracy_score(pred_y_train, ftsel_y_train)
    print("Train Accuracy: {}".format(train_acc))

    # write the graph data to a dot file
    class_names = ['rarely/never', 'sporadic', 'always']
    graph_data = tree.export_graphviz(clf,
                                      out_file="graph.dot",
                                      feature_names=ftsel_questions,
                                      class_names=class_names,
                                      filled=True,
                                      rounded=True,
                                      special_characters=True)
    # write the .dot file to a png
    command = "dot -Tpng graph.dot -o graph1.png"
    process = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
    process.communicate()

if __name__ == "__main__":
    main()

max_stars_repo_name: tommy-waltmann/voting-ml

max_issues_repo_name: tommy-waltmann/voting-ml

max_forks_repo_name: tommy-waltmann/voting-ml