text:
import datetime as dt
from unittest import SkipTest

import numpy as np

from holoviews.core import NdOverlay
from holoviews.core.options import Cycle
from holoviews.core.util import pd
from holoviews.element import Points
from holoviews.streams import Stream

from .testplot import TestBokehPlot, bokeh_renderer
from ..utils import ParamLogStream

try:
    from bokeh.models import FactorRange, LinearColorMapper, CategoricalColorMapper
    from bokeh.models import Scatter
except:
    pass

class TestPointPlot(TestBokehPlot):

    def test_points_colormapping(self):
        points = Points(np.random.rand(10, 4), vdims=['a', 'b']).opts(plot=dict(color_index=3))
        self._test_colormapping(points, 3)

    def test_points_colormapping_with_nonselection(self):
        opts = dict(plot=dict(color_index=3),
                    style=dict(nonselection_color='red'))
        points = Points(np.random.rand(10, 4), vdims=['a', 'b']).opts(**opts)
        self._test_colormapping(points, 3)

    def test_points_colormapping_categorical(self):
        points = Points([(i, i*2, i*3, chr(65+i)) for i in range(10)],
                         vdims=['a', 'b']).opts(plot=dict(color_index='b'))
        plot = bokeh_renderer.get_plot(points)
        plot.initialize_plot()
        cmapper = plot.handles['color_mapper']
        self.assertIsInstance(cmapper, CategoricalColorMapper)
        self.assertEqual(cmapper.factors, list(points['b']))

    def test_points_color_selection_nonselection(self):
        opts = dict(color='green', selection_color='red', nonselection_color='blue')
        points = Points([(i, i*2, i*3, chr(65+i)) for i in range(10)],
                         vdims=['a', 'b']).opts(style=opts)
        plot = bokeh_renderer.get_plot(points)
        glyph_renderer = plot.handles['glyph_renderer']
        self.assertEqual(glyph_renderer.glyph.fill_color, 'green')
        self.assertEqual(glyph_renderer.glyph.line_color, 'green')
        self.assertEqual(glyph_renderer.selection_glyph.fill_color, 'red')
        self.assertEqual(glyph_renderer.selection_glyph.line_color, 'red')
        self.assertEqual(glyph_renderer.nonselection_glyph.fill_color, 'blue')
        self.assertEqual(glyph_renderer.nonselection_glyph.line_color, 'blue')

    def test_points_alpha_selection_nonselection(self):
        opts = dict(alpha=0.8, selection_alpha=1.0, nonselection_alpha=0.2)
        points = Points([(i, i*2, i*3, chr(65+i)) for i in range(10)],
                         vdims=['a', 'b']).opts(style=opts)
        plot = bokeh_renderer.get_plot(points)
        glyph_renderer = plot.handles['glyph_renderer']
        self.assertEqual(glyph_renderer.glyph.fill_alpha, 0.8)
        self.assertEqual(glyph_renderer.glyph.line_alpha, 0.8)
        self.assertEqual(glyph_renderer.selection_glyph.fill_alpha, 1)
        self.assertEqual(glyph_renderer.selection_glyph.line_alpha, 1)
        self.assertEqual(glyph_renderer.nonselection_glyph.fill_alpha, 0.2)
        self.assertEqual(glyph_renderer.nonselection_glyph.line_alpha, 0.2)

    def test_points_alpha_selection_partial(self):
        opts = dict(selection_alpha=1.0, selection_fill_alpha=0.2)
        points = Points([(i, i*2, i*3, chr(65+i)) for i in range(10)],
                         vdims=['a', 'b']).opts(style=opts)
        plot = bokeh_renderer.get_plot(points)
        glyph_renderer = plot.handles['glyph_renderer']
        self.assertEqual(glyph_renderer.glyph.fill_alpha, 1.0)
        self.assertEqual(glyph_renderer.glyph.line_alpha, 1.0)
        self.assertEqual(glyph_renderer.selection_glyph.fill_alpha, 0.2)
        self.assertEqual(glyph_renderer.selection_glyph.line_alpha, 1)

    def test_batched_points(self):
        overlay = NdOverlay({i: Points(np.arange(i)) for i in range(1, 100)})
        plot = bokeh_renderer.get_plot(overlay)
        extents = plot.get_extents(overlay, {})
        self.assertEqual(extents, (0, 0, 98, 98))

    def test_batched_points_size_and_color(self):
        opts = {'NdOverlay': dict(plot=dict(legend_limit=0)),
                'Points': dict(style=dict(size=Cycle(values=[1, 2])))}
        overlay = NdOverlay({i: Points([(i, j) for j in range(2)])
                             for i in range(2)}).opts(opts)
        plot = bokeh_renderer.get_plot(overlay).subplots[()]
        size = np.array([1, 1, 2, 2])
        color = np.array(['#30a2da', '#30a2da', '#fc4f30', '#fc4f30'],
                         dtype='<U7')
        self.assertEqual(plot.handles['source'].data['color'], color)
        self.assertEqual(plot.handles['source'].data['size'], size)

    def test_batched_points_line_color_and_color(self):
        opts = {'NdOverlay': dict(plot=dict(legend_limit=0)),
                'Points': dict(style=dict(line_color=Cycle(values=['red', 'blue'])))}
        overlay = NdOverlay({i: Points([(i, j) for j in range(2)])
                             for i in range(2)}).opts(opts)
        plot = bokeh_renderer.get_plot(overlay).subplots[()]
        line_color = np.array(['red', 'red', 'blue', 'blue'])
        fill_color = np.array(['#30a2da', '#30a2da', '#fc4f30', '#fc4f30'],
                         dtype='<U7')
        self.assertEqual(plot.handles['source'].data['fill_color'], fill_color)
        self.assertEqual(plot.handles['source'].data['line_color'], line_color)

    def test_batched_points_alpha_and_color(self):
        opts = {'NdOverlay': dict(plot=dict(legend_limit=0)),
                'Points': dict(style=dict(alpha=Cycle(values=[0.5, 1])))}
        overlay = NdOverlay({i: Points([(i, j) for j in range(2)])
                             for i in range(2)}).opts(opts)
        plot = bokeh_renderer.get_plot(overlay).subplots[()]
        alpha = np.array([0.5, 0.5, 1., 1.])
        color = np.array(['#30a2da', '#30a2da', '#fc4f30', '#fc4f30'],
                         dtype='<U7')
        self.assertEqual(plot.handles['source'].data['alpha'], alpha)
        self.assertEqual(plot.handles['source'].data['color'], color)

    def test_batched_points_line_width_and_color(self):
        opts = {'NdOverlay': dict(plot=dict(legend_limit=0)),
                'Points': dict(style=dict(line_width=Cycle(values=[0.5, 1])))}
        overlay = NdOverlay({i: Points([(i, j) for j in range(2)])
                             for i in range(2)}).opts(opts)
        plot = bokeh_renderer.get_plot(overlay).subplots[()]
        line_width = np.array([0.5, 0.5, 1., 1.])
        color = np.array(['#30a2da', '#30a2da', '#fc4f30', '#fc4f30'],
                         dtype='<U7')
        self.assertEqual(plot.handles['source'].data['line_width'], line_width)
        self.assertEqual(plot.handles['source'].data['color'], color)

    def test_points_overlay_datetime_hover(self):
        if pd is None:
            raise SkipTest("Test requires pandas")
        obj = NdOverlay({i: Points((list(pd.date_range('2016-01-01', '2016-01-31')), range(31))) for i in range(5)},
                        kdims=['Test'])
        opts = {'Points': {'tools': ['hover']}}
        obj = obj.opts(plot=opts)
        self._test_hover_info(obj, [('Test', '@{Test}'), ('x', '@{x_dt_strings}'), ('y', '@{y}')])

    def test_points_overlay_hover_batched(self):
        obj = NdOverlay({i: Points(np.random.rand(10,2)) for i in range(5)},
                        kdims=['Test'])
        opts = {'Points': {'tools': ['hover']},
                'NdOverlay': {'legend_limit': 0}}
        obj = obj.opts(plot=opts)
        self._test_hover_info(obj, [('Test', '@{Test}'), ('x', '@{x}'), ('y', '@{y}')])

    def test_points_overlay_hover(self):
        obj = NdOverlay({i: Points(np.random.rand(10,2)) for i in range(5)},
                        kdims=['Test'])
        opts = {'Points': {'tools': ['hover']},
                'NdOverlay': {'legend_limit': 0}}
        obj = obj.opts(plot=opts)
        self._test_hover_info(obj, [('Test', '@{Test}'), ('x', '@{x}'),
                                    ('y', '@{y}')])

    def test_points_no_single_item_legend(self):
        points = Points([('A', 1), ('B', 2)], label='A')
        plot = bokeh_renderer.get_plot(points)
        plot.initialize_plot()
        fig = plot.state
        self.assertEqual(len(fig.legend), 0)

    def test_points_non_numeric_size_warning(self):
        data = (np.arange(10), np.arange(10), list(map(chr, range(94,104))))
        points = Points(data, vdims=['z']).opts(plot=dict(size_index=2))
        with ParamLogStream() as log:
            bokeh_renderer.get_plot(points)
        log_msg = log.stream.read()
        warning = ('z dimension is not numeric, '
                   'cannot use to scale Points size.\n')
        self.assertEqual(log_msg, warning)

    def test_points_categorical_xaxis(self):
        points = Points((['A', 'B', 'C'], (1,2,3)))
        plot = bokeh_renderer.get_plot(points)
        x_range = plot.handles['x_range']
        self.assertIsInstance(x_range, FactorRange)
        self.assertEqual(x_range.factors, ['A', 'B', 'C'])

    def test_points_categorical_xaxis_mixed_type(self):
        points = Points(range(10))
        points2 = Points((['A', 'B', 'C', 1, 2.0], (1, 2, 3, 4, 5)))
        plot = bokeh_renderer.get_plot(points*points2)
        x_range = plot.handles['x_range']
        self.assertIsInstance(x_range, FactorRange)
        self.assertEqual(x_range.factors, list(map(str, range(10))) + ['A', 'B', 'C', '2.0'])

    def test_points_categorical_xaxis_invert_axes(self):
        points = Points((['A', 'B', 'C'], (1,2,3))).opts(plot=dict(invert_axes=True))
        plot = bokeh_renderer.get_plot(points)
        y_range = plot.handles['y_range']
        self.assertIsInstance(y_range, FactorRange)
        self.assertEqual(y_range.factors, ['A', 'B', 'C'])

    def test_points_overlay_categorical_xaxis(self):
        points = Points((['A', 'B', 'C'], (1,2,3)))
        points2 = Points((['B', 'C', 'D'], (1,2,3)))
        plot = bokeh_renderer.get_plot(points*points2)
        x_range = plot.handles['x_range']
        self.assertIsInstance(x_range, FactorRange)
        self.assertEqual(x_range.factors, ['A', 'B', 'C', 'D'])

    def test_points_overlay_categorical_xaxis_invert_axis(self):
        points = Points((['A', 'B', 'C'], (1,2,3))).opts(plot=dict(invert_xaxis=True))
        points2 = Points((['B', 'C', 'D'], (1,2,3)))
        plot = bokeh_renderer.get_plot(points*points2)
        x_range = plot.handles['x_range']
        self.assertIsInstance(x_range, FactorRange)
        self.assertEqual(x_range.factors, ['A', 'B', 'C', 'D'][::-1])

    def test_points_overlay_categorical_xaxis_invert_axes(self):
        points = Points((['A', 'B', 'C'], (1,2,3))).opts(plot=dict(invert_axes=True))
        points2 = Points((['B', 'C', 'D'], (1,2,3)))
        plot = bokeh_renderer.get_plot(points*points2)
        y_range = plot.handles['y_range']
        self.assertIsInstance(y_range, FactorRange)
        self.assertEqual(y_range.factors, ['A', 'B', 'C', 'D'])

    def test_points_padding_square(self):
        points = Points([1, 2, 3]).options(padding=0.1)
        plot = bokeh_renderer.get_plot(points)
        x_range, y_range = plot.handles['x_range'], plot.handles['y_range']
        self.assertEqual(x_range.start, -0.2)
        self.assertEqual(x_range.end, 2.2)
        self.assertEqual(y_range.start, 0.8)
        self.assertEqual(y_range.end, 3.2)

    def test_curve_padding_square_per_axis(self):
        curve = Points([1, 2, 3]).options(padding=((0, 0.1), (0.1, 0.2)))
        plot = bokeh_renderer.get_plot(curve)
        x_range, y_range = plot.handles['x_range'], plot.handles['y_range']
        self.assertEqual(x_range.start, 0)
        self.assertEqual(x_range.end, 2.2)
        self.assertEqual(y_range.start, 0.8)
        self.assertEqual(y_range.end, 3.4)

    def test_points_padding_unequal(self):
        points = Points([1, 2, 3]).options(padding=(0.05, 0.1))
        plot = bokeh_renderer.get_plot(points)
        x_range, y_range = plot.handles['x_range'], plot.handles['y_range']
        self.assertEqual(x_range.start, -0.1)
        self.assertEqual(x_range.end, 2.1)
        self.assertEqual(y_range.start, 0.8)
        self.assertEqual(y_range.end, 3.2)

    def test_points_padding_nonsquare(self):
        points = Points([1, 2, 3]).options(padding=0.1, width=600)
        plot = bokeh_renderer.get_plot(points)
        x_range, y_range = plot.handles['x_range'], plot.handles['y_range']
        self.assertEqual(x_range.start, -0.1)
        self.assertEqual(x_range.end, 2.1)
        self.assertEqual(y_range.start, 0.8)
        self.assertEqual(y_range.end, 3.2)

    def test_points_padding_logx(self):
        points = Points([(1, 1), (2, 2), (3,3)]).options(padding=0.1, logx=True)
        plot = bokeh_renderer.get_plot(points)
        x_range, y_range = plot.handles['x_range'], plot.handles['y_range']
        self.assertEqual(x_range.start, 0.89595845984076228)
        self.assertEqual(x_range.end, 3.3483695221017129)
        self.assertEqual(y_range.start, 0.8)
        self.assertEqual(y_range.end, 3.2)

    def test_points_padding_logy(self):
        points = Points([1, 2, 3]).options(padding=0.1, logy=True)
        plot = bokeh_renderer.get_plot(points)
        x_range, y_range = plot.handles['x_range'], plot.handles['y_range']
        self.assertEqual(x_range.start, -0.2)
        self.assertEqual(x_range.end, 2.2)
        self.assertEqual(y_range.start, 0.89595845984076228)
        self.assertEqual(y_range.end, 3.3483695221017129)

    def test_points_padding_datetime_square(self):
        points = Points([(np.datetime64('2016-04-0%d' % i), i) for i in range(1, 4)]).options(
            padding=0.1
        )
        plot = bokeh_renderer.get_plot(points)
        x_range, y_range = plot.handles['x_range'], plot.handles['y_range']
        self.assertEqual(x_range.start, np.datetime64('2016-03-31T19:12:00.000000000'))
        self.assertEqual(x_range.end, np.datetime64('2016-04-03T04:48:00.000000000'))
        self.assertEqual(y_range.start, 0.8)
        self.assertEqual(y_range.end, 3.2)

    def test_points_padding_datetime_nonsquare(self):
        points = Points([(np.datetime64('2016-04-0%d' % i), i) for i in range(1, 4)]).options(
            padding=0.1, width=600
        )
        plot = bokeh_renderer.get_plot(points)
        x_range, y_range = plot.handles['x_range'], plot.handles['y_range']
        self.assertEqual(x_range.start, np.datetime64('2016-03-31T21:36:00.000000000'))
        self.assertEqual(x_range.end, np.datetime64('2016-04-03T02:24:00.000000000'))
        self.assertEqual(y_range.start, 0.8)
        self.assertEqual(y_range.end, 3.2)

    def test_points_padding_hard_xrange(self):
        points = Points([1, 2, 3]).redim.range(x=(0, 3)).options(padding=0.1)
        plot = bokeh_renderer.get_plot(points)
        x_range, y_range = plot.handles['x_range'], plot.handles['y_range']
        self.assertEqual(x_range.start, 0)
        self.assertEqual(x_range.end, 3)
        self.assertEqual(y_range.start, 0.8)
        self.assertEqual(y_range.end, 3.2)

    def test_points_padding_soft_xrange(self):
        points = Points([1, 2, 3]).redim.soft_range(x=(0, 3)).options(padding=0.1)
        plot = bokeh_renderer.get_plot(points)
        x_range, y_range = plot.handles['x_range'], plot.handles['y_range']
        self.assertEqual(x_range.start, 0)
        self.assertEqual(x_range.end, 3)
        self.assertEqual(y_range.start, 0.8)
        self.assertEqual(y_range.end, 3.2)

    def test_points_datetime_hover(self):
        points = Points([(0, 1, dt.datetime(2017, 1, 1))], vdims='date').options(tools=['hover'])
        plot = bokeh_renderer.get_plot(points)
        cds = plot.handles['cds']
        self.assertEqual(cds.data['date'].astype('datetime64'), np.array([1483228800000000000]))
        self.assertEqual(cds.data['date_dt_strings'], ['2017-01-01 00:00:00'])
        hover = plot.handles['hover']
        self.assertEqual(hover.tooltips, [('x', '@{x}'), ('y', '@{y}'), ('date', '@{date_dt_strings}')])

    def test_points_selected(self):
        points = Points([(0, 0), (1, 1), (2, 2)]).opts(selected=[0, 2])
        plot = bokeh_renderer.get_plot(points)
        cds = plot.handles['cds']
        self.assertEqual(cds.selected.indices, [0, 2])

    def test_points_update_selected(self):
        stream = Stream.define('Selected', selected=[])()
        points = Points([(0, 0), (1, 1), (2, 2)]).apply.opts(selected=stream.param.selected)
        plot = bokeh_renderer.get_plot(points)
        cds = plot.handles['cds']
        self.assertEqual(cds.selected.indices, [])
        stream.event(selected=[0, 2])
        self.assertEqual(cds.selected.indices, [0, 2])

    ###########################
    #    Styling mapping      #
    ###########################

    def test_point_color_op(self):
        points = Points([(0, 0, '#000'), (0, 1, '#F00'), (0, 2, '#0F0')],
                        vdims='color').options(color='color')
        plot = bokeh_renderer.get_plot(points)
        cds = plot.handles['cds']
        glyph = plot.handles['glyph']
        self.assertEqual(cds.data['color'], np.array(['#000', '#F00', '#0F0']))
        self.assertEqual(glyph.fill_color, {'field': 'color'})
        self.assertEqual(glyph.line_color, {'field': 'color'})

    def test_point_linear_color_op(self):
        points = Points([(0, 0, 0), (0, 1, 1), (0, 2, 2)],
                        vdims='color').options(color='color')
        plot = bokeh_renderer.get_plot(points)
        cds = plot.handles['cds']
        glyph = plot.handles['glyph']
        cmapper = plot.handles['color_color_mapper']
        self.assertTrue(cmapper, LinearColorMapper)
        self.assertEqual(cmapper.low, 0)
        self.assertEqual(cmapper.high, 2)
        self.assertEqual(cds.data['color'], np.array([0, 1, 2]))
        self.assertEqual(glyph.fill_color, {'field': 'color', 'transform': cmapper})
        self.assertEqual(glyph.line_color, {'field': 'color', 'transform': cmapper})

    def test_point_categorical_color_op(self):
        points = Points([(0, 0, 'A'), (0, 1, 'B'), (0, 2, 'C')],
                        vdims='color').options(color='color')
        plot = bokeh_renderer.get_plot(points)
        cds = plot.handles['cds']
        glyph = plot.handles['glyph']
        cmapper = plot.handles['color_color_mapper']
        self.assertTrue(cmapper, CategoricalColorMapper)
        self.assertEqual(cmapper.factors, ['A', 'B', 'C'])
        self.assertEqual(cds.data['color'], np.array(['A', 'B', 'C']))
        self.assertEqual(glyph.fill_color, {'field': 'color', 'transform': cmapper})
        self.assertEqual(glyph.line_color, {'field': 'color', 'transform': cmapper})

    def test_point_categorical_dtype_color_op(self):
        df = pd.DataFrame(dict(sample_id=['subject 1', 'subject 2', 'subject 3', 'subject 4'], category=['apple', 'pear', 'apple', 'pear'], value=[1, 2, 3, 4]))
        df['category'] = df['category'].astype('category')
        points = Points(df, ['sample_id', 'value']).opts(color='category')
        plot = bokeh_renderer.get_plot(points)
        cds = plot.handles['cds']
        glyph = plot.handles['glyph']
        cmapper = plot.handles['color_color_mapper']
        self.assertTrue(cmapper, CategoricalColorMapper)
        self.assertEqual(cmapper.factors, ['apple', 'pear'])
        self.assertEqual(np.asarray(cds.data['color']), np.array(['apple', 'pear', 'apple', 'pear']))
        self.assertEqual(glyph.fill_color, {'field': 'color', 'transform': cmapper})
        self.assertEqual(glyph.line_color, {'field': 'color', 'transform': cmapper})

    def test_point_explicit_cmap_color_op(self):
        points = Points([(0, 0), (0, 1), (0, 2)]).options(
            color='y', cmap={0: 'red', 1: 'green', 2: 'blue'})
        plot = bokeh_renderer.get_plot(points)
        cds = plot.handles['cds']
        glyph = plot.handles['glyph']
        cmapper = plot.handles['color_color_mapper']
        self.assertTrue(cmapper, CategoricalColorMapper)
        self.assertEqual(cmapper.factors, ['0', '1', '2'])
        self.assertEqual(cmapper.palette, ['red', 'green', 'blue'])
        self.assertEqual(cds.data['color_str__'], ['0', '1', '2'])
        self.assertEqual(glyph.fill_color, {'field': 'color_str__', 'transform': cmapper})
        self.assertEqual(glyph.line_color, {'field': 'color_str__', 'transform': cmapper})

    def test_point_line_color_op(self):
        points = Points([(0, 0, '#000'), (0, 1, '#F00'), (0, 2, '#0F0')],
                        vdims='color').options(line_color='color')
        plot = bokeh_renderer.get_plot(points)
        cds = plot.handles['cds']
        glyph = plot.handles['glyph']
        self.assertEqual(cds.data['line_color'], np.array(['#000', '#F00', '#0F0']))
        self.assertNotEqual(glyph.fill_color, {'field': 'line_color'})
        self.assertEqual(glyph.line_color, {'field': 'line_color'})

    def test_point_fill_color_op(self):
        points = Points([(0, 0, '#000'), (0, 1, '#F00'), (0, 2, '#0F0')],
                        vdims='color').options(fill_color='color')
        plot = bokeh_renderer.get_plot(points)
        cds = plot.handles['cds']
        glyph = plot.handles['glyph']
        self.assertEqual(cds.data['fill_color'], np.array(['#000', '#F00', '#0F0']))
        self.assertEqual(glyph.fill_color, {'field': 'fill_color'})
        self.assertNotEqual(glyph.line_color, {'field': 'fill_color'})

    def test_point_angle_op(self):
        points = Points([(0, 0, 0), (0, 1, 45), (0, 2, 90)],
                        vdims='angle').options(angle='angle')
        plot = bokeh_renderer.get_plot(points)
        cds = plot.handles['cds']
        glyph = plot.handles['glyph']
        self.assertEqual(cds.data['angle'], np.array([0, 0.785398, 1.570796]))
        self.assertEqual(glyph.angle, {'field': 'angle'})

    def test_point_alpha_op(self):
        points = Points([(0, 0, 0), (0, 1, 0.2), (0, 2, 0.7)],
                        vdims='alpha').options(alpha='alpha')
        plot = bokeh_renderer.get_plot(points)
        cds = plot.handles['cds']
        glyph = plot.handles['glyph']
        self.assertEqual(cds.data['alpha'], np.array([0, 0.2, 0.7]))
        self.assertEqual(glyph.fill_alpha, {'field': 'alpha'})

    def test_point_line_alpha_op(self):
        points = Points([(0, 0, 0), (0, 1, 0.2), (0, 2, 0.7)],
                        vdims='alpha').options(line_alpha='alpha')
        plot = bokeh_renderer.get_plot(points)
        cds = plot.handles['cds']
        glyph = plot.handles['glyph']
        self.assertEqual(cds.data['line_alpha'], np.array([0, 0.2, 0.7]))
        self.assertEqual(glyph.line_alpha, {'field': 'line_alpha'})
        self.assertNotEqual(glyph.fill_alpha, {'field': 'line_alpha'})

    def test_point_fill_alpha_op(self):
        points = Points([(0, 0, 0), (0, 1, 0.2), (0, 2, 0.7)],
                        vdims='alpha').options(fill_alpha='alpha')
        plot = bokeh_renderer.get_plot(points)
        cds = plot.handles['cds']
        glyph = plot.handles['glyph']
        self.assertEqual(cds.data['fill_alpha'], np.array([0, 0.2, 0.7]))
        self.assertNotEqual(glyph.line_alpha, {'field': 'fill_alpha'})
        self.assertEqual(glyph.fill_alpha, {'field': 'fill_alpha'})

    def test_point_size_op(self):
        points = Points([(0, 0, 1), (0, 1, 4), (0, 2, 8)],
                        vdims='size').options(size='size')
        plot = bokeh_renderer.get_plot(points)
        cds = plot.handles['cds']
        glyph = plot.handles['glyph']
        self.assertEqual(cds.data['size'], np.array([1, 4, 8]))
        self.assertEqual(glyph.size, {'field': 'size'})

    def test_point_line_width_op(self):
        points = Points([(0, 0, 1), (0, 1, 4), (0, 2, 8)],
                        vdims='line_width').options(line_width='line_width')
        plot = bokeh_renderer.get_plot(points)
        cds = plot.handles['cds']
        glyph = plot.handles['glyph']
        self.assertEqual(cds.data['line_width'], np.array([1, 4, 8]))
        self.assertEqual(glyph.line_width, {'field': 'line_width'})

    def test_point_marker_op(self):
        points = Points([(0, 0, 'circle'), (0, 1, 'triangle'), (0, 2, 'square')],
                        vdims='marker').options(marker='marker')
        plot = bokeh_renderer.get_plot(points)
        cds = plot.handles['cds']
        glyph = plot.handles['glyph']
        self.assertEqual(cds.data['marker'], np.array(['circle', 'triangle', 'square']))
        self.assertEqual(glyph.marker, {'field': 'marker'})

    def test_op_ndoverlay_value(self):
        markers = ['circle', 'triangle']
        overlay = NdOverlay({marker: Points(np.arange(i)) for i, marker in enumerate(markers)}, 'Marker').options('Points', marker='Marker')
        plot = bokeh_renderer.get_plot(overlay)
        for subplot, glyph_type, marker in zip(plot.subplots.values(), [Scatter, Scatter], markers):
            self.assertIsInstance(subplot.handles['glyph'], glyph_type)
            self.assertEqual(subplot.handles['glyph'].marker, marker)

    def test_point_color_index_color_clash(self):
        points = Points([(0, 0, 0), (0, 1, 1), (0, 2, 2)],
                        vdims='color').options(color='color', color_index='color')
        with ParamLogStream() as log:
            bokeh_renderer.get_plot(points)
        log_msg = log.stream.read()
        warning = ("Cannot declare style mapping for 'color' option "
                   "and declare a color_index; ignoring the color_index.\n")
        self.assertEqual(log_msg, warning)

    def test_point_color_index_color_no_clash(self):
        points = Points([(0, 0, 0), (0, 1, 1), (0, 2, 2)],
                        vdims='color').options(fill_color='color', color_index='color')
        plot = bokeh_renderer.get_plot(points)
        glyph = plot.handles['glyph']
        cmapper = plot.handles['fill_color_color_mapper']
        cmapper2 = plot.handles['color_mapper']
        self.assertEqual(glyph.fill_color, {'field': 'fill_color', 'transform': cmapper})
        self.assertEqual(glyph.line_color, {'field': 'color', 'transform': cmapper2})

    def test_point_size_index_size_clash(self):
        points = Points([(0, 0, 0), (0, 1, 1), (0, 2, 2)],
                        vdims='size').options(size='size', size_index='size')
        with ParamLogStream() as log:
            bokeh_renderer.get_plot(points)
        log_msg = log.stream.read()
        warning = ("Cannot declare style mapping for 'size' option "
                   "and declare a size_index; ignoring the size_index.\n")
        self.assertEqual(log_msg, warning)

