Пример #1
0
def adjoining_cuts(cuts, bit, board):
    '''
    Given the cuts on an edge, computes the cuts on the adjoining edge.

    cuts: An array of Cut objects
    bit: A Router_Bit object
    board: A Board object

    Returns an array of Cut objects
    '''
    nc = len(cuts)
    adjCuts = []
    # if the left-most input cut does not include the left edge, add an
    # adjoining cut that includes the left edge
    if cuts[0].xmin > 0:
        left = 0
        right = my_round(cuts[0].xmin + bit.offset) - board.dheight
        if right - left >= board.dheight:
            adjCuts.append(Cut(left, right))
    # loop through the input cuts and form an adjoining cut, formed
    # by looking where the previous cut ended and the current cut starts
    for i in lrange(1, nc):
        left = my_round(cuts[i-1].xmax - bit.offset + board.dheight)
        right = max(left + bit.width, my_round(cuts[i].xmin + bit.offset) - board.dheight)
        adjCuts.append(Cut(left, right))
    # if the right-most input cut does not include the right edge, add an
    # adjoining cut that includes this edge
    if cuts[-1].xmax < board.width:
        left = my_round(cuts[-1].xmax - bit.offset) + board.dheight
        right = board.width
        if right - left >= board.dheight:
            adjCuts.append(Cut(left, right))
    return adjCuts
Пример #2
0
def adjoining_cuts(cuts, bit, board):
    '''
    Given the cuts on an edge, computes the cuts on the adjoining edge.

    cuts: An array of Cut objects
    bit: A Router_Bit object
    board: A Board object

    Returns an array of Cut objects
    '''
    nc = len(cuts)
    adjCuts = []
    # if the left-most input cut does not include the left edge, add an
    # adjoining cut that includes the left edge
    if cuts[0].xmin > 0:
        left = 0
        right = my_round(cuts[0].xmin + bit.offset) - board.dheight
        if right - left >= board.dheight:
            adjCuts.append(Cut(left, right))
    # loop through the input cuts and form an adjoining cut, formed
    # by looking where the previous cut ended and the current cut starts
    for i in lrange(1, nc):
        left = my_round(cuts[i - 1].xmax - bit.offset + board.dheight)
        right = max(left + bit.width,
                    my_round(cuts[i].xmin + bit.offset) - board.dheight)
        adjCuts.append(Cut(left, right))
    # if the right-most input cut does not include the right edge, add an
    # adjoining cut that includes this edge
    if cuts[-1].xmax < board.width:
        left = my_round(cuts[-1].xmax - bit.offset) + board.dheight
        right = board.width
        if right - left >= board.dheight:
            adjCuts.append(Cut(left, right))
    return adjCuts