max_stars_repo_name: Guillemdb/holoviews

max_issues_repo_name: Guillemdb/holoviews

max_forks_repo_name: Guillemdb/holoviews


text:
'''
Este script define a classe Mentor, incluindo métodos
matemáticos para cálculo de cinématica direta e inversa
do manipulador, orientação e posição do atuador final,
verificação de posição e correções de quadrante.

Este arquivo pode ser importado como um módulo utilizando:
from src.mentor import Mentor
'''
import itertools
import numpy as np

class Mentor:
    '''
    Classe de um robo mentor. A classe será definida
    por elementos que obedeçam as leis de cinemática do robô mentor,
    além de limitações (constraints) de velocidade e posição.

    Atributos
    ----------
    alpha : list
        List contendo tempo, angulos e velocidades discretizadas.
    a: list
        Métrica de distância percorrida do elemento.
    d: list
        Coordenadas cartesianos do elemento ao longo do tempo.

    Métodos
    -------
    test_inverse_kinematics(self, pos, rot, tag_theta1=True, tag_theta2=True, tag_theta3=True):
        Método de teste de todos os ângulos, para verificação se os quadrantes se encontram corretos.
    get_angles(self, pos, rot):
        Cálculo de cinemática inversa para todas as possibilidades de quadrantes entre os três primeiros
        atuadores rotacionais do robô.
    _inverse_kinematics(self, pos, orientation, tag_theta1=True, tag_theta2=True, tag_theta3=True):
        Cálculo da cinemática inversa para uma cenário específico.
    verify(self, pos, rot, returned_pos, returned_rot):
        Verificação se posição encontrada pela cinemática é compatível com o desejado.
    get_position(self, theta, z_axis=0):
        Aplicação de cinemática direta para encontrar posição do atuador.
    get_orientation(self, alpha, beta, gamma):
        Aplicação de cinemática direta para encontrar orientação do atuador.
    separate(self, matrix, z_axis):
        Separação da matriz extendida nas parcelas de rotação e translação.
    denavit(self, theta, i):
        Aplicação de denavit hartenberg para encontrar matriz de transformação.
    fix_quadrante(self, sin, cos):
        Ajustar quadrante a partir de sin e cos de ângulo.
    fix_theta(self, param, tag, angle):
        Ajustar quadrante a partir de qualquer parâmetro de entrada possivel.
    '''
    def __init__(self):
        '''
        Não há parâmetros de entrada neste método. Apenas a definição dos
        parâmetros de Denavit-Hartenberg.
        '''
        self.alpha = [0, -np.pi/2, 0, 0, -np.pi/2]
        self.a = [0, 0, 17.2739, 15.5, 0]
        self.d = [0, 0, 0, 0, 0]

    def test_inverse_kinematics(self, pos, rot, tag_theta1=True, tag_theta2=True, tag_theta3=True):
        '''
        Método de teste de todos os ângulos, fazendo o cálculo da cinemática inversa e
        a verificação se os quadrantes estão corretos. Ajustes dos ângulos com base nas
        tags especificadas. A função de cinemática inversa é chamada para encontrar os ângulos,
        para então serem passados para função verify que testará se os mesmos estão corretos.

        Parâmetros
        ----------
        pos: list
            Lista com informações de posição do atuador final do manipuldor
            no espaço cartesiano.
        rot: list
            Matriz de rotação do atuador final do manipulador no espaço
            cartesiano.
        tag_theta1: bool(opcional):
            Tag de verificação se há erro no quadrante do ângulo 1.
        tag_theta2: bool(opcional):
            Tag de verificação se há erro no quadrante do ângulo 2.
        tag_theta3: bool(opcional):
            Tag de verificação se há erro no quadrante do ângulo 3.

        Retorna
        -------
        tag:
            Verificação de há erro ou não na cinemática inversa.
        theta:
            Lista com ângulos calculados.
        '''

        theta = self._inverse_kinematics(pos, rot, tag_theta1=tag_theta1, tag_theta2=tag_theta2, tag_theta3=tag_theta3)
        returned_pos, returned_rot = self.get_position(theta)
        tag = self.verify(pos, rot, returned_pos, returned_rot)
        return tag, theta

    def get_angles(self, pos, rot):
        '''
        Método para efetuar cinemática inversa em todos os cenários possíveis
        de erros de quadrantes. Com base nisso é possível identificar se a
        posição/orientação inserida pelo usuário é atingível ou não pelo manipulador.

        Parâmetros
        ----------
        pos: list
            Lista com informações de posição do atuador final do manipuldor
            no espaço cartesiano.
        rot: list
            Matriz de rotação do atuador final do manipulador no espaço
            cartesiano.

        Retorna
        -------
        tag:
            Booleano que identifica (se verdadeiro) se há erro e a posição é impossível
        theta:
            Lista com ângulos calculados para cinemática inversa.
        '''
        for element in itertools.product([True, False],[False, True],[False, True]):
            tag, theta = self.test_inverse_kinematics(pos, rot, element[0], element[1], element[2])
            if tag:
                return False, theta
        return True, theta

    def _inverse_kinematics(self, pos, orientation, tag_theta1=True, tag_theta2=True, tag_theta3=True):
        '''
        Método para cálculo da cinemática inversa. Esta função implementa o equacionamento
        mostrado na documentação do projeto. A correção de quadrante é feita com base
        nas tags de cada ângulo.

        Parâmetros
        ----------
        pos: list
            Lista com informações de posição do atuador final do manipuldor
            no espaço cartesiano.
        rot: list
            Matriz de rotação do atuador final do manipulador no espaço
            cartesiano.
        tag_theta1: bool(opcional):
            Tag de verificação se há erro no quadrante do ângulo 1.
        tag_theta2: bool(opcional):
            Tag de verificação se há erro no quadrante do ângulo 2.
        tag_theta3: bool(opcional):
            Tag de verificação se há erro no quadrante do ângulo 3.

        Retorna
        -------
        theta:
            Lista com ângulos calculados para cinemática inversa.
        '''
        theta = []
        theta1 = np.nan_to_num(self.fix_theta(pos, tag_theta1, 'theta1'))
        theta.append(theta1)
        theta3 = self.fix_theta((pos[0]**2+pos[1]**2+pos[2]**2-self.a[2]**2-self.a[3]**2)/(2*self.a[2]*self.a[3]), tag_theta3, 'theta3')
        theta3 = np.nan_to_num(theta3)
        theta2  = np.nan_to_num(-theta3+self.fix_theta(((-np.cos(theta3)*self.a[2]-self.a[3])*pos[2]+np.sin(theta3)*self.a[2]*(np.sin(theta1)*pos[1]+pos[0]*np.cos(theta1)))/(np.power(np.cos(theta1)*pos[0]+np.sin(theta1)*pos[1], 2)+pos[2]*pos[2]), tag_theta2, 'theta2'))
        theta.append(theta2)
        theta.append(theta3)
        sin_theta4 = np.sin(theta2+theta3)*orientation[2][2] - np.cos(theta1)*np.cos(theta2+theta3)*orientation[0][2] - np.sin(theta1)*np.cos(theta2+theta3)*orientation[1][2]
        cos_theta4 = -np.cos(theta2+theta3)*orientation[2][2] - np.cos(theta1)*np.sin(theta2+theta3)*orientation[0][2] - np.sin(theta1)*np.sin(theta2+theta3)*orientation[1][2]
        theta.append(self.fix_quadrante(sin_theta4, cos_theta4))
        sin_theta5 = np.sin(theta1)*orientation[0][0] - np.cos(theta1)*orientation[1][0]
        cos_theta5 = np.sin(theta1)*orientation[0][1] - np.cos(theta1)*orientation[1][1]
        theta.append(self.fix_quadrante(sin_theta5, cos_theta5))
        return theta

    def verify(self, pos, rot, returned_pos, returned_rot):
        '''
        Método para verificação se os ângulos encontrados realmente
        atingem a posição solicitada.

        Parâmetros
        ----------
        pos: list
            Lista com informações de posição correta do atuador final do manipuldor
            no espaço cartesiano.
        rot: list
            Matriz de rotação correta do atuador final do manipulador no espaço
            cartesiano.
        returned_pos: list
            Lista com informações de posição do atuador final do manipuldor
            no espaço cartesiano.
        returned_rot: list
            Matriz de rotação do atuador final do manipulador no espaço
            cartesiano.

        Retorna
        -------
        Retorna boolean para identifição se a posição está ou não correta.
        '''
        diff = pos[:3]-returned_pos[:3]
        rot_norm = np.linalg.norm(rot-returned_rot)
        if rot_norm > 0.001 or abs(diff[0])>0.001 or abs(diff[1]>0.001) or abs(diff[2]>0.001):
            return False
        else:
            return True

    def get_position(self, theta, z_axis=0):
        '''
        Método para encontrar posição a partir da cinemática direta.

        Parâmetros
        ----------
        theta: Numpy Array
            Vetor com os ângulos das juntas.
        z_axis: float (opcional)
            Distância do sistema de coordenadas do atuador final em
            relação à última junta rotacional do Mentor.

        Retorna
        -------
        Matrizes de rotação e orientação que definem o sistema de coordenada
        final do atuador no sistema cartesiano da base.
        '''
        matrix = np.matmul(self.denavit(theta, 3),self.denavit(theta, 4))
        for i in range(3):
            matrix = np.matmul(self.denavit(theta, 2-i), matrix)
        return self.separate(matrix, z_axis)

    def get_orientation(self, alpha, beta, gamma):
        '''
        Método para verificação dos constraints. Com base na velocidade
        máxima permitida definida nas constantes.

        Parâmetros
        ----------
        alpha: float
            Ângulo de orientação do eixo X.
        beta: float
            Ângulo de orientação do eixo Y.
        gamma: float
            Ângulo de orientação do eixo Z.            .

        Retorna
        -------
        Matriz de rotação encontrada a partir dos ângulos alpha-beta-gamma.
        '''
        return [[np.cos(alpha)*np.cos(beta), np.cos(alpha)*np.sin(beta)*np.sin(gamma) - np.sin(alpha)*np.cos(gamma), np.cos(alpha)*np.sin(beta)*np.cos(gamma) + np.sin(alpha)*np.sin(gamma) ],
                        [np.sin(alpha)*np.cos(beta), np.sin(alpha)*np.sin(beta)*np.sin(gamma) + np.cos(alpha)*np.cos(gamma), np.sin(alpha)*np.sin(beta)*np.cos(gamma) - np.cos(alpha)*np.sin(gamma) ],
                        [-np.sin(beta), -np.cos(beta)*np.sin(gamma), np.cos(beta)*np.cos(gamma)]]

    def separate(self, matrix, z_axis):
        '''
        Método para separação da matriz de Denavit-Hartenberg
        da última junta nas parcelas de posição e orientação.

        Parâmetros
        ----------
        theta: Numpy Array
            Vetor com os ângulos das juntas.
        z_axis: float (opcional)
            Distância do sistema de coordenadas do atuador final em
            relação à última junta rotacional do Mentor.

        Retorna
        -------
        pos: float
            Matriz 3x3 de rotação do robô que define a orientação da garra.
        np.array(rot):
            Matriz 3x3 de rotação do robô que define a orientação da garra.
        '''
        pos =  np.matmul(matrix, [0,0,z_axis,1])
        rot = [matrix[i][:-1] for i in range(3)]
        return pos, np.array(rot)

    def denavit(self, theta, i):
        '''
        Método para criação de matriz de Denavit-Hartenberg de uma
        determinada transição de sistemas coordenados.

        Parâmetros
        ----------
        theta: list
            Lista com ângulos das juntas em determinado instante.
        i: int
            Index que definirá entre quais sistemas coordenados está acontecendo
            está transformação de coordenadas.

        Retorna
        -------
        Matrix 4x4 extendida e triangular por blocos que contém
            matriz de rotação (3x3) e vetor de posição (3x1).
        '''
        return  [[np.cos(theta[i]), -np.sin(theta[i]),  0,   self.a[i]],
            [np.sin(theta[i])*np.cos(self.alpha[i]), np.cos(theta[i])*np.cos(self.alpha[i]), -np.sin(self.alpha[i]), -np.sin(self.alpha[i])*self.d[i]],
            [np.sin(theta[i])*np.sin(self.alpha[i]), np.cos(theta[i])*np.sin(self.alpha[i]), np.cos(self.alpha[i]), np.cos(self.alpha[i])*self.d[i]],
            [0, 0, 0, 1]]

    def fix_quadrante(self, sin, cos):
        '''
        Método para correção de quadrante a partir do par sin/cos.

        Parâmetros
        ----------
        sin: float
            Tempo de duração da simulação.
        cos: float
            Tempo de duração da simulação.

        Retorna
        -------
        Ângulo ajustado para o quadrante correto
        '''
        if sin >= 0 and cos >= 0:
            return np.arcsin(abs(sin))
        if sin >= 0  and cos <= 0:
            return np.pi - np.arcsin(abs(sin))
        if sin <= 0 and cos >= 0:
            return 2*np.pi - np.arcsin(abs(sin))
        if sin <= 0 and cos <= 0:
            return np.arccos(abs(cos)) + np.pi

    def fix_theta(self, param, tag, angle):
        '''
        Método correção dos três primeiros ângulos do robô.

        Parâmetros
        ----------
        parm: float
            Parâmetro que será analisado para o ajuste, podendo ser,
            lista de posição (x,y), sin e cos.
        tag: boolean
            Tag de verificação que determina se o ângulo está correto ou não.
        angle: str
            Descritivo sobre qual ângulo é, permitindo vincular com
            operação matemática especifica.

        Retorna
        -------
        Ângulo corrigido para o quadrante correto.
        '''
        if angle=='theta1':
            if abs(param[0]) < 0.001:
                param = np.pi/2
            else:
                param = np.arctan(param[1]/ param[0])
        if tag and param>=0:
            if angle == 'theta1':
                return param
            if angle == 'theta2':
                return np.arcsin(abs(param))
            if angle == 'theta3':
                return np.arccos(abs(param))
        if not tag and param>=0:
            if angle == 'theta1':
                return np.pi + param
            if angle == 'theta2':
                return np.pi-np.arcsin(abs(param))
            if angle == 'theta3':
                return 2*np.pi-np.arccos(abs(param))
        if tag and param<=0:
            if angle == 'theta1':
                return 2*np.pi - abs(param)
            if angle == 'theta2':
                return 2*np.pi - np.arcsin(abs(param))
            if angle == 'theta3':
                return np.pi-np.arccos(abs(param))
        if not tag and param<=0:
            if angle == 'theta1':
                return np.pi - abs(param)
            if angle == 'theta2':
                return np.pi + np.arcsin(abs(param))
            if angle == 'theta3':
                return np.pi + np.arccos(abs(param))

ext: py

max_stars_repo_name: oscarkremer/antenna-modeling

max_issues_repo_name: oscarkremer/antenna-modeling

max_forks_repo_name: oscarkremer/antenna-modeling

reason: import numpy


text:
import cv2
import numpy as np
import pymba
import time
import Motorsteps as MS
import test_cameras as tc

##tc.test_cameras(0)
MS.Imageprocess('test','home/pi/MDX_codes/','home/pi/MDX_codes/')
MS.img2('test','home/pi/MDX_codes/','home/pi/MDX_codes/')


text:
import numpy as np
from openvino.inference_engine import IENetwork,IECore
import cv2
from matplotlib import pyplot as plt

class face_detection:

    def __init__(self, model_name, device='CPU', extensions=None):
        self.model_weights=model_name+'.bin'
        self.model_structure=model_name+'.xml'
        self.device=device

    def load_model(self):
        # Loading network to device
        self.core = IECore()
        self.model=self.core.read_network(self.model_structure, self.model_weights)
        self.net = self.core.load_network(network=self.model, device_name=self.device, num_requests=1)
        print("Successfully loaded Face Detection model")

    def pre_process_input(self,image):
        self.image=image
        resized_img = cv2.resize(self.image, (672,384)) #width,height
        input_img = np.moveaxis(resized_img, -1, 0)
        input_img=np.expand_dims(input_img, axis=0)
        return input_img

    def check_model(self):
        layers_supported = self.core.query_network(network=self.model, device_name="CPU")
        layers_in_model = self.model.layers.keys()
        all_layers_supported = True
        for l in layers_in_model:
            if l  not in layers_supported:
                all_layers_supported = False
                print('Layer', l, '- Not supported')
        if all_layers_supported:
            print('All layers supported - FaceDetection Model')

    def get_input_name(self):
        self.input_name = next(iter(self.net.inputs))

    def predict(self, image):
        result = self.net.infer({self.input_name:image})
        return result

    def preprocess_output(self, res):
        prediction = res.get('detection_out')
        ih, iw = self.image.shape[:-1]
        tmp_image = self.image
        self.boxes=[]

        for results in prediction[0][0]:
            if (np.int(results[1])==1 and results[2] > 0.9):
                xmin = np.int(iw * results[3])
                ymin = np.int(ih * results[4])
                xmax = np.int(iw * results[5])
                ymax = np.int(ih * results[6])
                self.boxes.append([xmin, ymin, xmax, ymax])

        return tmp_image,self.boxes

    def plot_image(self,output_image):
        img = cv2.cvtColor(output_image, cv2.COLOR_BGR2RGB)
        plt.figure(figsize = (15,9))
        plt.imshow(img,interpolation='nearest', aspect='auto')
        plt.show()

    def save_image(self,image_id,image):
        cv2.imwrite("bin/face_detection-{}.jpg".format(image_id+1), image)
        print("saved image as: bin/face_detection-{}.jpg".format(image_id+1))

    def cropped_image(self):
        cropped_output = []
        for id,images in enumerate(self.boxes):
            crop_img_org = self.image[images[1]:images[3], images[0]:images[2]] #ymin:ymax, xmin:xmax
            cropped_output.append(crop_img_org)
        return cropped_output

    def get_face_location(self):
        face_loc_list=[]
        for face_id,box in enumerate(self.boxes):
            face_loc = self.image[box[1]:box[3], box[0]:box[2]]
            face_loc_list.append(face_loc)
        return face_loc_list