Пример #3
0
    def set_cuts(self):
        '''
        Sets the cuts to make the joint
        '''
        spacing = self.params['Spacing'].v - 2 * self.dhtot
        width = self.params['Width'].v
        centered = self.params['Centered'].v

        board_width = self.boards[0].width
        units = self.bit.units
        label = units.increments_to_string(spacing, True)
        self.labels = self.keys[:]
        self.labels[0] += ': ' + label
        self.labels[1] += ': ' + units.increments_to_string(width, True)
        self.description = 'Equally spaced (' + self.labels[0] + \
                           ', ' + self.labels[1] + ')'
        self.cuts = [] # return value
        neck_width = utils.my_round(self.bit.neck + width - self.bit.width + spacing)
        if neck_width < 1:
            raise Spacing_Exception('Specified bit paramters give a zero'
                                    ' or negative cut width (%d increments) at'
                                    ' the surface!  Please change the'
                                    ' bit parameters width, depth, or angle.' % neck_width)
        # put a cut at the center of the board
        xMid = board_width // 2
        if centered or \
           self.bit.angle > 0: # always symm. for dovetail
            left = max(0, xMid - width // 2)
        else:
            left = max(0, (xMid // width) * width)
        right = min(board_width, left + width)
        self.cuts.append(router.Cut(left, right))
        # do left side of board
        i = left - neck_width
        min_interior = utils.my_round(self.dhtot + self.bit.offset)
        while i > 0:
            li = max(i - width, 0)
            if i - li > self.config.min_finger_width and i > min_interior:
                self.cuts.append(router.Cut(li, i))
            i = li - neck_width
        # do right side of board
        i = right + neck_width
        while i < board_width:
            ri = min(i + width, board_width)
            if ri - i > self.config.min_finger_width and board_width - i > min_interior:
                self.cuts.append(router.Cut(i, ri))
            i = ri + neck_width
        # If we have only one cut the entire width of the board, then
        # the board width is too small for the bit
        if self.cuts[0].xmin == 0 and self.cuts[0].xmax == board_width:
            raise Spacing_Exception('Unable to compute a equally-spaced'\
                                    ' joint for the board and bit parameters'\
                                    ' specified.  This is likely because'\
                                    ' the board width is too small for the'\
                                    ' bit width specified.')
        # sort the cuts in increasing x
        self.cuts = sorted(self.cuts, key=attrgetter('xmin'))
        if self.config.debug:
            print('e-s cuts:')
            dump_cuts(self.cuts)
Пример #4
0
 def dovetail_correction(self):
     '''
     Correction for rounding the offset
     '''
     if utils.my_round(self.neck) + 2 * utils.my_round(self.offset) < self.width:
         return 1
     else:
         return 0
Пример #5
0
 def change_units(self, new_units):
     '''Changes units to new_units'''
     s = self.units.get_scaling(new_units)
     if s == 1:
         return
     self.width = my_round(self.width * s)
     self.height = my_round(self.height * s)
     self.thickness = my_round(self.thickness * s)
     self.units = new_units
Пример #6
0
 def change_units(self, new_units):
     '''Changes units to new_units'''
     s = self.units.get_scaling(new_units)
     if s == 1:
         return
     self.width = my_round(self.width * s)
     self.height = my_round(self.height * s)
     self.thickness = my_round(self.thickness * s)
     self.units = new_units
Пример #7
0
 def change_units(self, new_units):
     '''Changes units to new_units'''
     s = self.units.get_scaling(new_units)
     if s == 1:
         return
     self.width = my_round(self.width * s)
     self.width += self.width % 2  # ensure even
     self.depth = my_round(self.depth * s)
     self.units = new_units
     self.reinit()
Пример #8
0
 def change_units(self, new_units):
     '''Changes units to new_units'''
     s = self.units.get_scaling(new_units)
     if s == 1:
         return
     self.width = my_round(self.width * s)
     self.width += self.width % 2 # ensure even
     self.depth = my_round(self.depth * s)
     self.units = new_units
     self.reinit()
Пример #9
0
    def paint_all(self, painter, dpi=None):
        '''
        Paints all the objects.

        painter: A QPainter object
        dpi: The resolution of the painter, in dots-per-inch.  If None, then
             the image is maximized in the window, but maintaining aspect ratio.
        '''
        rw = painter.window()
        window_width = rw.width()
        window_height = rw.height()
        units = self.geom.bit.units

        if dpi is None:
            # transform the painter to maintain the figure aspect ratio in the current
            # window
            window_ar = float(window_width) / window_height
            fig_ar = float(self.fig_width) / self.fig_height
            if fig_ar < window_ar:
                w = utils.my_round(fig_ar * window_height)
                painter.translate((window_width - w) // 2, window_height)
                scale = float(window_height) / self.fig_height
            else:
                h = utils.my_round(window_width / fig_ar)
                painter.translate(0, (window_height + h) // 2)
                scale = float(window_width) / self.fig_width
        else:
            # Scale so that the image is the correct size on the page
            painter.translate(0, window_height)
            scale = float(dpi) / units.increments_per_inch
        painter.scale(scale, -scale)

        # Save the inverse of the un-zoomed transform
        (self.base_transform,
         dummy_invertable) = painter.transform().inverted()

        # Apply the zoom, zooming on the current figure center
        painter.scale(self.scaling, self.scaling)
        factor = 0.5 - 0.5 / self.scaling
        x = self.translate[0] - self.fig_width * factor
        y = self.translate[1] - self.fig_height * factor
        painter.translate(x, y)
        self.transform = painter.transform()

        # draw the objects
        self.draw_boards(painter)
        self.draw_template(painter)
        self.draw_title(painter)
        # self.draw_finger_sizes(painter)
        if self.config.show_finger_widths:
            self.draw_finger_sizes(painter)

        return (window_width, window_height)
Пример #10
0
    def paint_all(self, painter, dpi=None):
        '''
        Paints all the objects.

        painter: A QPainter object
        dpi: The resolution of the painter, in dots-per-inch.  If None, then
             the image is maximized in the window, but maintaining aspect ratio.
        '''
        rw = painter.window()
        window_width = rw.width()
        window_height = rw.height()
        units = self.geom.bit.units

        if dpi is None:
            # transform the painter to maintain the figure aspect ratio in the current
            # window
            window_ar = float(window_width) / window_height
            fig_ar = float(self.fig_width) / self.fig_height
            if fig_ar < window_ar:
                w = utils.my_round(fig_ar * window_height)
                painter.translate((window_width - w) // 2, window_height)
                scale = float(window_height) / self.fig_height
            else:
                h = utils.my_round(window_width / fig_ar)
                painter.translate(0, (window_height + h) // 2)
                scale = float(window_width) / self.fig_width
        else:
            # Scale so that the image is the correct size on the page
            painter.translate(0, window_height)
            scale = float(dpi) / units.increments_per_inch
        painter.scale(scale, -scale)

        # Save the inverse of the un-zoomed transform
        (self.base_transform, invertable) = painter.transform().inverted()

        # Apply the zoom, zooming on the current figure center
        painter.scale(self.scaling, self.scaling)
        factor = 0.5 - 0.5 / self.scaling
        x = self.translate[0] - self.fig_width * factor
        y = self.translate[1] - self.fig_height * factor
        painter.translate(x, y)
        self.transform = painter.transform()

        # draw the objects
        self.draw_boards(painter)
        self.draw_template(painter)
        self.draw_title(painter)
        if self.config.show_finger_widths:
            self.draw_finger_sizes(painter)

        return (window_width, window_height)
Пример #11
0
    def image_fig(self, template, boards, bit, spacing, woods, min_width):
        '''
        Prints the figure to a QImage object
        '''
        self.woods = woods
        self.set_fig_dimensions(template, boards)
        self.geom = router.Joint_Geometry(template, boards, bit, spacing, self.margins,\
                                          self.config.caul_trim)
        self.current_background = self.background

        s = self.size()
        window_ar = float(s.width()) / s.height()
        fig_ar = float(self.fig_width) / self.fig_height
        if window_ar < fig_ar:
            w = max(min_width, s.width())
        else:
            w = max(min_width, int(s.height() * fig_ar))
        h = utils.my_round(w / fig_ar)
        sNew = QtCore.QSize(w, h)

        image = QtGui.QImage(sNew, QtGui.QImage.Format_RGB32)
        painter = QtGui.QPainter()
        painter.begin(image)
        size = image.size()
        painter.fillRect(0, 0, size.width(), size.height(), self.background)
        self.paint_all(painter)
        painter.end()
        return image
Пример #12
0
    def image(self, template, boards, bit, spacing, woods, description):
        '''
        Prints the figure to a QImage object
        '''
        self.woods = woods
        self.description = description
        self.set_fig_dimensions(template, boards)
        self.geom = router.Joint_Geometry(template, boards, bit, spacing, self.margins,
                                          self.config)
        self.set_colors(True)

        s = self.size()
        window_ar = float(s.width()) / s.height()
        fig_ar = float(self.fig_width) / self.fig_height
        if window_ar < fig_ar:
            w = s.width()
        else:
            w = int(s.height() * fig_ar)
        w = max(self.config.min_image_width, min(self.config.max_image_width, w))
        h = utils.my_round(w / fig_ar)
        sNew = QtCore.QSize(w, h)

        im = QtGui.QImage(sNew, QtGui.QImage.Format_RGB32)
        painter = QtGui.QPainter()
        painter.begin(im)
        size = im.size()
        if self.colors['canvas_background'] is not None:
            b = QtGui.QBrush(self.colors['canvas_background'])
            painter.fillRect(0, 0, size.width(), size.height(), b)
        self.paint_all(painter)
        painter.end()
        return im
Пример #13
0
    def image(self, template, boards, bit, spacing, woods, description):
        '''
        Prints the figure to a QImage object
        '''
        self.woods = woods
        self.description = description
        self.set_fig_dimensions(template, boards)
        self.geom = router.Joint_Geometry(template, boards, bit, spacing,
                                          self.margins, self.config)
        self.set_colors(True)

        s = self.size()
        window_ar = float(s.width()) / s.height()
        fig_ar = float(self.fig_width) / self.fig_height
        if window_ar < fig_ar:
            w = s.width()
        else:
            w = int(s.height() * fig_ar)
        w = max(self.config.min_image_width, min(self.config.max_image_width,
                                                 w))
        h = utils.my_round(w / fig_ar)
        sNew = QtCore.QSize(w, h)

        im = QtGui.QImage(sNew, QtGui.QImage.Format_RGB32)
        painter = QtGui.QPainter()
        painter.begin(im)
        size = im.size()
        if self.colors['canvas_background'] is not None:
            b = QtGui.QBrush(self.colors['canvas_background'])
            painter.fillRect(0, 0, size.width(), size.height(), b)
        self.paint_all(painter)
        painter.end()
        return im
Пример #14
0
    def image_fig(self, template, boards, bit, spacing, woods, min_width):
        '''
        Prints the figure to a QImage object
        '''
        self.woods = woods
        self.set_fig_dimensions(template, boards)
        self.geom = router.Joint_Geometry(template, boards, bit, spacing, self.margins,\
                                          self.config.caul_trim)
        self.current_background = self.background

        s = self.size()
        window_ar = float(s.width()) / s.height()
        fig_ar = float(self.fig_width) / self.fig_height
        if window_ar < fig_ar:
            w = max(min_width, s.width())
        else:
            w = max(min_width, int(s.height() * fig_ar))
        h = utils.my_round(w / fig_ar)
        sNew = QtCore.QSize(w, h)

        image = QtGui.QImage(sNew, QtGui.QImage.Format_RGB32)
        painter = QtGui.QPainter()
        painter.begin(image)
        size = image.size()
        painter.fillRect(0, 0, size.width(), size.height(), self.background)
        self.paint_all(painter)
        painter.end()
        return image
Пример #15
0
 def __str__(self):
     result = ['ellipsoid:']
     #result.append('lengths measured in meters')
     for (k, v) in sorted(self.__dict__.items()):
         if k == 'phi_0':
             continue
         result.append('    ' + k + ' = ' + str(my_round(v, 15)))
     return "\n".join(result)
Пример #16
0
 def __str__(self):
     result = ['ellipsoid:']
     #result.append('lengths measured in meters')
     for (k, v) in sorted(self.__dict__.items()):
         if k == 'phi_0':
             continue
         result.append('    ' + k + ' = ' + str(my_round(v, 15)))
     return "\n".join(result)
Пример #17
0
 def set_font_size(self, painter, param):
     '''
     Sets the font size for type param
     '''
     font_inches = self.font_size[param] / 32.0 * self.geom.bit.units.increments_per_inch
     font = painter.font()
     xx = self.transform.map(font_inches, 0)[0] - self.transform.dx()
     font.setPixelSize(utils.my_round(xx))
     painter.setFont(font)
Пример #18
0
 def set_font_size(self, painter, param):
     '''
     Sets the font size for type param
     '''
     font_inches = self.font_size[
         param] / 32.0 * self.geom.bit.units.increments_per_inch
     font = painter.font()
     xx = self.transform.map(font_inches, 0)[0] - self.transform.dx()
     font.setPixelSize(utils.my_round(xx))
     painter.setFont(font)
Пример #19
0
    def __init__(self, bit, boards, config):
        Base_Spacing.__init__(self, bit, boards, config)
        # eff_width is the effective width, an average of the bit width
        # and the neck width
        self.eff_width = utils.my_round(0.5 * (self.bit.width + self.bit.neck)) + 2 * self.dhtot
        self.wb = self.boards[0].width // self.eff_width
        self.alpha = (self.wb + 1) % 2
        # min and max number of fingers
        self.mMin = max(3 - self.alpha, utils.my_round(math.ceil(math.sqrt(self.wb))))
        self.mMax = utils.my_round((self.wb - 1.0 + self.alpha) // 2)
        if self.mMax < self.mMin:
            raise Spacing_Exception('Unable to compute a variable-spaced'\
                                    ' joint for the board and bit parameters'\
                                    ' specified.  This is likely because'\
                                    ' the board width is too small for the'\
                                    ' bit width specified.')
        self.mDefault = (self.mMin + self.mMax) // 2

        self.params = {'Fingers':Spacing_Param(self.mMin, self.mMax, self.mDefault)}
Пример #20
0
    def paint_all(self, painter, dpi=None):
        '''
        Paints all the objects.

        painter: A QPainter object
        dpi: The resolution of the painter, in dots-per-inch.  If None, then
             the image is maximized in the window, but maintaining aspect ratio.
        '''
        rw = painter.window()
        window_width = rw.width()
        window_height = rw.height()
        units = self.geom.bit.units

        if dpi is None:
            # transform the painter to maintain the figure aspect ratio in the current
            # window
            window_ar = float(window_width) / window_height
            fig_ar = float(self.fig_width) / self.fig_height
            if fig_ar < window_ar:
                w = utils.my_round(fig_ar * window_height)
                painter.translate((window_width - w) // 2, window_height)
                scale = float(window_height) / self.fig_height
            else:
                h = utils.my_round(window_width / fig_ar)
                painter.translate(0, (window_height + h) // 2)
                scale = float(window_width) / self.fig_width
        else:
            # Scale so that the image is the correct size on the page
            painter.translate(0, window_height)
            scale = float(dpi) / units.increments_per_inch
        painter.scale(scale, -scale)
        self.transform = painter.transform()

        painter.setPen(QtCore.Qt.black)

        # draw the objects
        self.draw_boards(painter)
        self.draw_template(painter)
        self.draw_title(painter)
        self.draw_cut_sizes(painter)

        return (window_width, window_height)
Пример #21
0
    def paint_all(self, painter, dpi=None):
        '''
        Paints all the objects.

        painter: A QPainter object
        dpi: The resolution of the painter, in dots-per-inch.  If None, then
             the image is maximized in the window, but maintaining aspect ratio.
        '''
        rw = painter.window()
        window_width = rw.width()
        window_height = rw.height()
        units = self.geom.bit.units

        if dpi is None:
            # transform the painter to maintain the figure aspect ratio in the current
            # window
            window_ar = float(window_width) / window_height
            fig_ar = float(self.fig_width) / self.fig_height
            if fig_ar < window_ar:
                w = utils.my_round(fig_ar * window_height)
                painter.translate((window_width - w) // 2, window_height)
                scale = float(window_height) / self.fig_height
            else:
                h = utils.my_round(window_width / fig_ar)
                painter.translate(0, (window_height + h) // 2)
                scale = float(window_width) / self.fig_width
        else:
            # Scale so that the image is the correct size on the page
            painter.translate(0, window_height)
            scale = float(dpi) / units.increments_per_inch
        painter.scale(scale, -scale)
        self.transform = painter.transform()

        painter.setPen(QtCore.Qt.black)

        # draw the objects
        self.draw_boards(painter)
        self.draw_template(painter)
        self.draw_title(painter)
        self.draw_cut_sizes(painter)

        return (window_width, window_height)
Пример #22
0
 def get_limits(self, f):
     '''
     Returns the x-coordinate limits of the cut index f
     '''
     xmin = 0
     xmax = self.boards[0].width
     neck_width = utils.my_round(self.bit.neck)
     if f > 0:
         xmin = self.cuts[f - 1].xmax + neck_width
     if f < len(self.cuts) - 1:
         xmax = self.cuts[f + 1].xmin - neck_width
     return (xmin, xmax)
Пример #23
0
 def get_limits(self, f):
     """
     Returns the x-coordinate limits of the cut index f
     """
     xmin = 0
     xmax = self.boards[0].width
     neck_width = utils.my_round(self.bit.neck)
     if f > 0:
         xmin = self.cuts[f - 1].xmax + neck_width
     if f < len(self.cuts) - 1:
         xmax = self.cuts[f + 1].xmin - neck_width
     return (xmin, xmax)
Пример #24
0
    def upgrade(self):
        eff_width = self.bit.midline + self.dhtot * 2
        wb = self.boards[0].width // eff_width
        alpha = (wb + 1) % 2
        m = self.params['Fingers'].v

        c = eff_width * ((m - 1) * wb - m *
                         (m + 1) + alpha * m) / D(m * m - 2 * m - 1 + alpha)
        d = utils.my_round((c - eff_width) / (m - 1))
        self.params[Variable_Spaced.keys[1]] = Spacing_Param(0, d, d)
        self.params[Variable_Spaced.keys[2]] = Spacing_Param(
            0, 0, False)  # No inverse in previous version
Пример #25
0
 def set_height(self, bit, dheight=None):
     '''
     Sets the height from the router bit depth of cut
     '''
     if dheight is None:
         if self.dheight > 0:
             h = self.dheight
         else:
             h = my_round(0.5 * bit.depth)
     else:
         self.dheight = dheight
         h = dheight
     self.height = bit.depth + h
Пример #26
0
 def get_limits(self, f):
     '''
     Returns the x-coordinate limits of the cut index f
     '''
     xmin = 0
     xmax = self.boards[0].width
     midline = utils.my_round(self.bit.midline)
     overhang = self.bit.overhang
     if f > 0:
         xmin = self.cuts[f - 1].xmax + midline - overhang * 2
     if f < len(self.cuts) - 1:
         xmax = self.cuts[f + 1].xmin - midline + overhang * 2
     return (xmin, xmax)
Пример #27
0
 def set_height(self, bit, dheight=None):
     '''
     Sets the height from the router bit depth of cut
     '''
     if dheight is None:
         if self.dheight > 0:
             h = self.dheight
         else:
             h = my_round(0.5 * bit.depth)
     else:
         self.dheight = dheight
         h = dheight
     self.height = bit.depth + h
Пример #28
0
    def __init__(self, bit, boards, config):
        Base_Spacing.__init__(self, bit, boards, config)
        # eff_width is the effective width, an average of the bit width
        # and the neck width
        self.eff_width = utils.my_round(
            0.5 * (self.bit.width + self.bit.neck)) + 2 * self.dhtot
        self.wb = self.boards[0].width // self.eff_width
        self.alpha = (self.wb + 1) % 2
        # min and max number of fingers
        self.mMin = max(3 - self.alpha,
                        utils.my_round(math.ceil(math.sqrt(self.wb))))
        self.mMax = utils.my_round((self.wb - 1.0 + self.alpha) // 2)
        if self.mMax < self.mMin:
            raise Spacing_Exception('Unable to compute a variable-spaced'\
                                    ' joint for the board and bit parameters'\
                                    ' specified.  This is likely because'\
                                    ' the board width is too small for the'\
                                    ' bit width specified.')
        self.mDefault = (self.mMin + self.mMax) // 2

        self.params = {
            'Fingers': Spacing_Param(self.mMin, self.mMax, self.mDefault)
        }
Пример #29
0
 def cut_add(self):
     '''
     Adds a cut to the first location possible, searching from the left.
     The active cut is set the the new cut.
     '''
     neck_width = utils.my_round(self.bit.neck)
     index = None
     cuts_save = copy.deepcopy(self.cuts)
     if self.cuts[0].xmin > self.bit.neck:
         if self.config.debug:
             print('add at left')
         index = 0
         xmin = 0
         xmax = self.cuts[0].xmin - neck_width
     wadd = 2 * self.bit.width + neck_width
     wdelta = self.bit.width - neck_width
     for i in lrange(1, len(self.cuts)):
         if self.cuts[i].xmin - self.cuts[i - 1].xmax + wdelta >= wadd:
             if self.config.debug:
                 print('add in cut')
             index = i
             xmin = self.cuts[i - 1].xmax + neck_width
             xmax = xmin + self.bit.width
             break
         elif self.cuts[i].xmax - self.cuts[i].xmin >= wadd:
             if self.config.debug:
                 print('add in cut')
             index = i + 1
             xmin = self.cuts[i].xmax - self.bit.width
             xmax = self.cuts[i].xmax
             self.cuts[i].xmax = self.cuts[i].xmin + self.bit.width
             break
     if index is None and \
        self.cuts[-1].xmax < self.boards[0].width - self.bit.neck:
         if self.config.debug:
             print('add at right')
         index = len(self.cuts)
         xmax = self.boards[0].width
         xmin = self.cuts[-1].xmax + neck_width
     if index is None:
         return 'Unable to add cut'
     self.undo_cuts.append(cuts_save)
     c = self.cuts[0:index]
     c.append(router.Cut(xmin, xmax))
     c.extend(self.cuts[index:])
     self.cuts = c
     self.cursor_cut = index
     self.active_cuts = [index]
     return 'Added cut'
Пример #30
0
 def cut_add(self):
     '''
     Adds a cut to the first location possible, searching from the left.
     The active cut is set the the new cut.
     '''
     neck_width = utils.my_round(self.bit.neck)
     index = None
     cuts_save = copy.deepcopy(self.cuts)
     if self.cuts[0].xmin > self.bit.neck:
         if self.config.debug:
             print('add at left')
         index = 0
         xmin = 0
         xmax = self.cuts[0].xmin - neck_width
     wadd = 2 * self.bit.width + neck_width
     wdelta = self.bit.width - neck_width
     for i in lrange(1, len(self.cuts)):
         if self.cuts[i].xmin - self.cuts[i - 1].xmax + wdelta >= wadd:
             if self.config.debug:
                 print('add in cut')
             index = i
             xmin = self.cuts[i - 1].xmax + neck_width
             xmax = xmin + self.bit.width
             break
         elif self.cuts[i].xmax - self.cuts[i].xmin >= wadd:
             if self.config.debug:
                 print('add in cut')
             index = i + 1
             xmin = self.cuts[i].xmax - self.bit.width
             xmax = self.cuts[i].xmax
             self.cuts[i].xmax = self.cuts[i].xmin + self.bit.width
             break
     if index is None and \
        self.cuts[-1].xmax < self.boards[0].width - self.bit.neck:
         if self.config.debug:
             print('add at right')
         index = len(self.cuts)
         xmax = self.boards[0].width
         xmin = self.cuts[-1].xmax + neck_width
     if index is None:
         return 'Unable to add cut'
     self.undo_cuts.append(cuts_save)
     c = self.cuts[0:index]
     c.append(router.Cut(xmin, xmax))
     c.extend(self.cuts[index:])
     self.cuts = c
     self.cursor_cut = index
     self.active_cuts = [index]
     return 'Added cut'
Пример #31
0
    def set_cuts(self):
        '''
        Sets the cuts to make the joint
        '''

        # on local variables init
        # we have to care about imperial values and convert them to increments before use
        spacing = self.params['Spacing'].v
        width = Decimal(math.floor(self.params['Width'].v))

        if not self.bit.units.metric and width < 1.:
            spacing = self.bit.units.inches_to_increments(self.params['Spacing'].v)
            width = Decimal(math.floor(self.bit.units.inches_to_increments(self.params['Width'].v)))

        shift = Decimal(self.bit.midline % 2) / 2  # offset to keep cut center mm count
        centered = self.params['Centered'].v
        neck_width = width + spacing
        overhang = self.bit.overhang

        board_width = self.boards[0].width
        units = self.bit.units
        label = units.increments_to_string(spacing, True)

        min_interior = utils.my_round(self.dhtot + self.bit.overhang)
        # min_finger_width means most thin wood at the corner
        min_finger_width = max(1, units.abstract_to_increments(self.config.min_finger_width))

        if centered or \
           self.bit.angle > 0:  # always symm. for dovetail
            # put a cut at the center of the board with half of inctrmrnt prec.
            xMid = Decimal(board_width // 2) - shift + (width % 2) / 2
            left = Decimal(max(0, xMid - width / 2))
        else:
            # keep corner finger and groove equality on the board edges
            left = (board_width % (width + neck_width)) // 2
            if (left - overhang) < min_finger_width:
                left = 0

        # Note the Width slider measures "midline" but indicates the actual cut space
        # show actual maximum cut with for dovetails
        self.labels = self.keys[:]
        l0 = self.transl.tr(self.labels[0])
        l1 = self.transl.tr(self.labels[1])
        self.labels[2] = self.transl.tr(self.labels[2])
        self.labels[0] = l0 +': ' + label
        self.labels[1] = l1 +': ' + units.increments_to_string(width + overhang * 2, True)
        self.description = self.transl.tr('Equally spaced ')+' (' + self.labels[0] + \
                           ', ' + self.labels[1] + ')'
        self.cuts = []  # return value

        right = Decimal(min(board_width, left + width))
        self.cuts.append(router.Cut(left - overhang, right + overhang))

        # do left side of board
        i = left

        while left > 0:
            i -= neck_width
            left = i - width

            # prevent thin first cut
            if left < min_finger_width:
                left = 0
            if (i - overhang) > min_finger_width and (i - left - overhang * 2) > min_interior:
                self.cuts.append(router.Cut(max(0, left - overhang), i + overhang))
            i = left

        # do right side of board
        i = right
        while right < board_width:
            i += neck_width
            right = i + width
            # prevent thin last cut
            # devetail may cut off corner finger
            if (board_width - right) < min_finger_width:
                right = board_width
            if (board_width - i + overhang) > min_finger_width and\
               (right - i - overhang * 2) > min_interior:
                self.cuts.append(router.Cut(i - overhang, min(board_width, right + overhang)))
            i = right

        # If we have only one cut the entire width of the board, then
        # the board width is too small for the bit
        if self.cuts[0].xmin == 0 and self.cuts[0].xmax == board_width:
            raise Spacing_Exception(self.transl.tr(Equally_Spaced.msg))
        # sort the cuts in increasing x
        self.cuts = sorted(self.cuts, key=attrgetter('xmin'))
        if self.config.debug:
            print('e-s cuts:')
            dump_cuts(self.cuts)
Пример #32
0
def distortion_stats(T, sample, my_round_numbers=3):
    r"""
    Return the sample minimum, sample maximum, sample median, sample mean, 
    and sample standard deviation of the maximum angular distortion, linear 
    distortion, and area distortion functions
    for the map projection `T` 
    (an projection_tools.Proj or projection_tools.Proj4 instance)
    of the list `sample` of longitude-latitude 
    points chosen from the surface `T.ellipsoid`.
    Most likely you will want sample to comprise points sampled uniformly 
    at random from the surface of `T.ellipsoid` (and not simply sampled 
    uniformly at random from the rectangle (-pi, pi) x (-pi/2, pi/2)).
        
    OUTPUT:
    
    (distortions, stats), where
    distortions is a list of distortion() outputs for each longitude-
    latitude point sampled;
    stats is the list of lists [maximum angular distortion stats, 
    linear distortion stats, area distortion stats], where each stats sublist 
    is of the form [sample mean, sample standard deviation, sample minimum,
    sample maximum, sample median].
    
    EXAMPLES::
    
        >>> from projection_wrapper import Proj
        >>> from ellipsoids import WGS84_ELLIPSOID_RADIANS
        >>> E = WGS84_ELLIPSOID_RADIANS
        >>> f = Proj(ellipsoid=E, proj='healpix')
        >>> sample = [E.random_point() for i in range(100)]
        >>> print(distortion_stats(f, sample)[1])  # doctest: +SKIP 
        [[0.309, 0.238, 0.001, 0.838, 0.178], [1.41, 0.375, 1.001, 2.372, 1.195], [1.178, 0.0, 1.178, 1.178, 1.178]]

    """
    distortions = []
    distortions_slice = []
    k = len(distortion(T, 0, 0)) - 1
    sample_sum = array([0.0 for i in range(k)])
    sample_min = array([float('inf') for i in range(k)])
    sample_max = array([float('-inf') for i in range(k)])
    N = len(sample)
    for (lam, phi) in sample:
        d = distortion(T, lam, phi)
        distortions.append(d)
        distortions_slice.append(d[1:])
        for i in range(k):
            if d[1 + i] < sample_min[i]:
                sample_min[i] = d[1 + i]
            if d[1 + i] > sample_max[i]:
                sample_max[i] = d[1 + i] 
        sample_sum += array(d[1:])
    distortions_slice = array(distortions_slice)
    sample_median = median(distortions_slice, axis=0)
    sample_mean = sample_sum/N
    sample_var = sum(((d - sample_mean)**2 for d in distortions_slice))/(N - 1)
    sample_std = sqrt(sample_var)
    #sample_mean_error = sample_std/sqrt(N)
    # Zero until i find an appropriate estimate:
    #sample_std_error = [0 for i in range(k)]   
    # Compile stats.
    stats = [sample_mean, sample_std, sample_min, sample_max, sample_median]
    #errors = [sample_mean_error, sample_std_error] 
    # Reorder to have ld stuff followed by ad stuff.
    stats = list(zip(*stats)) 
    #errors = zip(*errors)
    ## Compile result
    #stats = [stats[0], errors[0], stats[1], errors[1]]
    # Round stats if desired.
    if my_round_numbers:
        new_stats = []
        for x in stats:
             new_stats.append([my_round(xx, my_round_numbers) for xx in x])
        stats = new_stats
    return distortions, stats   
Пример #33
0
 def set_cuts(self):
     """
     Sets the cuts to make the joint
     """
     board_width = self.boards[0].width
     m = self.params["Fingers"].v
     self.labels = [self.keys[0] + ":"]
     self.description = "Variable Spaced (" + self.keys[0] + ": {})".format(m)
     # c is the ideal center-cut width
     c = (
         self.eff_width
         * ((m - 1.0) * self.wb - m * (m + 1.0) + self.alpha * m)
         / (m * m - 2.0 * m - 1.0 + self.alpha)
     )
     # d is the ideal decrease in finger width for each finger away from center finger
     d = (c - self.eff_width) / (m - 1.0)
     # compute fingers on one side of the center and the center and store them
     # in increments.  Keep a running total of sizes.
     increments = [0] * (m + 1)
     ivals = 0
     for i in lrange(1, m + 1):
         increments[i] = max(self.bit.width, int(c - d * i))
         ivals += 2 * increments[i]
     # Set the center increment.  This takes up the slop in the rounding and increment
     # resolution.
     increments[0] = board_width - ivals
     if increments[0] < increments[1]:
         # The center increment is narrower than the adjacent increment,
         # so reset it to the adjacent increment and get rid of a finger.
         increments[0] = increments[1]
         m -= 1
     if self.config.debug:
         print("v-s increments", increments)
     # Adjustments for dovetails
     deltaP = self.bit.width + 2 * self.dhtot - self.eff_width
     deltaM = utils.my_round(self.eff_width - self.bit.neck - 2 * self.dhtot) - self.bit.dovetail_correction()
     # put a cut at the center of the board
     xMid = board_width // 2
     width = increments[0] + deltaP
     left = max(0, xMid - width // 2)
     right = min(board_width, left + width)
     self.cuts = [router.Cut(left, right)]
     # do the remaining cuts
     do_cut = False
     for i in lrange(1, m + 1):
         if do_cut:
             width = increments[i] + deltaP
             farLeft = max(0, left - width)
             self.cuts.append(router.Cut(farLeft, left))
             farRight = min(board_width, right + width)
             self.cuts.append(router.Cut(right, farRight))
         else:
             width = increments[i] - deltaM
             farLeft = max(0, left - width)
             farRight = min(board_width, right + width)
         left = farLeft
         right = farRight
         do_cut = not do_cut
     # sort the cuts in increasing x
     self.cuts = sorted(self.cuts, key=attrgetter("xmin"))
     if self.config.debug:
         print("v-s cuts:")
         dump_cuts(self.cuts)
Пример #34
0
def test_calculator():
    resolver = ExpressionResolver(verbose=False)

    # Simple test
    ret = resolver.solve(expression="5 * 5^0")
    assert ret == "5.0"

    # Simple test exponential
    ret = resolver.solve(expression="5 * 5^10")
    assert ret == "48828125.0"

    # Simple test with priority
    ret = resolver.solve(expression="5 * 5 + 10")
    assert ret == "35.0"

    # Simple test with float
    ret = resolver.solve(expression="5.3 * 5.2 + 10.8")
    assert ret == "38.36"

    # Test with parenthesis
    ret = resolver.solve(expression="5 * (5 + 10)")
    assert ret == "75.0"

    # Test with multiple parenthesis
    ret = resolver.solve(expression="5 * (5 + (10 * 50 + 2))")
    assert ret == "2535.0"

    # Test with multiple useless parenthesis
    ret = resolver.solve(expression="((((5 * (5 + (10 * 50 + 2))))))")
    assert ret == "2535.0"

    # Hard test with multiple parenthesis
    ret = resolver.solve(
        expression=
        "5 * (5 + (10 * 50 + 24.15) *    50 * 18 *(12 + 52)) * (18 - (5 + 2))")
    assert ret == "1660507475.0"

    # Hard test with float
    ret = resolver.solve(
        expression="545875785748.34444444478 * 5.2542 + 10456.81212")
    assert my_round(float(ret), 2) == my_round(2868140563935.763, 2)

    # Implicit multiplication with open parenthesis
    ret = resolver.solve(expression="25(5 + 2)")
    assert ret == "175.0"

    # Implicit multiplication with closing parenthesis
    ret = resolver.solve(expression="(5 + 2)25")
    assert ret == "175.0"

    # Test different parenthesis
    ret = resolver.solve(expression="(5 + 2]25")
    assert ret == "175.0"

    # Test different parenthesis
    ret = resolver.solve(expression="[5 + 2]25")
    assert ret == "175.0"

    # Test different parenthesis
    ret = resolver.solve(expression="[5 + 2}25")
    assert ret == "175.0"

    # Test multiplying by a signed number
    ret = resolver.solve(expression="5 * -10 + 599")
    assert ret == "549.0"

    # Test multiplying by a signed number
    ret = resolver.solve(expression="5 * +10")
    assert ret == "50.0"

    # Test multiplying by a signed number in parenthesis
    ret = resolver.solve(expression="5 * (+10)")
    assert ret == "50.0"

    # Test multiplying by a signed number in parenthesis
    ret = resolver.solve(expression="(+10)10")
    assert ret == "100.0"

    # Test substract by a signed number in parenthesis
    ret = resolver.solve(expression="(-10)-10")
    assert ret == "-20.0"

    # Test substract by a signed number in parenthesis
    ret = resolver.solve(expression="(-10)(-10)")
    assert ret == "100.0"

    # Test multiplying by a signed float
    ret = resolver.solve(expression="5 * -10.35843958432134 + 599")
    assert my_round(float(ret), 2) == my_round(547.2078020783933, 2)

    # Test sign before first number
    ret = resolver.solve(expression="-42-2")
    assert ret == "-44.0"

    # Test one var with parenthesis in calculator
    ret = resolver.solve(expression="5 * x(5 + 10)")
    assert ret == "75.0*X"
Пример #35
0
 def scale(self, s):
     '''Scales dimensions by the factor s'''
     self.width = my_round(self.width * s)
     self.width += self.width % 2 # ensure even
     self.depth = my_round(self.depth * s)
     self.reinit()
Пример #36
0
    def set_cuts(self):
        """
        Sets the cuts to make the joint
        """
        spacing = self.params["Spacing"].v - 2 * self.dhtot
        width = self.params["Width"].v
        centered = self.params["Centered"].v

        board_width = self.boards[0].width
        units = self.bit.units
        label = units.increments_to_string(spacing, True)
        self.labels = self.keys[:]
        self.labels[0] += ": " + label
        self.labels[1] += ": " + units.increments_to_string(width, True)
        self.description = "Equally spaced (" + self.labels[0] + ", " + self.labels[1] + ")"
        self.cuts = []  # return value
        neck_width = width + spacing - 2 * utils.my_round(self.bit.offset)
        if neck_width < 1:
            raise Spacing_Exception(
                "Specified bit paramters give a zero"
                " or negative cut width (%d increments) at"
                " the surface!  Please change the"
                " bit parameters width, depth, or angle." % neck_width
            )
        # put a cut at the center of the board
        xMid = board_width // 2
        if centered or self.bit.angle > 0:  # always symm. for dovetail
            left = max(0, xMid - width // 2)
        else:
            left = max(0, (xMid // width) * width)
        right = min(board_width, left + width)
        self.cuts.append(router.Cut(left, right))
        # do left side of board
        i = left - neck_width
        min_interior = utils.my_round(self.dhtot + self.bit.offset)
        min_finger_width = max(1, units.abstract_to_increments(self.config.min_finger_width))
        while i > 0:
            li = max(i - width, 0)
            if i - li > min_finger_width and i > min_interior:
                self.cuts.append(router.Cut(li, i))
            i = li - neck_width
        # do right side of board
        i = right + neck_width
        while i < board_width:
            ri = min(i + width, board_width)
            if ri - i > min_finger_width and board_width - i > min_interior:
                self.cuts.append(router.Cut(i, ri))
            i = ri + neck_width
        # If we have only one cut the entire width of the board, then
        # the board width is too small for the bit
        if self.cuts[0].xmin == 0 and self.cuts[0].xmax == board_width:
            raise Spacing_Exception(
                "Unable to compute a equally-spaced"
                " joint for the board and bit parameters"
                " specified.  This is likely because"
                " the board width is too small for the"
                " bit width specified."
            )
        # sort the cuts in increasing x
        self.cuts = sorted(self.cuts, key=attrgetter("xmin"))
        if self.config.debug:
            print("e-s cuts:")
            dump_cuts(self.cuts)
Пример #37
0
 def set_cuts(self):
     '''
     Sets the cuts to make the joint
     '''
     board_width = self.boards[0].width
     m = self.params['Fingers'].v
     self.labels = [self.keys[0] + ': %d' % m]
     self.description = 'Variable Spaced (' + self.labels[0] + ')'
     # c is the ideal center-cut width
     c = self.eff_width * ((m - 1.0) * self.wb - \
                           m * (m + 1.0) + self.alpha * m) /\
         (m * m - 2.0 * m - 1.0 + self.alpha)
     # d is the ideal decrease in finger width for each finger away from center finger
     d = (c - self.eff_width) / (m - 1.0)
     # compute fingers on one side of the center and the center and store them
     # in increments.  Keep a running total of sizes.
     increments = [0] * (m + 1)
     ivals = 0
     for i in lrange(1, m + 1):
         increments[i] = max(2, int(c - d * i))
         ivals += 2 * increments[i]
     # Set the center increment.  This takes up the slop in the rounding and increment
     # resolution.
     increments[0] = board_width - ivals
     if increments[0] < increments[1]:
         # The center increment is narrower than the adjacent increment,
         # so reset it to the adjacent increment and get rid of a finger.
         increments[0] = increments[1]
         m -= 1
     if self.config.debug:
         print('v-s increments', increments)
     # Adjustments for dovetails
     deltaP = self.bit.width + 2 * self.dhtot - self.eff_width
     deltaM = utils.my_round(self.eff_width - self.bit.neck -
                             2 * self.dhtot)
     # put a cut at the center of the board
     xMid = board_width // 2
     width = increments[0] + deltaP
     left = max(0, xMid - width // 2)
     right = min(board_width, left + width)
     self.cuts = [router.Cut(left, right)]
     # do the remaining cuts
     do_cut = False
     for i in lrange(1, m + 1):
         if do_cut:
             width = increments[i] + deltaP
             farLeft = max(0, left - width)
             self.cuts.append(router.Cut(farLeft, left))
             farRight = min(board_width, right + width)
             self.cuts.append(router.Cut(right, farRight))
         else:
             width = increments[i] - deltaM
             farLeft = max(0, left - width)
             farRight = min(board_width, right + width)
         left = farLeft
         right = farRight
         do_cut = (not do_cut)
     # sort the cuts in increasing x
     self.cuts = sorted(self.cuts, key=attrgetter('xmin'))
     if self.config.debug:
         print('v-s cuts:')
         dump_cuts(self.cuts)
Пример #38
0
    def resolve_npi(self, npi_list) -> str:
        stack = []
        c = 0.0
        var_is_present = True if self.var_name else False

        for elem in npi_list:
            if is_number(elem) or (var_is_present and elem in self.var_name):
                stack.append(elem)
            else:
                last_two_in_stack = stack[-2:]
                del stack[-2:]
                if len(last_two_in_stack) < 2:
                    raise IndexError(
                        "There is a problem in the npi resolver, the npi_list isn't well formated."
                    )
                # Doing var calc if there is a var
                if var_is_present and (
                    self._check_have_var(str(last_two_in_stack[0]))
                    or self._check_have_var(str(last_two_in_stack[1]))
                ):
                    # - or + operator, adding to c
                    if elem in _SIGN:
                        if not self._check_have_var(str(last_two_in_stack[0])):
                            if elem == "-":
                                c = my_round(c + float(last_two_in_stack[0]))
                                # Inverting the sign of the var because it is the second element.
                                result = self._multiply_a_var("-1", str(last_two_in_stack[1]))
                            else:
                                c = my_round(c + float(last_two_in_stack[0]))
                                result = str(last_two_in_stack[1])

                        elif not self._check_have_var(str(last_two_in_stack[1])):
                            if elem == "-":
                                c = my_round(c - float(last_two_in_stack[1]))
                            else:
                                c = my_round(c + float(last_two_in_stack[1]))
                            result = str(last_two_in_stack[0])
                        else:
                            # Adding var to var
                            result = self._add_or_substract_var_to_var(
                                operator=elem,
                                first_var=str(last_two_in_stack[0]),
                                second_var=str(last_two_in_stack[1]),
                            )
                    elif elem == "*":
                        result = self._multiply_a_var(
                            str(last_two_in_stack[0]), str(last_two_in_stack[1])
                        )
                    elif elem == "/":
                        result = self._divide_a_var(
                            str(last_two_in_stack[0]), str(last_two_in_stack[1])
                        )
                    elif elem == "^":
                        result = self._power_a_var(
                            str(last_two_in_stack[0]), str(last_two_in_stack[1])
                        )
                    else:
                        raise NotImplementedError(
                            "This type of operation with vars is not accepted for the moment."
                        )

                # Doing usual calc
                elif elem == "^":
                    result = my_round(
                        my_power(float(last_two_in_stack[0]), float(last_two_in_stack[1]))
                    )
                elif elem == "*":
                    result = my_round(float(last_two_in_stack[0]) * float(last_two_in_stack[1]))
                elif elem == "/":
                    if float(last_two_in_stack[1]) == 0.0:
                        raise ValueError(
                            "The expression lead to a division by zero : ",
                            float(last_two_in_stack[0]),
                            " / ",
                            float(last_two_in_stack[1]),
                        )
                    result = my_round(float(last_two_in_stack[0]) / float(last_two_in_stack[1]))
                elif elem == "%":
                    if float(last_two_in_stack[1]) == 0.0:
                        raise ValueError(
                            "The expression lead to a modulo zero : ",
                            float(last_two_in_stack[0]),
                            " % ",
                            float(last_two_in_stack[1]),
                        )
                    result = my_round(float(last_two_in_stack[0]) % float(last_two_in_stack[1]))
                elif elem == "+":
                    result = my_round(float(last_two_in_stack[0]) + float(last_two_in_stack[1]))
                elif elem == "-":
                    result = my_round(float(last_two_in_stack[0]) - float(last_two_in_stack[1]), 6)
                stack.append(result)

        if len(stack) > 1:
            raise Exception(
                "Unexpected error when trying to resolve npi. Maybe your input format is not accepted?"
            )

        if var_is_present:
            if c != 0.0:
                # Parse sign because could have duplicate sign with the add of the +
                return parse_sign(str(c) + "+" + str(stack[0]))
            else:
                return str(stack[0])
        else:
            return str(stack[0])
Пример #39
0
    def _solve_polynom_degree_two(self):
        try:
            a = get_var_multiplier(self._polynom_dict_left["a"], var_name=self.var_name)
        except:
            a = 0.0
        try:
            b = get_var_multiplier(self._polynom_dict_left["b"], var_name=self.var_name)
        except:
            b = 0.0
        try:
            c = float(self._polynom_dict_left["c"])
        except:
            c = 0.0

        print("a = ", a, " b = ", b, " c = ", c) if self._verbose is True else None

        discriminant = self._get_discriminant(a, b, c)
        if discriminant > 0:
            print("The discriminant is strictly positive.")
        elif discriminant == 0:
            print("The discriminant is exactly zero.")
        else:
            print("The discriminant is strictly negative.")
        print("discriminant = ", discriminant)
        if discriminant > 0:
            self.solution = []
            if a == 0:
                raise ValueError(
                    "The expression lead to a division by zero : ",
                    float(str((-b + my_sqrt(discriminant)))),
                    " / ",
                    a,
                )
            solution_one = str((-b + my_sqrt(discriminant)) / (2 * a))
            solution_two = str((-b - my_sqrt(discriminant)) / (2 * a))
            if solution_one == "-0.0":
                solution_one = "0.0"
            if solution_two == "-0.0":
                solution_two = "0.0"
            self.solution.append(str(my_round(float(solution_one), 6)))
            self.solution.append(str(my_round(float(solution_two), 6)))
        elif discriminant == 0:
            if a == 0:
                raise ValueError(
                    "The expression lead to a division by zero : ",
                    float(str((-b + my_sqrt(discriminant)))),
                    " / ",
                    a,
                )
            self.solution = str((-b) / (2 * a))
            if self.solution == "-0.0":
                self.solution = "0.0"
        else:
            print("There is two solutions in complex number.")
            self.solution = []
            discriminant = -discriminant
            solution_one = convert_signed_number(
                f"{-b} / (2 * {a}) + i * {my_sqrt(discriminant)} / (2 * {a})".replace(" ", "")
            )
            tokens = convert_to_tokens(
                convert_signed_number(parse_sign(solution_one), accept_var=True)
            )
            self.solution.append(
                self._calculator.solve(tokens=tokens, verbose=self._force_calculator_verbose)
            )

            solution_two = f"{-b} / (2 * {a}) - i * {my_sqrt(discriminant)} / (2 * {a})".replace(
                " ", ""
            )
            tokens = convert_to_tokens(
                convert_signed_number(parse_sign(solution_two), accept_var=True)
            )
            self.solution.append(
                self._calculator.solve(tokens=tokens, verbose=self._force_calculator_verbose)
            )
Пример #40
0
 def scale(self, s):
     '''Scales dimensions by the factor s'''
     self.width = my_round(self.width * s)
     self.width += self.width % 2  # ensure even
     self.depth = my_round(self.depth * s)
     self.reinit()
Пример #41
0
def main(inp, method, training_size, epoch):

    sample_func, data = sampling_methods[method]

    if data[-4:] == '.pth':
        data = torch.load(data)

    device = torch.device('cpu')
    batch_size = 128
    budget = epoch

    config = {
        'ndim': 250,
        'sdim': 56,
        'num_gnn_layers': 2,
        'g_aggr': 'gsum',
        'num_acc_layers': 4,
        'lr': 0.00001,
    }

    t0 = time()
    test_dataset = fetch_data('data/test_data_20.pth')
    logging.info('Loaded test graphs in {} sec.'.format(round(time() - t0, 2)))
    t0 = time()
    val_dataset = fetch_data('data/validation_data_10.pth')
    logging.info('Loaded validation graphs model in {} sec.'.format(
        round(time() - t0, 2)))

    test_loader = DataLoader(test_dataset, batch_size=2048, shuffle=False)
    val_loader = DataLoader(val_dataset, batch_size=2048, shuffle=False)

    criterion = nn.MSELoss()

    for num in [training_size]:
        ratio = np.round(num / 100, 2)
        run_name = '{}{}'.format(method, num)

        rmse_list = list()
        all_loss = list()
        best_rmse_list = []
        for step in range(5):

            logger.info('sampling')
            sampled_dataset = sample_func(ratio, data)
            train_loader = DataLoader(sampled_dataset,
                                      batch_size=batch_size,
                                      shuffle=True)
            logger.info('start run {}_{} with {}% ({} graphs) '.format(
                run_name, step + 1, num, len(sampled_dataset)))

            model = GNNpred(config['ndim'], config['sdim']).to(device)
            optimizer = torch.optim.Adam(model.parameters(), lr=config['lr'])

            best_val = np.inf
            best_test = np.inf
            for epoch in range(int(budget)):
                loss = 0
                model.train()
                running_loss = torch.Tensor().to(device)
                for i, graph_batch in enumerate(train_loader):
                    graph_batch = graph_batch.to(device)
                    optimizer.zero_grad()
                    output = model(graph_batch.edge_index,
                                   graph_batch.node_atts,
                                   graph_batch.batch.to(device))
                    loss = criterion(output.view(-1), graph_batch.acc)
                    running_loss = torch.cat([running_loss, loss.view(-1)])
                    loss.backward()
                    optimizer.step()
                loss = torch.sqrt(torch.mean(running_loss)).item()
                all_loss.append(loss)

                logger.info('epoch {}:\tloss = {}'.format(
                    epoch, my_round(loss, 4)))

                val_rmse, _, val_acc = evaluate(model, val_loader, device)

                logger.info('epoch {}:\tval_rmse = {}'.format(
                    epoch, my_round(val_rmse, 4)))

                test_rmse, test_mae, _ = evaluate(model, test_loader, device)

                logger.info('epoch {}:\ttest_rmse = {}'.format(
                    epoch, my_round(test_rmse, 4)))
                logger.info('epoch {}:\ttest_mae = {}'.format(
                    epoch, my_round(test_mae, 4)))

                if val_rmse < best_val:
                    best_val = val_rmse
                    best_test = test_rmse


#                         save(model, run_name)
                rmse_list.append(best_val)
            best_rmse_list.append(best_val)
            logger.info('step {}:\tbest_test = {}'.format(
                step + 1, my_round(best_test, 4)))

            torch.save(rmse_list,
                       path_results + '/{}_all_rmse.pth'.format(run_name))
            logger.info('Saved all validation rmse to {}'.format(path_results))

            torch.save(best_rmse_list,
                       path_results + '/{}_best_rmse.pth'.format(run_name))
            logger.info('Saved best validation rmse of each run to {}'.format(
                path_results))

            torch.save(all_loss,
                       path_results + '/{}_loss.pth'.format(run_name))
            logger.info('Saved trainings loss to {}'.format(path_results))

            torch.save(val_acc,
                       path_saved_acc + '/{}_val_acc.pth'.format(run_name))
            logger.info(
                'Saved true and predicted accuracy of validation set to {}'.
                format(path_saved_acc))

            _, _, train_acc = evaluate(model, train_loader, device)
            torch.save(train_acc,
                       path_saved_acc + '/{}_train_acc.pth'.format(run_name))
            logger.info(
                'Saved true and predicted accuracy of training set to {}'.
                format(path_saved_acc))

            logger.info('epoch {}:\ttest_rmse = {}'.format(
                epoch, my_round(test_rmse, 4)))

    return loss, val_rmse, test_rmse, test_mae, model.number_of_parameters()
Пример #42
0
    def set_cuts(self):
        '''
        Sets the cuts to make the joint
        '''
        spacing = self.params['Spacing'].v - 2 * self.dhtot
        width = self.params['Width'].v
        centered = self.params['Centered'].v

        board_width = self.boards[0].width
        units = self.bit.units
        label = units.increments_to_string(spacing, True)
        self.labels = self.keys[:]
        self.labels[0] += ': ' + label
        self.labels[1] += ': ' + units.increments_to_string(width, True)
        self.description = 'Equally spaced (' + self.labels[0] + \
                           ', ' + self.labels[1] + ')'
        self.cuts = []  # return value
        neck_width = utils.my_round(self.bit.neck + width - self.bit.width +
                                    spacing)
        if neck_width < 1:
            raise Spacing_Exception('Specified bit paramters give a zero'
                                    ' or negative cut width (%d increments) at'
                                    ' the surface!  Please change the'
                                    ' bit parameters width, depth, or angle.' %
                                    neck_width)
        # put a cut at the center of the board
        xMid = board_width // 2
        if centered or \
           self.bit.angle > 0: # always symm. for dovetail
            left = max(0, xMid - width // 2)
        else:
            left = max(0, (xMid // width) * width)
        right = min(board_width, left + width)
        self.cuts.append(router.Cut(left, right))
        # do left side of board
        i = left - neck_width
        min_interior = utils.my_round(self.dhtot + self.bit.offset)
        while i > 0:
            li = max(i - width, 0)
            if i - li > self.config.min_finger_width and i > min_interior:
                self.cuts.append(router.Cut(li, i))
            i = li - neck_width
        # do right side of board
        i = right + neck_width
        while i < board_width:
            ri = min(i + width, board_width)
            if ri - i > self.config.min_finger_width and board_width - i > min_interior:
                self.cuts.append(router.Cut(i, ri))
            i = ri + neck_width
        # If we have only one cut the entire width of the board, then
        # the board width is too small for the bit
        if self.cuts[0].xmin == 0 and self.cuts[0].xmax == board_width:
            raise Spacing_Exception('Unable to compute a equally-spaced'\
                                    ' joint for the board and bit parameters'\
                                    ' specified.  This is likely because'\
                                    ' the board width is too small for the'\
                                    ' bit width specified.')
        # sort the cuts in increasing x
        self.cuts = sorted(self.cuts, key=attrgetter('xmin'))
        if self.config.debug:
            print('e-s cuts:')
            dump_cuts(self.cuts)
Пример #43
0
def test_my_round():
    # Test round up
    assert my_round(10.025, 2) == 10.03

    # Test multiple round up
    assert my_round(19.9951, 2) == 20.00

    assert my_round(10, 2) == 10

    with pytest.raises(ValueError) as e:
        my_round(10, 200000000) == 10
    assert str(e.value) == "Precision should be between 0 and 20"

    assert my_round(10, 20) == 10
    assert my_round(10, 0) == 10

    assert my_round(10.01234567891011121314555555555, 20) == 10.01234567891011121314555555555
    assert my_round(10.01234567891011121314555555555, 18) == 10.01234567891011121314555555555

    assert my_round(10.025, 10) == 10.025
    assert my_round(10.025454555557885454242, 10) == 10.0254545556

    assert my_round(10.025, 20) == 10.025
    assert my_round(10.025454555557885454242, 20) == 10.025454555557885454242
    assert my_round(10.0254545555578854542424444447585876545645, 20) == 10.025454555557885454242

    assert my_round(0.00000000000000000000000009, 20) == 0
    assert my_round(1.11111115e2, 1) == 111.1

    # Big round
    assert my_round(99999999999999999999999999999999999999, 20) == 1e38
    assert my_round(1e10, 5) == 10000000000.0

    # small round
    assert my_round(1e-100000, 20) == 0

    # Negative round
    assert my_round(-1.045754345454242, 6) == -1.045754
    assert my_round(-0.47513146390886934, 6) == -0.475131