text:
import os
import pickle
import re
import numpy as np

from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request

def log_print(text, logger, log_only = False):
    if not log_only:
        print(text)
    if logger is not None:
        logger.info(text)

def get_module_name(obj):
    try:
        return re.findall(r"[A-Za-z0-9]+'",str(type(obj)))[0].replace("'",'')
    except:
        return "Name not found"

def upload_google_sheets(upload_dict, spreadsheet_id = '1nliojVYnyy-42Sy-OFy3rB28dOdNakTA06oHa-Gyg9c', sheet_name = 'CV_Record', logger = None):
    SCOPES = ['https://www.googleapis.com/auth/spreadsheets']

    # Authentication
    creds = None
    # The file token.pickle stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)

    service = build('sheets', 'v4', credentials=creds)

    # Get Current Row Number and headings
    sheet = service.spreadsheets()
    currentRowNumber = len(sheet.values().get(spreadsheetId=spreadsheet_id, range=f'{sheet_name}!1:1000').execute()['values'])
    headings = sheet.values().get(spreadsheetId=spreadsheet_id, range=f'{sheet_name}!1:1').execute()['values'][0]

    upload_list = []
    for header in headings:
        if header in upload_dict.keys():
            upload_list.append(str(upload_dict[header]))
        else:
            upload_list.append('')

    # Upload to Google Sheets
    body = {
        'values': [upload_list]
    }
    result = service.spreadsheets().values().update(
        spreadsheetId=spreadsheet_id, range=f'{sheet_name}!{currentRowNumber+1}:{currentRowNumber+1}',
        valueInputOption='USER_ENTERED', body=body).execute()
    log_print('Results Uploaded', logger)

def compute_cm_binary(y_pred, y):
    TP = np.logical_and(y_pred == 1, y == 1).sum()
    TN = np.logical_and(y_pred == 0, y == 0).sum()
    FP = np.logical_and(y_pred == 1, y == 0).sum()
    FN = np.logical_and(y_pred == 0, y == 1).sum()
    return TN, FP, FN, TP

def get_iou_score(y_pred, y, threshold):
    y_pred = np.where(y_pred > threshold, 1, 0)
    tn ,fp, fn, tp = compute_cm_binary(y_pred, y)
    iou_score = (2*tp) / (2*tp + fp + fn)
    return iou_score

max_stars_repo_name: o-hx/CV-Proj

max_issues_repo_name: o-hx/CV-Proj

max_forks_repo_name: o-hx/CV-Proj


text:
#! python3
# -*- coding:utf-8 -*-
import cv2
import numpy as np

#open video
cap = cv2.VideoCapture(0)

# Define the codec and create VideoWriter object
# FourCC は動画のコーデックを指定するための4バイトのコードで、使用可能なコードのリストは fourcc.org で確認できる．OS依存なので気を付けて選ぶこと．
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
# filename,FourCC codec, framerate,width $ height
out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480))

#cap.set(11,20) #Brightness video only
#cap.set(12,0) #Contrast video only
#cap.set(13,0) #Saturation video only
#cap.set(14,0) #Hue video only
#cap.set(15,0) #Gain video only
#cap.set(16,150) #Exposure video only
#cap.set(17,0)   #bool flag for converted to RGB
while True:
    ret ,frame = cap.read()

    if ret==True:
        #
        #frame = cv2.flip(frame,0)

        # write the frame
        out.write(frame)
        cv2.imshow('frame',frame)
        if cv2.waitKey(1) & 0xff == ord('q'):
            break

cap.release()
out.release()
cv2.destroyAllWindows()

max_stars_repo_name: OKKyu/PythonLearn

max_issues_repo_name: OKKyu/PythonLearn

max_forks_repo_name: OKKyu/PythonLearn


text:
r"""
Affine Crystals
"""
#*****************************************************************************
#       Copyright (C) 2008 Brant Jones <brant at math.ucdavis.edu>
#                          Anne Schilling <anne at math.ucdavis.edu>
#
#  Distributed under the terms of the GNU General Public License (GPL)
#                  http://www.gnu.org/licenses/
#****************************************************************************
# Acknowledgment: most of the design and implementation of this
# library is heavily inspired from MuPAD-Combinat.
#****************************************************************************

from sage.misc.abstract_method import abstract_method
from sage.categories.regular_crystals import RegularCrystals
from sage.categories.finite_crystals import FiniteCrystals
from sage.structure.parent import Parent
from sage.structure.unique_representation import UniqueRepresentation
from sage.structure.element_wrapper import ElementWrapper
from sage.combinat.root_system.cartan_type import CartanType

class AffineCrystalFromClassical(UniqueRepresentation, Parent):
    r"""
    This abstract class can be used for affine crystals that are constructed
    from a classical crystal. The zero arrows can be implemented using
    different methods (for example using a Dynkin diagram automorphisms or
    virtual crystals).

    This is a helper class, mostly used to implement Kirillov-Reshetikhin
    crystals (see:
    :func:`~sage.combinat.crystals.kirillov_reshetikhin.KirillovReshetikhinCrystal`).

    For general information about crystals see :mod:`sage.combinat.crystals`.

    INPUT:

    - ``cartan_type`` -- the Cartan type of the resulting affine crystal

    - ``classical_crystal`` -- instance of a classical crystal

    EXAMPLES::

        sage: n = 2
        sage: C = crystals.Tableaux(['A',n],shape=[1])
        sage: pr = attrcall("promotion")
        sage: pr_inverse = attrcall("promotion_inverse")
        sage: A = crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
        sage: A.list()
        [[[1]], [[2]], [[3]]]
        sage: A.cartan_type()
        ['A', 2, 1]
        sage: A.index_set()
        (0, 1, 2)
        sage: b=A(rows=[[1]])
        sage: b.weight()
        -Lambda[0] + Lambda[1]
        sage: b.classical_weight()
        (1, 0, 0)
        sage: [x.s(0) for x in A.list()]
        [[[3]], [[2]], [[1]]]
        sage: [x.s(1) for x in A.list()]
        [[[2]], [[1]], [[3]]]
    """
    @staticmethod
    def __classcall__(cls, cartan_type, *args, **options):
        """
        TESTS::

            sage: n = 1
            sage: C = crystals.Tableaux(['A',n],shape=[1])
            sage: pr = attrcall("promotion")
            sage: pr_inverse = attrcall("promotion_inverse")
            sage: A = crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1) # indirect doctest
            sage: B = crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1) # indirect doctest
            sage: A is B
            True
        """
        ct = CartanType(cartan_type)
        return super(AffineCrystalFromClassical, cls).__classcall__(cls, ct, *args, **options)

    def __init__(self, cartan_type, classical_crystal, category = None):
        """
        Input is an affine Cartan type ``cartan_type``, a classical crystal
        ``classical_crystal``, and automorphism and its inverse
        ``automorphism`` and ``inverse_automorphism``, and the Dynkin node
        ``dynkin_node``.

        EXAMPLES::

            sage: n = 1
            sage: C = crystals.Tableaux(['A',n],shape=[1])
            sage: pr = attrcall("promotion")
            sage: pr_inverse = attrcall("promotion_inverse")
            sage: A = crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1) # indirect doctest
            sage: A.list()
            [[[1]], [[2]]]
            sage: A.cartan_type()
            ['A', 1, 1]
            sage: A.index_set()
            (0, 1)

        .. NOTE::

            :class:`~sage.combinat.crystals.affine.AffineCrystalFromClassical`
            is an abstract class, so we can't test it directly.

        TESTS::

            sage: TestSuite(A).run()
        """
        if category is None:
            category = (RegularCrystals(), FiniteCrystals())
        self._cartan_type = cartan_type
        Parent.__init__(self, category = category)
        self.classical_crystal = classical_crystal;
        self.module_generators = [self.retract(_) for _ in self.classical_crystal.module_generators]
        self.element_class._latex_ = lambda x: x.lift()._latex_()

    def _repr_(self):
        """
        EXAMPLES::

            sage: n=1
            sage: C=crystals.Tableaux(['A',n],shape=[1])
            sage: pr = attrcall("promotion")
            sage: pr_inverse = attrcall("promotion_inverse")
            sage: crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1) # indirect doctest
            An affine crystal for type ['A', 1, 1]
        """
        return "An affine crystal for type {}".format(self.cartan_type())

    def __iter__(self):
        r"""
        Construct the iterator from the underlying classical crystal.

        TESTS::

            sage: n=1
            sage: C=crystals.Tableaux(['A',n],shape=[1])
            sage: pr = attrcall("promotion")
            sage: pr_inverse = attrcall("promotion_inverse")
            sage: A=crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1) # indirect doctest
            sage: A.list() # indirect doctest
            [[[1]], [[2]]]
        """
        for x in self.classical_crystal:
            yield self.retract(x)

    # should be removed once crystal defines __iter__ instead of list
    def list(self):
        """
        Return the list of all crystal elements using the underlying
        classical crystal.

        EXAMPLES::

            sage: n=2
            sage: C=crystals.Tableaux(['A',n],shape=[1])
            sage: pr = attrcall("promotion")
            sage: pr_inverse = attrcall("promotion_inverse")
            sage: A=crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
            sage: A.list()
            [[[1]], [[2]], [[3]]]
        """
        return [self.retract(_) for _ in self.classical_crystal.list()]

    def lift(self, affine_elt):
        """
        Lift an affine crystal element to the corresponding classical
        crystal element.

        EXAMPLES::

            sage: n=2
            sage: C=crystals.Tableaux(['A',n],shape=[1])
            sage: pr = attrcall("promotion")
            sage: pr_inverse = attrcall("promotion_inverse")
            sage: A=crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
            sage: b=A.list()[0]
            sage: A.lift(b)
            [[1]]
            sage: A.lift(b).parent()
            The crystal of tableaux of type ['A', 2] and shape(s) [[1]]
        """
        return affine_elt.lift()

    def retract(self, classical_elt):
        """
        Transform a classical crystal element to the corresponding
        affine crystal element.

        EXAMPLES::

            sage: n=2
            sage: C=crystals.Tableaux(['A',n],shape=[1])
            sage: pr = attrcall("promotion")
            sage: pr_inverse = attrcall("promotion_inverse")
            sage: A=crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
            sage: t=C(rows=[[1]])
            sage: t.parent()
            The crystal of tableaux of type ['A', 2] and shape(s) [[1]]
            sage: A.retract(t)
            [[1]]
            sage: A.retract(t).parent() is A
            True
        """
        return self.element_class(self, classical_elt)

    def _element_constructor_(self, *value, **options):
        r"""
        Coerces ``value`` into ``self``.

        EXAMPLES::

            sage: n=2
            sage: C=crystals.Tableaux(['A',n],shape=[1])
            sage: pr = attrcall("promotion")
            sage: pr_inverse = attrcall("promotion_inverse")
            sage: A=crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
            sage: b=A(rows=[[1]]) # indirect doctest
            sage: b
            [[1]]
            sage: b.parent()
            An affine crystal for type ['A', 2, 1]
            sage: A(b) is b
            True
        """
        if len(value) == 1 and isinstance(value[0], self.element_class) and value[0].parent() == self:
            return value[0]
        else: # Should do sanity checks!  (Including check for inconsistent parent.)
            return self.retract(self.classical_crystal(*value, **options))

    def __contains__(self, x):
        r"""
        Checks whether ``x`` is an element of ``self``.

        EXAMPLES::

            sage: n=2
            sage: C=crystals.Tableaux(['A',n],shape=[1])
            sage: pr = attrcall("promotion")
            sage: pr_inverse = attrcall("promotion_inverse")
            sage: A=crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
            sage: b=A(rows=[[1]])
            sage: A.__contains__(b)
            True
        """
        return x.parent() is self

class AffineCrystalFromClassicalElement(ElementWrapper):
    r"""
    Elements of crystals that are constructed from a classical crystal.
    The elements inherit many of their methods from the classical crystal
    using lift and retract.

    This class is not instantiated directly but rather ``__call__``-ed from
    :class:`~sage.combinat.crystals.affine.AffineCrystalFromClassical`.
    The syntax of this is governed by the (classical) crystal.

    EXAMPLES::

        sage: n=2
        sage: C=crystals.Tableaux(['A',n],shape=[1])
        sage: pr = attrcall("promotion")
        sage: pr_inverse = attrcall("promotion_inverse")
        sage: A=crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
        sage: b=A(rows=[[1]])
        sage: b._repr_()
        '[[1]]'
    """
    def classical_weight(self):
        """
        Return the classical weight corresponding to ``self``.

        EXAMPLES::

            sage: n=2
            sage: C=crystals.Tableaux(['A',n],shape=[1])
            sage: pr = attrcall("promotion")
            sage: pr_inverse = attrcall("promotion_inverse")
            sage: A=crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
            sage: b=A(rows=[[1]])
            sage: b.classical_weight()
            (1, 0, 0)
        """
        return self.lift().weight()

    def lift(self):
        """
        Lift an affine crystal element to the corresponding classical
        crystal element.

        EXAMPLES::

            sage: n=2
            sage: C=crystals.Tableaux(['A',n],shape=[1])
            sage: pr = attrcall("promotion")
            sage: pr_inverse = attrcall("promotion_inverse")
            sage: A=crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
            sage: b=A.list()[0]
            sage: b.lift()
            [[1]]
            sage: b.lift().parent()
            The crystal of tableaux of type ['A', 2] and shape(s) [[1]]
        """
        return self.value

    def pp(self):
        """
        Method for pretty printing.

        EXAMPLES::

            sage: K = crystals.KirillovReshetikhin(['D',3,2],1,1)
            sage: t=K(rows=[[1]])
            sage: t.pp()
            1
        """
        return self.lift().pp()

    @abstract_method
    def e0(self):
        r"""
        Assumes that `e_0` is implemented separately.
        """

    @abstract_method
    def f0(self):
        r"""
        Assumes that `f_0` is implemented separately.
        """

    def e(self, i):
        r"""
        Return the action of `e_i` on ``self``.

        EXAMPLES::

            sage: n=2
            sage: C=crystals.Tableaux(['A',n],shape=[1])
            sage: pr = attrcall("promotion")
            sage: pr_inverse = attrcall("promotion_inverse")
            sage: A=crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
            sage: b=A(rows=[[1]])
            sage: b.e(0)
            [[3]]
            sage: b.e(1)
        """
        if i == 0:
            return self.e0()
        else:
            x = self.lift().e(i)
            if (x is None):
                return None
            else:
                return self.parent().retract(x)

    def f(self, i):
        r"""
        Return the action of `f_i` on ``self``.

        EXAMPLES::

            sage: n=2
            sage: C=crystals.Tableaux(['A',n],shape=[1])
            sage: pr = attrcall("promotion")
            sage: pr_inverse = attrcall("promotion_inverse")
            sage: A=crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
            sage: b=A(rows=[[3]])
            sage: b.f(0)
            [[1]]
            sage: b.f(2)
        """
        if i == 0:
            return self.f0()
        else:
            x = self.lift().f(i)
            if (x is None):
                return None
            else:
                return self.parent().retract(x)

    def epsilon0(self):
        r"""
        Uses `\varepsilon_0` from the super class, but should be implemented
        if a faster implementation exists.

        EXAMPLES::

            sage: n=2
            sage: C=crystals.Tableaux(['A',n],shape=[1])
            sage: pr = attrcall("promotion")
            sage: pr_inverse = attrcall("promotion_inverse")
            sage: A=crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
            sage: [x.epsilon0() for x in A.list()]
            [1, 0, 0]
        """
        return super(AffineCrystalFromClassicalElement, self).epsilon(0)

    def epsilon(self, i):
        """
        Return the maximal time the crystal operator `e_i`
        can be applied to ``self``.

        EXAMPLES::

            sage: n=2
            sage: C=crystals.Tableaux(['A',n],shape=[1])
            sage: pr = attrcall("promotion")
            sage: pr_inverse = attrcall("promotion_inverse")
            sage: A=crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
            sage: [x.epsilon(0) for x in A.list()]
            [1, 0, 0]
            sage: [x.epsilon(1) for x in A.list()]
            [0, 1, 0]
        """
        if i == 0:
            return self.epsilon0()
        else:
            return self.lift().epsilon(i)

    def phi0(self):
        r"""
        Uses `\varphi_0` from the super class, but should be implemented
        if a faster implementation exists.

        EXAMPLES::

            sage: n=2
            sage: C=crystals.Tableaux(['A',n],shape=[1])
            sage: pr = attrcall("promotion")
            sage: pr_inverse = attrcall("promotion_inverse")
            sage: A=crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
            sage: [x.phi0() for x in A.list()]
            [0, 0, 1]
        """
        return super(AffineCrystalFromClassicalElement, self).phi(0)

    def phi(self, i):
        r"""
        Returns the maximal time the crystal operator `f_i` can be applied to self.

        EXAMPLES::

            sage: n=2
            sage: C=crystals.Tableaux(['A',n],shape=[1])
            sage: pr = attrcall("promotion")
            sage: pr_inverse = attrcall("promotion_inverse")
            sage: A=crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
            sage: [x.phi(0) for x in A.list()]
            [0, 0, 1]
            sage: [x.phi(1) for x in A.list()]
            [1, 0, 0]
        """
        if i == 0:
            return self.phi0()
        else:
            return self.lift().phi(i)

    def __lt__(self, other):
        """
        Non elements of the crystal are incomparable with elements of the
        crystal (or should it return ``NotImplemented``?). Elements of this
        crystal are compared using the comparison in the underlying
        classical crystal.

        EXAMPLES::

            sage: K = crystals.KirillovReshetikhin(['A',2,1],1,1)
            sage: b = K(rows=[[1]])
            sage: c = K(rows=[[2]])
            sage: c<b
            False
            sage: b<b
            False
            sage: b<c
            True
        """
        if self.parent() is not other.parent():
            return False
        return self.lift() < other.lift()

AffineCrystalFromClassical.Element = AffineCrystalFromClassicalElement

class AffineCrystalFromClassicalAndPromotion(AffineCrystalFromClassical):
    r"""
    Crystals that are constructed from a classical crystal and a
    Dynkin diagram automorphism `\sigma`.  In type `A_n`, the Dynkin
    diagram automorphism is `i \to i+1 \pmod n+1` and the
    corresponding map on the crystal is the promotion operation
    `\mathrm{pr}` on tableaux. The affine crystal operators are given
    by `f_0= \mathrm{pr}^{-1} f_{\sigma(0)} \mathrm{pr}`.

    INPUT:

    - ``cartan_type`` -- the Cartan type of the resulting affine crystal

    - ``classical_crystal`` -- instance of a classical crystal

    - ``automorphism, inverse_automorphism`` -- a function on the
      elements of the ``classical_crystal``

    - ``dynkin_node`` -- an integer specifying the classical node in the
      image of the zero node under the automorphism sigma

    EXAMPLES::

        sage: n=2
        sage: C=crystals.Tableaux(['A',n],shape=[1])
        sage: pr = attrcall("promotion")
        sage: pr_inverse = attrcall("promotion_inverse")
        sage: A=crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
        sage: A.list()
        [[[1]], [[2]], [[3]]]
        sage: A.cartan_type()
        ['A', 2, 1]
        sage: A.index_set()
        (0, 1, 2)
        sage: b=A(rows=[[1]])
        sage: b.weight()
        -Lambda[0] + Lambda[1]
        sage: b.classical_weight()
        (1, 0, 0)
        sage: [x.s(0) for x in A.list()]
        [[[3]], [[2]], [[1]]]
        sage: [x.s(1) for x in A.list()]
        [[[2]], [[1]], [[3]]]
    """

    def __init__(self, cartan_type, classical_crystal, p_automorphism, p_inverse_automorphism, dynkin_node):
        """
        Input is an affine Cartan type ``cartan_type``, a classical crystal
        ``classical_crystal``, and promotion automorphism and its inverse
        ``p_automorphism`` and ``p_inverse_automorphism``, and the Dynkin
        node ``dynkin_node``.

        EXAMPLES::

            sage: n=1
            sage: C=crystals.Tableaux(['A',n],shape=[1])
            sage: pr = attrcall("promotion")
            sage: pr_inverse = attrcall("promotion_inverse")
            sage: A=crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
            sage: A.list()
            [[[1]], [[2]]]
            sage: A.cartan_type()
            ['A', 1, 1]
            sage: A.index_set()
            (0, 1)

        TESTS::

            sage: TestSuite(A).run()
        """
        AffineCrystalFromClassical.__init__(self, cartan_type, classical_crystal)
        self.p_automorphism = p_automorphism
        self.p_inverse_automorphism = p_inverse_automorphism
        self.dynkin_node = dynkin_node

    def automorphism(self, x):
        """
        Give the analogue of the affine Dynkin diagram automorphism on
        the level of crystals.

        EXAMPLES::

            sage: n=2
            sage: C=crystals.Tableaux(['A',n],shape=[1])
            sage: pr = attrcall("promotion")
            sage: pr_inverse = attrcall("promotion_inverse")
            sage: A=crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
            sage: b=A.list()[0]
            sage: A.automorphism(b)
            [[2]]
        """
        return self.retract( self.p_automorphism( x.lift() ) )

    def inverse_automorphism(self, x):
        """
        Give the analogue of the inverse of the affine Dynkin diagram
        automorphism on the level of crystals.

        EXAMPLES::

            sage: n=2
            sage: C=crystals.Tableaux(['A',n],shape=[1])
            sage: pr = attrcall("promotion")
            sage: pr_inverse = attrcall("promotion_inverse")
            sage: A=crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
            sage: b=A.list()[0]
            sage: A.inverse_automorphism(b)
            [[3]]
        """
        return self.retract( self.p_inverse_automorphism( x.lift() ) )

class AffineCrystalFromClassicalAndPromotionElement(AffineCrystalFromClassicalElement):
    r"""
    Elements of crystals that are constructed from a classical crystal
    and a Dynkin diagram automorphism.  In type `A`, the automorphism is
    the promotion operation on tableaux.

    This class is not instantiated directly but rather ``__call__``-ed from
    :class:`~sage.combinat.crystals.affine.AffineCrystalFromClassicalAndPromotion`.
    The syntax of this is governed by the (classical) crystal.

    Since this class inherits from
    :class:`~sage.combinat.crystals.affine.AffineCrystalFromClassicalElement`,
    the methods that need to be implemented are :meth:`e0`, :meth:`f0` and
    possibly :meth:`epsilon0` and :meth:`phi0` if more efficient
    algorithms exist.

    EXAMPLES::

        sage: n=2
        sage: C=crystals.Tableaux(['A',n],shape=[1])
        sage: pr = attrcall("promotion")
        sage: pr_inverse = attrcall("promotion_inverse")
        sage: A=crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
        sage: b=A(rows=[[1]])
        sage: b._repr_()
        '[[1]]'
    """

    def e0(self):
        r"""
        Implements `e_0` using the automorphism as
        `e_0 = \operatorname{pr}^{-1} e_{dynkin_node} \operatorname{pr}`

        EXAMPLES::

            sage: n=2
            sage: C=crystals.Tableaux(['A',n],shape=[1])
            sage: pr = attrcall("promotion")
            sage: pr_inverse = attrcall("promotion_inverse")
            sage: A=crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
            sage: b=A(rows=[[1]])
            sage: b.e0()
            [[3]]
        """
        x = self.parent().automorphism(self).e(self.parent().dynkin_node)
        if (x is None):
            return None
        else:
            return self.parent().inverse_automorphism(x)

    def f0(self):
        r"""
        Implements `f_0` using the automorphism as
        `f_0 = \operatorname{pr}^{-1} f_{dynkin_node} \operatorname{pr}`

        EXAMPLES::

            sage: n=2
            sage: C=crystals.Tableaux(['A',n],shape=[1])
            sage: pr = attrcall("promotion")
            sage: pr_inverse = attrcall("promotion_inverse")
            sage: A=crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
            sage: b=A(rows=[[3]])
            sage: b.f0()
            [[1]]
        """
        x = self.parent().automorphism(self).f(self.parent().dynkin_node)
        if (x is None):
            return None
        else:
            return self.parent().inverse_automorphism(x)

    def epsilon0(self):
        r"""
        Implements `epsilon_0` using the automorphism.

        EXAMPLES::

            sage: n=2
            sage: C=crystals.Tableaux(['A',n],shape=[1])
            sage: pr = attrcall("promotion")
            sage: pr_inverse = attrcall("promotion_inverse")
            sage: A=crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
            sage: [x.epsilon0() for x in A.list()]
            [1, 0, 0]
        """
        x = self.parent().automorphism(self)
        return x.lift().epsilon(self.parent().dynkin_node)

    def phi0(self):
        r"""
        Implements `phi_0` using the automorphism.

        EXAMPLES::

            sage: n=2
            sage: C=crystals.Tableaux(['A',n],shape=[1])
            sage: pr = attrcall("promotion")
            sage: pr_inverse = attrcall("promotion_inverse")
            sage: A=crystals.AffineFromClassicalAndPromotion(['A',n,1],C,pr,pr_inverse,1)
            sage: [x.phi0() for x in A.list()]
            [0, 0, 1]
        """
        x = self.parent().automorphism(self)
        return x.lift().phi(self.parent().dynkin_node)

AffineCrystalFromClassicalAndPromotion.Element = AffineCrystalFromClassicalAndPromotionElement

max_stars_repo_name: switzel/sage

max_issues_repo_name: switzel/sage

max_forks_repo_name: switzel/sage

reason: from sage


text:
"""
Copyright 2020 The OneFlow Authors. All rights reserved.

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 oneflow as flow

def sparse_softmax_cross_entropy(labels, logits):
    """The interface is consistent with TensorFlow.
    The documentation is referenced from:
    https://www.tensorflow.org/api_docs/python/tf/nn/sparse_softmax_cross_entropy_with_logits

    Computes sparse softmax cross entropy between `logits` and `labels`.

    Measures the probability error in discrete classification tasks in which the
    classes are mutually exclusive (each entry is in exactly one class).  For
    example, each CIFAR-10 image is labeled with one and only one label: an image
    can be a dog or a truck, but not both.

    A common use case is to have logits of shape
    `[batch_size, num_classes]` and have labels of shape
    `[batch_size]`, but higher dimensions are supported, in which
    case the `dim`-th dimension is assumed to be of size `num_classes`.
    `logits` must have the dtype of `float16`, `float32`, or `float64`, and
    `labels` must have the dtype of `int32` or `int64`.

    Args:
        labels (Tensor): shape with [d_0, d_1, ..., d_{r-1}] (where `r` is rank of
            `labels` and output) and dtype `int32` or `int64`. Each entry in `labels`
            must be an index in [0, num_classes).
        logits (Tensor): Per-label activations (typically a linear output) of shape
            [d_0, d_1, ..., d_{r-1}, num_classes] and dtype `float16`, `float32`, or
            `float64`. These activation energies are interpreted as unnormalized log
            probabilities.

    Returns:
        output (Tensor): A `Tensor` of the same shape as `labels` and of the same type as `logits`
        with the softmax cross entropy loss.

    Examples::
        >>> import numpy as np
        >>> import oneflow as flow
        >>> np_logits = np.array(
        ...      [
        ...          [2.0, -5.0, 0.5, -0.1],
        ...          [0.0, 0.0, 1.9, 1.4],
        ...          [-100.0, 100.0, -100.0, -100.0],
        ...      ]
        ...  )
        >>> np_labels = np.array([0, 3, 1])
        >>> logits = flow.tensor(np_logits, dtype=flow.float32)
        >>> labels = flow.tensor(np_labels, dtype=flow.int32)
        >>> output = flow.nn.functional.sparse_softmax_cross_entropy(
        ...     labels=labels, logits=logits
        ... )
        >>> output
        tensor([0.2975, 1.1448, -0.0000], dtype=oneflow.float32)
    """
    return flow._C.sparse_softmax_cross_entropy(logits, labels)

if __name__ == "__main__":
    import doctest

    doctest.testmod(raise_on_error=True)

max_stars_repo_name: grybd/oneflow

max_issues_repo_name: grybd/oneflow

max_forks_repo_name: grybd/oneflow


text:
import time
import unittest
from io import BytesIO

import numpy as np
from matplotlib.axes import Axes
from plotly.graph_objects import Figure

from elastipy import Search, plot
from elastipy.aggregation import Aggregation

from tests import data
from tests.live.base import TestCase

class TestPlot(TestCase):

    @classmethod
    def setUpClass(cls):
        cls.maxDiff = int(1e5)
        data.export_data(data.orders.orders, data.orders.OrderExporter)

    @classmethod
    def tearDownClass(cls):
        data.orders.OrderExporter().delete_index()

    def search(self):
        return Search(index=data.orders.OrderExporter.INDEX_NAME)

    def get_fig_data(self, plt, format: str = "png"):
        if isinstance(plt, Axes):
            file = BytesIO()
            plt.figure.savefig(file, format=format)
            file.seek(0)
            return file.read()
        elif isinstance(plt, Figure):
            # TODO: what could we test here?
            return plt
        else:
            raise AssertionError(f"Invalid plt type '{type(plt)}'")

    def test_backend(self):
        # just check that default is actually what the docs say
        self.assertEqual(
            "matplotlib", plot.get_backend()
        )

    def test_heatmap_matplotlib(self):
        plot.set_backend("matplotlib")

        agg = self.search() \
            .agg_date_histogram(calendar_interval="day") \
            .agg_terms(field="sku").execute()
        ax = agg.plot.heatmap()
        data = self.get_fig_data(ax)

        ax = agg.plot.heatmap(figsize=(20, 20))
        data2 = self.get_fig_data(ax)
        self.assertGreater(len(data2), len(data))

    def test_heatmap_plotly(self):
        plot.set_backend("plotly")

        agg = self.search() \
            .agg_date_histogram("date", calendar_interval="day") \
            .agg_terms("sku", field="sku").execute()

        fig = agg.plot.heatmap(replace={np.nan: 0})
        self.assertEqual("sku", fig.layout.xaxis.title.text)
        self.assertEqual("date", fig.layout.yaxis.title.text)
        self.assertEqual("sku.doc_count", fig.layout.coloraxis.colorbar.title.text)

        fig = agg.plot.heatmap(labels={"x": "override"}, transpose=True)
        self.assertEqual("override", fig.layout.xaxis.title.text)
        self.assertEqual("sku", fig.layout.yaxis.title.text)
        self.assertEqual("sku.doc_count", fig.layout.coloraxis.colorbar.title.text)

        agg = self.search() \
            .agg_date_histogram("date", calendar_interval="day") \
            .agg_terms("sku", field="sku") \
            .metric_sum("qty", field="quantity", return_self=True).execute()

        fig = agg.plot.heatmap()
        self.assertEqual("sku", fig.layout.xaxis.title.text)
        self.assertEqual("date", fig.layout.yaxis.title.text)
        self.assertEqual("qty", fig.layout.coloraxis.colorbar.title.text)

    def assert_line_bar_etc(self, mpl: bool):
        agg: Aggregation = self.search() \
            .agg_date_histogram("date", calendar_interval="day") \
            .metric_sum("qty", field="quantity").execute() \
            .metric_sum("idx", field="item_line_index").execute()

        self.assertTrue(self.get_fig_data(agg.plot(to_index=True)))
        self.assertTrue(self.get_fig_data(agg.plot.bar(to_index=True)))
        self.assertTrue(self.get_fig_data(agg.plot.barh(to_index=True)))
        self.assertTrue(self.get_fig_data(agg.plot.box(to_index=True)))
        self.assertTrue(self.get_fig_data(agg.plot.line(to_index=True)))
        self.assertTrue(self.get_fig_data(agg.plot.hist(to_index=True)))
        if mpl:
            self.assertTrue(self.get_fig_data(agg.plot.kde(to_index=True, y="qty")))
        self.assertTrue(self.get_fig_data(agg.plot.area(to_index=True, y="qty")))
        if mpl:
            self.assertTrue(self.get_fig_data(agg.plot.pie(to_index=True, y="qty")))
        self.assertTrue(self.get_fig_data(agg.plot.scatter("idx", "qty", to_index=True)))
        if mpl:
            self.assertTrue(self.get_fig_data(agg.plot.hexbin("idx", "qty", to_index=True)))

    def test_line_bar_etc_matplotlib(self):
        plot.set_backend("matplotlib")
        self.assert_line_bar_etc(True)

    def test_line_bar_etc_plotly(self):
        plot.set_backend("plotly")
        self.assert_line_bar_etc(False)

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

max_stars_repo_name: defgsus/elastipy

max_issues_repo_name: defgsus/elastipy

max_forks_repo_name: netzkolchose/elastipy


text:
"""
---------------------------------------------------------------------

This module contains the following functions:

kl_gp_reg:
    performs gaussian process regression using kl expansions

eigen_decomp:
    compute the eigendecomposition of an integral operator

eval_eigenfunction:
    evaluate an eigenfunction at one point

check_l2_error:
    check the difference between the effective and true covariance function

gp_reg_naive:
    perform gp regression using a naive implementation

legendre_nodes_weights:
    compute Gaussian nodes and weights on an interval

legendre_eval_exp:
    evaluate a Legendre expansion

legendre_pols:
    evaluate many Legendre polynomials at one point

legendre_mats:
    compute the matrices that convert function tabulation to expansions

kernel_matern32:
    evaluates matern 3/2 kernel

kernel_se:
    evaluates squared-exponential (Gaussian) kernel

---------------------------------------------------------------------

The functions contained in this module are used for performing Gaussian
process regression by using KL-expansion representations
of Gaussian processes.

See https://arxiv.org/abs/2108.05924 for details.

"""

import unittest
import logging
import numpy as np
from scipy.special import legendre as leg
import matplotlib.pyplot as plt

def kl_gp_reg(n, kern, el, a, b, xs, ys, sigma2, check_err=False):
    '''
    evaluate the conditional mean and covariance of a Gaussian process
    regression using KL-expansions. That is, find the mean coefficients
    in the KL-expansion and the covariance of those coefficients

    Parameters
    ----------
    n: int
        the number of discretization nodes
    kern: function
        the covariance kernel (a function) with calling sequence
        `kern(x, y, el)` where `el` is the timescale hyperparameter
    el: float
        timescale of the covariance kernel
    a: float
        the lower bound of the interval on which the Gaussian process is defined
    b: float
        the upper bound of the interval on which the Gaussian process is defined
    xs: array_like
        the independent variable of the data
    ys: array_like
        the dependent variable of the data, ie the observations
    sigma2: float
        the residual variance
    check_err: bool
        when set to True, this function will compute the L2 accuracy of the
        effective covariance kernel compared to the true covariance kernel

    Returns
    -------
    lams: array_like
        the eigenvalues of the integral operator that's discretized
    coefs: array_like
        n x k array with the expansion coefficients in a Legendre basis
        of the KL-expansion basis functions
    coefs_mean: array_like
        arry of length k. the expectation of the coefficients in a
        kl-expansion basis
    coefs_cov: array_like
        k x k array. the covariance of the posterior coefficients
    '''

    # transform xs and el to [-1, 1]
    xs_scaled = -1.0 + 2.0*(xs - a)/(b-a)
    el2_scaled = 2.0*el/(b-a)
    def kern_scaled(x, y):
        return kern(x, y, el2_scaled)

    # number of data points
    nn = np.shape(xs)[0]

    # eigen decomposition of integral operator
    k, lams, _, coefs = eigen_decomp(n, a=-1.0, b=1.0, kern=kern_scaled)
    lams = lams[:k]
    coefs = coefs[:,:k]

    # scale eigenfunctions
    coefs *= np.sqrt(lams)

    # evaluate legendre polynomials at data points for constructing a
    pols = np.zeros((nn, n))
    for i in range(nn):
        pols[i] = legendre_pols(xs_scaled[i], n-1)

    # construct a
    a = np.dot(pols, coefs)

    # eigendecomposition of of ata
    lams_ata, u = np.linalg.eigh(np.dot(a.T, a))

    # compute posterior mean
    aty = np.dot(a.T, ys)
    d_inv = np.diag(1 / (sigma2 + lams_ata))
    coefs_mean = np.dot(u, np.dot(d_inv, np.dot(u.T, aty)))

    # compute posterior covariance
    d_inv = sigma2*d_inv
    coefs_cov = np.dot(u, np.dot(d_inv, u.T))

    # check accuracy by taking L2 difference between the true and effective
    # covariance kernel
    if check_err:
        err1 = check_l2_err(a, b, kern_scaled, coefs, nn=21)
        err2 = check_l2_err(a, b, kern_scaled, coefs, nn=42)
        print(f'L2 error of effective kernel: {err1}')
        print(f'error accuracy: {err2 - err1}')

    return lams, coefs, coefs_mean, coefs_cov

def eval_eigenfunction(coefs, j, a, b, x):
    '''
    evaluate one basis function in the kl-expansion at one point.

    Parameters
    ----------
    coefs: array_like
        an n x m array, each column of which contains the Legendre expansion
        of one eigenfunction.
    j: int
        the index of the eigenfunction to be evaluated
    a: float
        the lower bound of the interval on which the eigenfunction is defined
    b: float
        the upper bound of the interval on which the eigenfunction is defined
    x: float
        the point in \([a, b]\) at which to evaluate the eigenfunction

    Returns
    -------
    f: float
        the value of the eigenfunction
    '''

    n = coefs.shape[0]

    # move x to [a, b]
    x_scaled = -1.0 + 2.0*(x - a)/(b-a)

    # evaluate
    f = legendre_eval_exp(n-1, coefs[:,j], x_scaled)

    return f

def gp_reg_naive(kern, xs, sigma2):
    '''
    construct the full inverse of the covariance matrix that appears in
    Gaussian process regression by taking an eigendecomposition of the
    covariance matrix -- \(K(x_i, x_j) + \sigma^2 * I\). This function
    exists for testing purposes.

    Parameters
    ----------
    kern: function
        the covariance kernel with calling sequence kern(x, y)
    xs: array_like
        the independent variable of the observed data
    sigma2: float
        the residual variance (nugget)

    Returns
    -------
    c_inv: array_like
        n x n array where n is the length of xs and ys. this matrix is
        the inverse of the covariance matrix
    '''

    nn = np.shape(xs)[0]
    gram_mat = np.zeros((nn,nn))

    # construct gram matrix
    for i in range(nn):
        for j in range(nn):
            gram_mat[i, j] = kern(xs[i], xs[j])

    # take eigendecomposition
    lams, u = np.linalg.eigh(gram_mat)

    # construct (K + sigma2 * I)^{-1}
    lams_inv = 1/(lams+ sigma2)
    c_inv = np.dot(u, np.dot(np.diag(lams_inv), u.T))

    return c_inv

def check_l2_err(a, b, kern, coefs, nn):
    '''check the accruracy of a KL-expansion by computing the L2
    norm of the difference between the true kernel and the
    effective kernel -- the outerproduct of eigenfunctions. That
    \(L^2\) difference is an integral over the square
    \([a, b] \\times [a, b] \subseteq \mathbb{R}^2\) and is computed
    using a tensor product of Gaussian nodes.

    Parameters
    ----------
    a: float
        the lower bound of the interval on which the eigenfunctions are defined
    b: float
        the upper bound of the interval on which the eigenfunctions are defined
    kern: function
        the true covariance kernel with calling sequence kern(x, y)
    coefs: array_like
        n x m array of the Legendre expansions of the basis functions of the
        KL-expansion
    nn: int
        the number of Gaussian nodes in each direction

    Returns
    -------
    err: float
        the error
    '''

    # get length of legendre expansions
    n, k = np.shape(coefs)

    ts, whts = legendre_nodes_weights(a, b, nn)

    err = 0.0
    for i in range(nn):
        for j in range(nn):
            x = ts[i]
            y = ts[j]
            dsum = 0.0
            for ijk in range(k):
                f1 = legendre_eval_exp(n-1, coefs[:,ijk], x)
                f2 = legendre_eval_exp(n-1, coefs[:,ijk], y)
                dsum += f1*f2
            err += (dsum - kern(x, y))**2 * whts[i]*whts[j]
    err = np.sqrt(err)

    return err

def legendre_eval_exp(n, legendre_coefs, x):
    '''
    evaluate a legendre expansion at one point using the three-term recurrence
    forumula

    Parameters
    ----------
    n: int
        the length of the Legendre expansion
    legendre_coefs: array_like
        array containing the coefficients in the Legendre expansion
    x: float
        the point at which to evaluate the Legendre expansion

    Returns
    -------
    f: float
        the value of the expansion
    '''

    # initialize recurrence
    pjm2 = 1
    pjm1 = x

    # first two terms
    f = legendre_coefs[0]*pjm2+legendre_coefs[1]*pjm1

    # recurrence
    for j in range(2, n+1):
        pj=  ((2*j-1)*x*pjm1-(j-1)*pjm2 ) / j
        f=f+legendre_coefs[j]*pj
        pjm2 = pjm1
        pjm1 = pj

    return f

def legendre_mats(n):
    '''
    construct matrices for transforming coefficients in a Legendre
    expansion to tabulations at Gaussian nodes and vice versa

    Parameters
    ----------
    n: int
        the size of the square matrices to be returned

    Returns
    -------
    coefs_to_vals: array_like
        n x n matrix that transforms coefficients in legendre expansion
        to its values at Gaussian nodes
    vals_to_coefs: array_like
        n x n matrix that transforms values at Gaussian nodes to
        Legendre expansions
    '''

    # initialize matrices
    vals_to_coefs = np.zeros((n,n))
    coefs_to_vals = np.zeros((n,n))

    # construct order-n Gaussian nodes and weights
    a = -1.0
    b = 1.0
    x, whts = legendre_nodes_weights(a, b, n)

    for i in range(n):
        coefs_to_vals[i] = legendre_pols(x[i], n-1)

    # now, v converts coefficients of a legendre expansion
    # into its values at the gaussian nodes. construct its
    # inverse u, converting the values of a function at
    # gaussian nodes into the coefficients of a legendre
    # expansion of that function
    for i in range(n):
        d = 1.0
        d = d * (2.0 * (i+1) - 1.0) / 2.0
        for j in range(n):
            vals_to_coefs[i,j]=coefs_to_vals[j,i]*whts[j]*d

    return vals_to_coefs, coefs_to_vals

def legendre_pols(x, n):
    '''
    Evaluate the Legendre polynomials of order 0,1,2,...,n at one point

    Parameters
    ----------
    n: float
        the point at which to evluate the polynomials
    n: int
        the order of the largest Legendre polynomial to be evaluated

    Returns
    -------
    pols: array_like
        the Legendre polynomials evaluated at one point
    '''

    # initialize recurrence
    pk = 1.0
    pkp1 = x

    if n == 0:
        return np.array([1.0])
    if n == 1:
        return np.array([1.0, x])

    # n is greater than 2. conduct recursion
    pols = np.zeros(n+1)
    pols[0] = 1.0
    pols[1] = x
    for k in range(1, n):
        pkm1 = pk
        pk = pkp1
        pkp1 = ((2.0*k+1.0)*x*pk-k*pkm1)/(k+1.0)
        pols[k+1] = pkp1

    return pols

def eigen_decomp(n, a, b, kern, tol=10**(-13)):
    """Evaluate the eigendecomposition of the integral operator

      $$Kf(x) = \int_{a}^{b} k(x, y) f(y) dy$$

    using a Nystrom method.

    Parameters
    ----------
    n: int
        the number of discretization nodes
    a: float
        the lower bound of the interval on which the eigenfunctions are defined
    b: float
        the upper bound of the interval on which the eigenfunctions are defined
    kern: function
        the true covariance kernel with calling sequence kern(x, y)
    tol: float
        the number of eigenvalues of magnitude greater than `tol` is
        returned by this function

    Returns
    -------
    k: int
        the number of eigenvalues with magnitude greater than `tol`
    lams: array_like
        array of length n containing eigenvalues of the integral operator
    vals: array_like
        n x n array with eigenfunctions tabulated at gaussian nodes
    coefs: array_like
        n x n array with legendre expansion of eigenvectors
    """

    xs, whts = legendre_nodes_weights(a, b, n)

    # construct kernel matrix
    a = np.zeros((n,n))
    for i in range(n):
        for j in range(n):
            a[i, j] = kern(xs[i], xs[j]) * np.sqrt(whts[i]*whts[j])

    # eigendecomposition of symmetric matrix a
    lams, vals = np.linalg.eigh(a)

    # sort eigenvalues in descending order
    args = np.argsort(lams)[::-1]
    lams = lams[args]
    vals = vals[:,args]

    # truncate eigendecomposition
    for i in range(n):
        if np.abs(lams[i]/lams[0]) > tol:
            k = i

    # scale eigenfunctions back to tabulation space
    for i in range(n):
        for j in range(n):
            vals[i, j] = vals[i, j] / np.sqrt(whts[i])

    # convert eigenfunctions to coefficient space
    vals_to_coefs, _ = legendre_mats(n)
    coefs = np.dot(vals_to_coefs, vals)

    return k, lams, vals, coefs

def legendre_nodes_weights(a, b, n):
    '''
    Compute order-n Gaussian nodes and weights

    Parameters
    ----------
    a: float
        the lower bound of the interval on which the Gaussian nodes are defined
    b: float
        the upper bound of the interval on which the Gaussian nodes are defined
    n: int
        the order of Gaussian nodes

    Returns
    -------
    xs: array_like
        the order-n Gaussian nodes
    weights: array_like
        the order-n Gaussian weights, scaled according to the size of the
        interval specified in the calling sequence
    '''

    # initialize nodes and weights
    xs = np.zeros(n)
    weights = np.zeros(n)

    # get nodes and weights
    xleg = leg(n).weights[:,0]
    wleg = leg(n).weights[:,1]

    # scale weights and scale and shift nodes
    for i in range(n):
        tmp = (xleg[i] + 1.0)/2.0
        xs[i] = a + (b-a)*tmp
        weights[i] = wleg[i]*(b-a)/2.0

    return xs, weights

def kernel_se(x, y, el):
    '''
    squared exponential kernel

    Parameters
    ----------
    x: float
        one argument of the kernel
    y: float
        the other argument of the kernel
    el: float
        the timescale of the kernel

    Returns
    -------
    f: float
        the kernel evaluation
    '''
    return np.exp(-(x - y)**2/(2.0*el**2))

def kernel_matern32(x, y, el):
    '''
    matern 3/2 kernel

    Parameters
    ----------
    x: float
        one argument of the kernel
    y: float
        the other argument of the kernel
    el: float
        the timescale of the kernel

    Returns
    -------
    f: float
        the kernel evaluation
    '''
    tmp = np.sqrt(3)*np.abs(x-y)/el
    return (1.0 + tmp) * np.exp(-tmp)

class TestKL(unittest.TestCase):
    """For unit testing"""
    def test1(self):
        """in this testing routine, we compare the results of Gaussian
        process regression using KL expansions with the same procedure
        using the straightforward naive algorithm that requires o(n^3)
        operations.
        """

        np.random.seed(1)

        # set kernel
        el = 0.5
        def kern(x, y):
            return kernel_se(x, y, el)

        # set residual variance
        sigma2 = 0.7

        # construct data and true solution
        a = -1.0
        b = 1.0
        nn = 10
        xs = np.linspace(a, b, nn)
        eps = np.random.normal(size=nn)
        ys = np.cos(3*np.exp(xs/(b-a))) + eps
        nn_true = 100
        xs_true = np.linspace(a, b, nn_true)
        ys_true = np.cos(3*np.exp(xs_true/(b-a)))

        # use kl-expansions to compute conditional mean and covariance
        # of a Gaussian process. the mean and covariance are defined over
        # the space of coefficients in the kl-expansion
        n = 100
        lams, coefs, coefs_mean, coefs_cov = kl_gp_reg(n, kernel_se, el,
            a, b, xs, ys, sigma2, check_err=False)

        # set points at which to evaluate conditional mean
        nn_sol = 100
        ts_sol = np.linspace(a, b, nn_sol)
        ys_sol = np.zeros_like(ts_sol)

        # tabulate conditional mean
        k = np.shape(lams)[0]
        for i in range(nn_sol):
            f = 0.0
            for j in range(k):
                fj = eval_eigenfunction(coefs, j, a, b, ts_sol[i])
                f = f + fj * coefs_mean[j]
            ys_sol[i] = f

        # and plot it
        plt.scatter(xs, ys)
        plt.plot(ts_sol, ys_sol, c='red')
        plt.plot(xs_true, ys_true)
        plt.savefig('mle.png')

        # compute variance at the points where mean was tabulated
        fs = np.zeros(k)
        variance = np.zeros(nn_sol)
        for i in range(nn_sol):
            for j in range(k):
                fs[j] = eval_eigenfunction(coefs, j, a, b, ts_sol[i])
            variance[i] = np.dot(fs.T, np.dot(coefs_cov, fs.T))

        # now check whether using a naive, o(n^3)
        # straightforward algorithm gets the same solution as the
        # kl-expansion solution.

        # construct the vector C^{-1}*y
        c_inv = gp_reg_naive(kern, xs, sigma2)
        k_inv_y = np.dot(c_inv, ys)

        # tabulate mean at the same points where kl expansions conditional mean
        # was tabulated
        tmp2 = np.zeros((nn_sol, nn))
        for i in range(nn_sol):
            tmp2[i] = kern(ts_sol[i], xs)
        ys_sol2 = np.dot(tmp2, k_inv_y)

        # tabulate variances at each point
        variance2 = np.zeros(nn_sol)
        for i in range(nn_sol):
            variance2[i] = kern(0.0, 0.0) - np.dot(tmp2[i],
                                                   np.dot(c_inv, tmp2[i].T))

        # assert that the solutions obtained via kl expansions and
        # via naive implementation agree to several digits
        np.testing.assert_allclose(variance, variance2, atol=1e-10)
        np.testing.assert_allclose(ys_sol, ys_sol2, atol=1e-10)

if __name__ == '__main__':
    np.seterr(all='ignore')
    logging.basicConfig(format='%(message)s', level=logging.INFO)
    unittest.main()

reason: import numpy,from scipy