import time

import numpy as np
from lightning.impl.primal_cd import CDClassifier
from lightning.impl.sag import SAGAClassifier

from sklearn.datasets import fetch_20newsgroups_vectorized
from lightning.classification import SAGClassifier
from sklearn.linear_model import LogisticRegression

bunch = fetch_20newsgroups_vectorized(subset="all")
X = bunch.data
y = bunch.target
y[y >= 1] = 1

alpha = 1e-3
n_samples = X.shape[0]

sag = SAGClassifier(eta='auto',
                    loss='log',
                    alpha=alpha,
                    tol=1e-10,
                    max_iter=1000,
                    verbose=1,
                    random_state=0)
saga = SAGAClassifier(eta='auto',
                      loss='log',
                      alpha=alpha,
                      tol=1e-10,
                      max_iter=1000,
                      verbose=1,
                      random_state=0)
cd_classifier = CDClassifier(loss='log',
                             alpha=alpha / 2,
                             C=1 / n_samples,
                             tol=1e-10,
                             max_iter=100,
                             verbose=1,
                             random_state=0)
sklearn_sag = LogisticRegression(tol=1e-10, max_iter=1000,
                                 verbose=2, random_state=0,
                                 C=1. / (n_samples * alpha),
                                 solver='sag',
                                 penalty='l2',
                                 fit_intercept=False)

classifiers = [{'name': 'Lightning SAG', 'estimator': sag},
               {'name': 'Lightning SAGA', 'estimator': saga},
               {'name': 'Sklearn SAG', 'estimator': sklearn_sag},
               {'name': 'Lightning CD', 'estimator': cd_classifier},
               ]

start = time.time()
for classifier in classifiers:
    print(classifier['name'])
    clf = classifier['estimator']
    clf.fit(X, y)

    print("Training time", time.time() - start)
    print("Accuracy", np.mean(clf.predict(X) == y))
    n_nz = np.sum(np.sum(clf.coef_ != 0, axis=0, dtype=bool))
    n_nz /= clf.coef_.size
    print(clf.coef_)
    print('Non-zero', n_nz)


import matplotlib.pyplot as plt

def plot_events_with_segment_scores(segment_results, ground_truth_events, detected_events, use_datetime_x=False, show=True):
    """
    Test
    :param segment_results:
    :param ground_truth_events:
    :param detected_events:
    :param use_datetime_x:
    :param show:
    :return:
    """
    fig = plt.figure(figsize=(10, 3))
    a = 3

    # TODO: convert times to datetime if flag is set

    # write y axis labels for ground truth and detections
    plt.yticks([0.2, 0.5, 0.8], ["detections", "segment score", "actual events"])
    plt.ylim([0, 1])

    for d in detected_events:
        plt.axvspan(d[0], d[1], 0, 0.5)

    for gt in ground_truth_events:
        plt.axvspan(gt[0], gt[1], 0.5, 1)

    for s in segment_results:
        color = "black"
        index_of_cat = 4
        if s[index_of_cat] == "TP":
            color = "green"
        elif s[index_of_cat] == "FP":
            color = "red"
        elif s[index_of_cat] == "FN":
            color = "yellow"
        elif s[index_of_cat] == "TN":
            color = "blue"

        # TODO: format text nicely
        plt.text((s[1]+s[0])/2, 0.8, s[2], horizontalalignment='center', verticalalignment='center')
        plt.text((s[1]+s[0])/2, 0.2, s[3], horizontalalignment='center', verticalalignment='center')
        plt.text((s[1]+s[0])/2, 0.5, s[5], horizontalalignment='center', verticalalignment='center')
        plt.axvspan(s[0], s[1], 0.4, 0.6, color=color)
        plt.axvline(s[0], color="black")
        plt.axvline(s[1], color="black")

    plt.tight_layout()

    if show:
        plt.show()
    else:
        plt.draw()

def plot_events_with_event_scores(gt_event_scores, detected_event_scores, ground_truth_events, detected_events, show=True):
    fig = plt.figure(figsize=(10, 3))
    for i in range(len(detected_events)):
        d = detected_events[i]
        plt.axvspan(d[0], d[1], 0, 0.5)
        plt.text((d[1] + d[0]) / 2, 0.2, detected_event_scores[i], horizontalalignment='center', verticalalignment='center')

    for i in range(len(ground_truth_events)):
        gt = ground_truth_events[i]
        plt.axvspan(gt[0], gt[1], 0.5, 1)
        plt.text((gt[1] + gt[0]) / 2, 0.8, gt_event_scores[i], horizontalalignment='center', verticalalignment='center')

    plt.tight_layout()

    if show:
        plt.show()
    else:
        plt.draw()

def plot_twoset_metrics(results, startangle=120):
    fig1, axarr = plt.subplots(1, 2)

    # plot positive rates:
    labels_1 = ["tpr", "us", "ue", "fr", "dr"]
    values_1 = [
        results["tpr"],
        results["us"],
        results["ue"],
        results["fr"],
        results["dr"]
    ]

    axarr[0].pie(values_1, labels=labels_1, autopct='%1.0f%%', startangle=startangle)
    axarr[0].axis('equal')  # Equal aspect ratio ensures that pie is drawn as a circle.
    # TODO: add title

    # plot negative rates:
    labels_2 = ["1-fpr", "os", "oe", "mr", "ir"]
    values_2 = [
        1-results["fpr"],
        results["os"],
        results["oe"],
        results["mr"],
        results["ir"]
    ]

    axarr[1].pie(values_2, labels=labels_2, autopct='%1.0f%%', startangle=startangle)
    axarr[1].axis('equal')  # Equal aspect ratio ensures that pie is drawn as a circle.
    # TODO: add title

    plt.show()

def plot_segment_counts(results):
    # TODO: add title
    labels = results.keys()
    values = []
    for label in labels:
        values.append(results[label])

    #explode = (0, 0.1, 0, 0)  # only "explode" the 2nd slice (i.e. 'Hogs')

    total = sum(values)

    fig1, ax1 = plt.subplots()
    ax1.pie(values, labels=labels, autopct=lambda p: '{:.0f}'.format(p * total / 100), startangle=90)
    ax1.axis('equal')  # Equal aspect ratio ensures that pie is drawn as a circle.
    plt.show()

def plot_event_analysis_diagram(event_results, **kwargs):
    """ Plot the event analysis diagram (EAD) for the given results

    Visualisation of the distribution of specific error types either with the actual event count or
    showing the percentage of the total events. Elements of the plot can be adjusted (like color, fontsize etc.)

    Args:
        event_results (dictionary): Dictionary containing event counts for "total_gt", "total_det", "D", "F", "FM", "M",
                                    "C", "M'", "FM'", "F'", "I'" as returned by core_methods.event_metrics' third value

    Keyword Arguments:
        fontsize (int): Size of the text inside the bar plot (Reduce the value if some event types are too short)
        use_percentage (bool): whether percentage values or to show actual event counts on the chart (default: False)
        show (bool): whether to call plt.show (blocking) or plt.draw() for later displaying (default: True)
        color_deletion: any matplotlib color for deletion events
        color_fragmented: any matplotlib color for fragmented ground truth events
        color_fragmented_merged: any matplotlib color for merged and fragmented ground truth events
        color_merged: any matplotlib color for merged ground truth events
        color_correct: any matplotlib color for correct events
        color_merging: any matplotlib color for merging detection events
        color_merging_fragmenting: any matplotlib color for merging and fragmenting detection events
        color_fragmenting: any matplotlib color for merging detection events
        color_insertion: any matplotlib color for insertion events

    Returns:
        matplotlib Figure: matplotlib figure reference
    """
    fig = plt.figure(figsize=(10, 2))

    total = event_results["total_gt"] + event_results["total_det"] - event_results["C"]

    # Layout settings:
    y_min = 0.3
    y_max = 0.7
    width = 0.02
    text_x_offset = 0
    text_y_pos_1 = 0.55
    text_y_pos_2 = 0.4

    fontsize = kwargs.pop('fontsize', 10)
    fontsize_extern = 12
    use_percentage = kwargs.pop('use_percentage', False)

    # Color settings:
    cmap = plt.get_cmap("Paired")
    color_deletion = kwargs.pop('color_deletion', cmap(4))
    color_fragmented = kwargs.pop('color_fragmented', cmap(6))
    color_fragmented_merged = kwargs.pop('color_fragmented_merged', cmap(0))
    color_merged = kwargs.pop('color_merged', cmap(8))
    color_correct = kwargs.pop('color_correct', cmap(3))
    color_merging = kwargs.pop('color_merging', cmap(9))
    color_merging_fragmenting = kwargs.pop('color_merging_fragmenting', cmap(1))
    color_fragmenting = kwargs.pop('color_fragmenting', cmap(7))
    color_insertion = kwargs.pop('color_insertion', cmap(5))

    # Show deletions:
    current_score = "D"
    current_x_start = 0
    current_x_end = event_results[current_score]
    plt.axvspan(current_x_start, current_x_end, y_min, y_max, color=color_deletion)
    if event_results[current_score] > 0:
        plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_1, current_score, fontsize=fontsize,
                 horizontalalignment='center', verticalalignment='center')
        if use_percentage:
            plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_2, "{:.0f}".format(event_results[current_score]*100/event_results["total_gt"]) + "%",
                        fontsize=fontsize, horizontalalignment='center', verticalalignment='center')
        else:
            plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_2, str(event_results[current_score]),
                     fontsize=fontsize, horizontalalignment='center', verticalalignment='center')

    # Show fragmented events:
    current_score = "F"
    current_x_start = current_x_end
    current_x_end += event_results[current_score]
    plt.axvspan(current_x_start, current_x_end,  y_min, y_max, color=color_fragmented)
    if event_results[current_score] > 0:
        plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_1, current_score, fontsize=fontsize,
                 horizontalalignment='center', verticalalignment='center')
        if use_percentage:
            plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_2,
                     "{:.0f}".format(event_results[current_score] * 100 / event_results["total_gt"]) + "%",
                     fontsize=fontsize, horizontalalignment='center', verticalalignment='center')
        else:
            plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_2, str(event_results[current_score]),
                     fontsize=fontsize, horizontalalignment='center', verticalalignment='center')

    # Show fragmented and merged events:
    current_score = "FM"
    current_x_start = current_x_end
    current_x_end += event_results[current_score]
    plt.axvspan(current_x_start, current_x_end,  y_min, y_max, color=color_fragmented_merged)
    if event_results[current_score] > 0:
        plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_1, current_score, fontsize=fontsize,
                 horizontalalignment='center', verticalalignment='center')
        if use_percentage:
            plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_2,
                     "{:.0f}".format(event_results[current_score] * 100 / event_results["total_gt"]) + "%",
                     fontsize=fontsize, horizontalalignment='center', verticalalignment='center')
        else:
            plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_2, str(event_results[current_score]),
                     fontsize=fontsize, horizontalalignment='center', verticalalignment='center')

    # Show merged events:
    current_score = "M"
    current_x_start = current_x_end
    current_x_end += event_results[current_score]
    plt.axvspan(current_x_start, current_x_end,  y_min, y_max, color=color_merged)
    if event_results[current_score] > 0:
        plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_1, current_score, fontsize=fontsize,
                 horizontalalignment='center', verticalalignment='center')
        if use_percentage:
            plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_2,
                     "{:.0f}".format(event_results[current_score] * 100 / event_results["total_gt"]) + "%",
                     fontsize=fontsize, horizontalalignment='center', verticalalignment='center')
        else:
            plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_2, str(event_results[current_score]),
                     fontsize=fontsize, horizontalalignment='center', verticalalignment='center')

    # Show correct events:
    current_score = "C"
    current_x_start = current_x_end
    current_x_end += event_results[current_score]
    plt.axvspan(current_x_start, current_x_end,  y_min, y_max, color=color_correct)
    if event_results[current_score] > 0:
        plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_1, current_score, fontsize=fontsize,
                 horizontalalignment='center', verticalalignment='center')
        if use_percentage:
            plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_2,
                     "{:.0f}".format(event_results[current_score] * 100 / event_results["total_gt"]) + "%/" + "{:.0f}".format(event_results[current_score] * 100 / event_results["total_det"]) + "%",
                     fontsize=fontsize, horizontalalignment='center', verticalalignment='center')
        else:
            plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_2, str(event_results[current_score]),
                     fontsize=fontsize, horizontalalignment='center', verticalalignment='center')

    # Show merging detections:
    current_score = "M'"
    current_x_start = current_x_end
    current_x_end += event_results[current_score]
    plt.axvspan(current_x_start, current_x_end,  y_min, y_max, color=color_merging)
    if event_results[current_score] > 0:
        plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_1, current_score, fontsize=fontsize,
                 horizontalalignment='center', verticalalignment='center')
        if use_percentage:
            plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_2,
                     "{:.0f}".format(event_results[current_score] * 100 / event_results["total_det"]) + "%",
                     fontsize=fontsize, horizontalalignment='center', verticalalignment='center')
        else:
            plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_2, str(event_results[current_score]),
                     fontsize=fontsize, horizontalalignment='center', verticalalignment='center')

    # Show fragmenting and merging detections:
    current_score = "FM'"
    current_x_start = current_x_end
    current_x_end += event_results[current_score]
    plt.axvspan(current_x_start, current_x_end, y_min, y_max, color=color_merging_fragmenting)
    if event_results[current_score] > 0:
        plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_1, current_score, fontsize=fontsize,
                 horizontalalignment='center', verticalalignment='center')
        if use_percentage:
            plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_2,
                     "{:.0f}".format(event_results[current_score] * 100 / event_results["total_det"]) + "%",
                     fontsize=fontsize, horizontalalignment='center', verticalalignment='center')
        else:
            plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_2, str(event_results[current_score]),
                     fontsize=fontsize, horizontalalignment='center', verticalalignment='center')

    # Show fragmenting detections:
    current_score = "F'"
    current_x_start = current_x_end
    current_x_end += event_results[current_score]
    plt.axvspan(current_x_start, current_x_end, y_min, y_max, color=color_fragmenting)
    if event_results[current_score] > 0:
        plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_1, current_score, fontsize=fontsize,
                 horizontalalignment='center', verticalalignment='center')
        if use_percentage:
            plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_2,
                     "{:.0f}".format(event_results[current_score] * 100 / event_results["total_det"]) + "%",
                     fontsize=fontsize, horizontalalignment='center', verticalalignment='center')
        else:
            plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_2, str(event_results[current_score]),
                     fontsize=fontsize, horizontalalignment='center', verticalalignment='center')

    # Show insertions:
    current_score = "I'"
    current_x_start = current_x_end
    current_x_end += event_results[current_score]
    plt.axvspan(current_x_start, current_x_end, y_min, y_max, color=color_insertion)
    if event_results[current_score] > 0:
        plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_1, current_score, fontsize=fontsize,
                 horizontalalignment='center', verticalalignment='center')
        if use_percentage:
            plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_2,
                     "{:.0f}".format(event_results[current_score] * 100 / event_results["total_det"]) + "%",
                     fontsize=fontsize, horizontalalignment='center', verticalalignment='center')
        else:
            plt.text((current_x_start + current_x_end) / 2 - text_x_offset, text_y_pos_2, str(event_results[current_score]),
                     fontsize=fontsize, horizontalalignment='center', verticalalignment='center')

    # Draw line for total events:
    plt.axvspan(0, event_results["total_gt"], y_max, y_max + width, color="black")
    plt.axvspan( total - event_results["total_det"], total, y_min, y_min - width, color="black")

    plt.text((0 + event_results["total_gt"]) / 2, 0.8, "Actual events (total=" + str(event_results["total_gt"]) + ")",
             fontsize=fontsize_extern, horizontalalignment='center', verticalalignment='center')
    plt.text((2*total - event_results["total_det"]) / 2, 0.18, "Detected events (total=" + str(event_results["total_det"]) + ")",
             horizontalalignment='center', fontsize=fontsize_extern, verticalalignment='center')

    plt.tight_layout()
    if kwargs.pop('show', True):
        plt.show()
    else:
        plt.draw()
    return fig


# <nbformat>2</nbformat>

# <markdowncell>

# # Parallel Monto-Carlo options pricing

# <markdowncell>

# ## Problem setup

# <codecell>
from __future__ import print_function

import sys
import time
from IPython.parallel import Client
import numpy as np
from mckernel import price_options
from matplotlib import pyplot as plt

# <codecell>

cluster_profile = "default"
price = 100.0  # Initial price
rate = 0.05  # Interest rate
days = 260  # Days to expiration
paths = 10000  # Number of MC paths
n_strikes = 6  # Number of strike values
min_strike = 90.0  # Min strike price
max_strike = 110.0  # Max strike price
n_sigmas = 5  # Number of volatility values
min_sigma = 0.1  # Min volatility
max_sigma = 0.4  # Max volatility

# <codecell>

strike_vals = np.linspace(min_strike, max_strike, n_strikes)
sigma_vals = np.linspace(min_sigma, max_sigma, n_sigmas)

# <markdowncell>

# ## Parallel computation across strike prices and volatilities

# <markdowncell>

# The Client is used to setup the calculation and works with all engines.

# <codecell>

c = Client(profile=cluster_profile)

# <markdowncell>

# A LoadBalancedView is an interface to the engines that provides dynamic load
# balancing at the expense of not knowing which engine will execute the code.

# <codecell>

view = c.load_balanced_view()

# <codecell>

print("Strike prices: ", strike_vals)
print("Volatilities: ", sigma_vals)

# <markdowncell>

# Submit tasks for each (strike, sigma) pair.

# <codecell>

t1 = time.time()
async_results = []
for strike in strike_vals:
    for sigma in sigma_vals:
        ar = view.apply_async(price_options, price, strike, sigma, rate, days, paths)
        async_results.append(ar)

# <codecell>

print("Submitted tasks: ", len(async_results))

# <markdowncell>

# Block until all tasks are completed.

# <codecell>

c.wait(async_results)
t2 = time.time()
t = t2-t1

print("Parallel calculation completed, time = %s s" % t)

# <markdowncell>

# ## Process and visualize results

# <markdowncell>

# Get the results using the `get` method:

# <codecell>

results = [ar.get() for ar in async_results]

# <markdowncell>

# Assemble the result into a structured NumPy array.

# <codecell>

prices = np.empty(n_strikes*n_sigmas,
    dtype=[('ecall',float),('eput',float),('acall',float),('aput',float)]
)

for i, price in enumerate(results):
    prices[i] = tuple(price)

prices.shape = (n_strikes, n_sigmas)

# <markdowncell>

# Plot the value of the European call in (volatility, strike) space.

# <codecell>

plt.figure()
plt.contourf(sigma_vals, strike_vals, prices['ecall'])
plt.axis('tight')
plt.colorbar()
plt.title('European Call')
plt.xlabel("Volatility")
plt.ylabel("Strike Price")

# <markdowncell>

# Plot the value of the Asian call in (volatility, strike) space.

# <codecell>

plt.figure()
plt.contourf(sigma_vals, strike_vals, prices['acall'])
plt.axis('tight')
plt.colorbar()
plt.title("Asian Call")
plt.xlabel("Volatility")
plt.ylabel("Strike Price")

# <markdowncell>

# Plot the value of the European put in (volatility, strike) space.

# <codecell>

plt.figure()
plt.contourf(sigma_vals, strike_vals, prices['eput'])
plt.axis('tight')
plt.colorbar()
plt.title("European Put")
plt.xlabel("Volatility")
plt.ylabel("Strike Price")

# <markdowncell>

# Plot the value of the Asian put in (volatility, strike) space.

# <codecell>

plt.figure()
plt.contourf(sigma_vals, strike_vals, prices['aput'])
plt.axis('tight')
plt.colorbar()
plt.title("Asian Put")
plt.xlabel("Volatility")
plt.ylabel("Strike Price")

# <codecell>

plt.show()


#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
=========================================================
Logit function
=========================================================

Show in the plot is how the logistic regression would, in this
synthetic dataset, classify values as either 0 or 1,
i.e. class one or two, using the logit-curve.

"""
print(__doc__)

# Code source: Gael Varoquaux
# License: BSD 3 clause

import numpy as np
import matplotlib.pyplot as plt

from sklearn import linear_model

# this is our test set, it's just a straight line with some
# Gaussian noise
xmin, xmax = -5, 5
n_samples = 100
np.random.seed(0)
X = np.random.normal(size=n_samples)
y = (X > 0).astype(np.float)
X[X > 0] *= 4
X += .3 * np.random.normal(size=n_samples)

X = X[:, np.newaxis]
# run the classifier
clf = linear_model.LogisticRegression(C=1e5)
clf.fit(X, y)

# and plot the result
plt.figure(1, figsize=(4, 3))
plt.clf()
plt.scatter(X.ravel(), y, color='black', zorder=20)
X_test = np.linspace(-5, 10, 300)

def model(x):
    return 1 / (1 + np.exp(-x))
loss = model(X_test * clf.coef_ + clf.intercept_).ravel()
plt.plot(X_test, loss, color='blue', linewidth=3)

ols = linear_model.LinearRegression()
ols.fit(X, y)
plt.plot(X_test, ols.coef_ * X_test + ols.intercept_, linewidth=1)
plt.axhline(.5, color='.5')

plt.ylabel('y')
plt.xlabel('X')
plt.xticks(())
plt.yticks(())
plt.ylim(-.25, 1.25)
plt.xlim(-4, 10)

plt.show()


from __future__ import print_function
import numpy as np
import matplotlib
from matplotlib.testing.decorators import image_comparison, knownfailureif, cleanup
import matplotlib.pyplot as plt
import warnings
from nose.tools import with_setup

@image_comparison(baseline_images=['font_styles'])
def test_font_styles():
    from matplotlib import _get_data_path
    data_path = _get_data_path()

    def find_matplotlib_font(**kw):
        prop = FontProperties(**kw)
        path = findfont(prop, directory=data_path)
        return FontProperties(fname=path)

    from matplotlib.font_manager import FontProperties, findfont
    warnings.filterwarnings('ignore','findfont: Font family \[\'Foo\'\] '+ \
                            'not found. Falling back to .',
                            UserWarning,
                            module='matplotlib.font_manager')
    fig = plt.figure()
    ax = plt.subplot( 1, 1, 1 )

    normalFont = find_matplotlib_font( family = "sans-serif",
                                       style = "normal",
                                       variant = "normal",
                                       size = 14,
                                       )
    ax.annotate( "Normal Font", (0.1, 0.1), xycoords='axes fraction',
                  fontproperties = normalFont )

    boldFont = find_matplotlib_font( family = "Foo",
                                     style = "normal",
                                     variant = "normal",
                                     weight = "bold",
                                     stretch = 500,
                                     size = 14,
                                     )
    ax.annotate( "Bold Font", (0.1, 0.2), xycoords='axes fraction',
                  fontproperties = boldFont )

    boldItemFont = find_matplotlib_font( family = "sans serif",
                                         style = "italic",
                                         variant = "normal",
                                         weight = 750,
                                         stretch = 500,
                                         size = 14,
                                         )
    ax.annotate( "Bold Italic Font", (0.1, 0.3), xycoords='axes fraction',
                  fontproperties = boldItemFont )

    lightFont = find_matplotlib_font( family = "sans-serif",
                                      style = "normal",
                                      variant = "normal",
                                      weight = 200,
                                      stretch = 500,
                                      size = 14,
                                      )
    ax.annotate( "Light Font", (0.1, 0.4), xycoords='axes fraction',
                  fontproperties = lightFont )

    condensedFont = find_matplotlib_font( family = "sans-serif",
                                          style = "normal",
                                          variant = "normal",
                                          weight = 500,
                                          stretch = 100,
                                          size = 14,
                                          )
    ax.annotate( "Condensed Font", (0.1, 0.5), xycoords='axes fraction',
                  fontproperties = condensedFont )

    ax.set_xticks([])
    ax.set_yticks([])

@image_comparison(baseline_images=['multiline'])
def test_multiline():
    fig = plt.figure()
    ax = plt.subplot(1, 1, 1)
    ax.set_title("multiline\ntext alignment")

    plt.text(0.2, 0.5, "TpTpTp\n$M$\nTpTpTp", size=20,
             ha="center", va="top")

    plt.text(0.5, 0.5, "TpTpTp\n$M^{M^{M^{M}}}$\nTpTpTp", size=20,
             ha="center", va="top")

    plt.text(0.8, 0.5, "TpTpTp\n$M_{q_{q_{q}}}$\nTpTpTp", size=20,
             ha="center", va="top")

    plt.xlim(0, 1)
    plt.ylim(0, 0.8)

    ax.set_xticks([])
    ax.set_yticks([])

@image_comparison(baseline_images=['antialiased'], extensions=['png'])
def test_antialiasing():
    matplotlib.rcParams['text.antialiased'] = True

    fig = plt.figure(figsize=(5.25, 0.75))
    fig.text(0.5, 0.75, "antialiased", horizontalalignment='center',
             verticalalignment='center')
    fig.text(0.5, 0.25, "$\sqrt{x}$", horizontalalignment='center',
             verticalalignment='center')
    # NOTE: We don't need to restore the rcParams here, because the
    # test cleanup will do it for us.  In fact, if we do it here, it
    # will turn antialiasing back off before the images are actually
    # rendered.

def test_afm_kerning():
    from matplotlib.afm import AFM
    from matplotlib.font_manager import findfont

    fn = findfont("Helvetica", fontext="afm")
    with open(fn, 'rb') as fh:
        afm = AFM(fh)
    assert afm.string_width_height('VAVAVAVAVAVA') == (7174.0, 718)

@image_comparison(baseline_images=['text_contains'], extensions=['png'])
def test_contains():
    import matplotlib.backend_bases as mbackend

    fig = plt.figure()
    ax = plt.axes()

    mevent = mbackend.MouseEvent('button_press_event', fig.canvas, 0.5,
                                 0.5, 1, None)

    xs = np.linspace(0.25, 0.75, 30)
    ys = np.linspace(0.25, 0.75, 30)
    xs, ys = np.meshgrid(xs, ys)

    txt = plt.text(0.48, 0.52, 'hello world', ha='center', fontsize=30,
                   rotation=30)
    # uncomment to draw the text's bounding box
    # txt.set_bbox(dict(edgecolor='black', facecolor='none'))

    # draw the text. This is important, as the contains method can only work
    # when a renderer exists.
    plt.draw()

    for x, y in zip(xs.flat, ys.flat):
        mevent.x, mevent.y = plt.gca().transAxes.transform_point([x, y])

        contains, _ = txt.contains(mevent)

        color = 'yellow' if contains else 'red'

        # capture the viewLim, plot a point, and reset the viewLim
        vl = ax.viewLim.frozen()
        ax.plot(x, y, 'o', color=color)
        ax.viewLim.set(vl)

@image_comparison(baseline_images=['titles'])
def test_titles():
    # left and right side titles
    fig = plt.figure()
    ax = plt.subplot(1, 1, 1)
    ax.set_title("left title", loc="left")
    ax.set_title("right title", loc="right")
    ax.set_xticks([])
    ax.set_yticks([])

@image_comparison(baseline_images=['text_alignment'])
def test_alignment():
    fig = plt.figure()
    ax = plt.subplot(1, 1, 1)

    x = 0.1
    for rotation in (0, 30):
        for alignment in ('top', 'bottom', 'baseline', 'center'):
            ax.text(x, 0.5, alignment + " Tj", va=alignment, rotation=rotation,
                    bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5))
            ax.text(x, 1.0, r'$\sum_{i=0}^{j}$', va=alignment, rotation=rotation)
            x += 0.1

    ax.plot([0, 1], [0.5, 0.5])
    ax.plot([0, 1], [1.0, 1.0])

    ax.set_xlim([0, 1])
    ax.set_ylim([0, 1.5])
    ax.set_xticks([])
    ax.set_yticks([])


"""
This script has been used to compute the Dirichlet results of the paper

    Efficient spectral-Galerkin methods for second-order equations using different Chebyshev bases

The results have been computed using Python 3.9 and Shenfun 3.1.1.

The generalized Chebyshev-Tau results are computed with dedalus,
and are as such not part of this script.

"""
import sympy as sp
import numpy as np
import scipy.sparse.linalg as lin
import array_to_latex as a2l
from time import time

x = sp.Symbol('x', real=True)

fe = {}
rnd = {}
func = {}

def matvec(u_hat, f_hat, A, B, alpha, method):
    """Compute matrix vector product

    Parameters
    ----------
    u_hat : Function
        The solution array
    f_hat : Function
        The right hand side array
    A : SparseMatrix
        The stiffness matrix
    B : SparseMatrix
        The mass matrix
    alpha : number
        The weight of the mass matrix
    method : int
        The chosen method

    """
    from shenfun import chebyshev, la
    if method == 1:
        if alpha == 0:
            A.scale *= -1
            f_hat = A.matvec(u_hat, f_hat)
            A.scale *= -1
        else:
            sol = chebyshev.la.Helmholtz(A, B, -1, alpha)
            f_hat = sol.matvec(u_hat, f_hat)
    else:
        if alpha == 0:
            A.scale *= -1
            f_hat = A.matvec(u_hat, f_hat)
            A.scale *= -1
        else:
            M = alpha*B - A
            f_hat = M.matvec(u_hat, f_hat)
    return f_hat

def get_solver(A, B, alpha, method):
    """Return optimal solver for given method

    Parameters
    ----------
    A : SparseMatrix
        The stiffness matrix
    B : SparseMatrix
        The mass matrix
    alpha : number
        The weight of the mass matrix
    method : int
        The chosen method
    """
    from shenfun import chebyshev, la
    if method == 2:
        if alpha == 0:
            sol = la.TDMA(A*(-1))
        else:
            sol = la.PDMA(alpha*B - A)
    elif method == 1:
        if alpha == 0:
            A.scale = -1
            sol = chebyshev.la.ADD_Solve(A)
        else:
            sol = chebyshev.la.Helmholtz(A, B, -1, alpha)
    elif method in (0, 3, 4):
        if alpha == 0:
            sol = chebyshev.la.TwoDMA(A*(-1))
        else:
            sol = chebyshev.la.FDMA(alpha*B-A)
    elif method == 5:
        if alpha == 0:
            AA = A*(-1)
            sol = AA.solve
        else:
            sol = la.TDMA(alpha*B-A)

    else:
        raise NotImplementedError
    return sol

def solve(f_hat, u_hat, A, B, alpha, method):
    """Solve (alpha*B-A)u_hat = f_hat

    Parameters
    ----------
    f_hat : Function
        The right hand side array
    u_hat : Function
        The solution array
    A : SparseMatrix
        The stiffness matrix
    B : SparseMatrix
        The mass matrix
    alpha : number
        The weight of the mass matrix
    method : int
        The chosen method

    """
    from shenfun import extract_bc_matrices, Function
    if isinstance(B, list):
        u_hat.set_boundary_dofs()
        bc_mat = extract_bc_matrices([B])
        B = B[0]
        w0 = Function(u_hat.function_space())
        f_hat -= alpha*bc_mat[0].matvec(u_hat, w0)

    sol = get_solver(A, B, alpha, method)
    if method == 1 and alpha != 0:
        u_hat = sol(u_hat, f_hat)
    else:
        u_hat = sol(f_hat, u_hat)
    return u_hat

def main(N, method=0, alpha=0, returntype=0):
    from shenfun import FunctionSpace, TrialFunction, TestFunction, \
        inner, div, grad, chebyshev, SparseMatrix, Function, Array
    global fe
    basis = {0: ('ShenDirichlet', 'Heinrichs'),
             1: ('ShenDirichlet', 'ShenDirichlet'),
             2: ('Heinrichs', 'Heinrichs'),
             3: ('DirichletU', 'ShenDirichlet'),
             4: ('Orthogonal', 'ShenDirichlet'),    # Quasi-Galerkin
             5: ('ShenDirichlet', 'ShenDirichlet'), # Legendre
             }

    test, trial = basis[method]
    if returntype == 2:
        ue = sp.sin(100*sp.pi*x)

    family = 'C' if method < 5 else 'L'
    kw = {}
    scaled = True if method in (0, 5) else False
    if scaled:
        kw['scaled'] = True
    ST = FunctionSpace(N, family, basis=test, **kw)
    TS = FunctionSpace(N, family, basis=trial, **kw)
    wt = {0: 1, 1: 1, 2: 1, 3: 1-x**2, 4: 1, 5: 1}[method]
    u = TrialFunction(TS)
    v = TestFunction(ST)
    A = inner(v*wt, div(grad(u)))
    B = inner(v*wt, u)

    if method == 4:
        # Quasi
        Q2 = chebyshev.quasi.QIGmat(N)
        A = Q2*A
        B = Q2*B
    if method == 3:
        k = np.arange(N-2)
        K = SparseMatrix({0: 1/((k+1)*(k+2)*2)}, (N-2, N-2))
        A[0] *= K[0]
        A[2] *= K[0][:-2]
        B[-2] *= K[0][2:]
        B[0] *= K[0]
        B[2] *= K[0][:-2]
        B[4] *= K[0][:-4]

    if returntype == 0:
        M = alpha*B.diags()-A.diags()
        con = np.linalg.cond(M.toarray())

    elif returntype == 1:
        # Use rnd to get the same random numbers for all methods
        buf = rnd.get(N, np.random.random(N))
        if not N in rnd:
            rnd[N] = buf
        v = Function(TS, buffer=buf)
        v[-2:] = 0
        u_hat = Function(TS)
        f_hat = Function(TS)
        f_hat = matvec(v, f_hat, A, B, alpha, method)
        u_hat = solve(f_hat, u_hat, A, B, alpha, method)
        con = np.abs(u_hat-v).max()

    elif returntype == 2:
        fe = alpha*ue - ue.diff(x, 2)
        f_hat = Function(ST)
        fj = Array(ST, buffer=fe)
        if wt != 1:
            fj *= np.sin((np.arange(N)+0.5)*np.pi/N)**2
        f_hat = ST.scalar_product(fj, f_hat, fast_transform=True)

        if method == 4:
            f_hat[:-2] = Q2.diags('csc')*f_hat

        if method == 3:
            f_hat[:-2] *= K[0]

        sol = get_solver(A, B, alpha, method)
        u_hat = Function(TS)
        u_hat = solve(f_hat, u_hat, A, B, alpha, method)
        uj = Array(TS)
        uj = TS.backward(u_hat, uj, fast_transform=True)
        ua = Array(TS, buffer=ue)
        con = np.sqrt(inner(1, (uj-ua)**2))

    return con

if __name__ == '__main__':
    import matplotlib.pyplot as plt
    import argparse
    import os
    import sys

    parser = argparse.ArgumentParser(description='Solve the Helmholtz problem with Dirichlet boundary conditions')
    parser.add_argument('--return_type', action='store', type=int, required=True)
    parser.add_argument('--include_legendre', action='store_true')
    parser.add_argument('--verbose', '-v', action='count', default=0)
    parser.add_argument('--plot', action='store_true')
    parser.add_argument('--numba', action='store_true')
    args = parser.parse_args()

    if args.numba:
        try:
            import numba
            os.environ['SHENFUN_OPTIMIZATION'] = 'NUMBA'
        except ModuleNotFoundError:
            os.warning('Numba not found - using Cython')

    cond = []
    if args.return_type == 2:
        N = (2**4,2**6, 2**8, 2**12, 2**16, 2**20)
    elif args.return_type == 1:
        N = (2**4, 2**12, 2**20)
    else:
        N = (32, 64, 128, 256, 512, 1024, 2048)
    M = 6 if args.include_legendre else 5
    alphas = (0, 1000)

    if args.return_type in (0, 2):
        for alpha in alphas:
            cond.append([])
            if args.verbose > 0:
                print('alpha =', alpha)
            for basis in range(M): # To include Legendre use --include_legendre (takes hours for N=2**20)
                if args.verbose > 1:
                    print('Method =', basis)
                cond[-1].append([])
                for n in N:
                    if args.verbose > 2:
                        print('N =', n)
                    cond[-1][-1].append(main(n, basis, alpha, args.return_type))
        linestyle = {0: 'solid', 1: 'dashed', 2: 'dotted'}
        for i in range(len(cond)):
            plt.loglog(N, cond[i][0], 'b',
                       N, cond[i][1], 'r',
                       N, cond[i][2], 'k',
                       N, cond[i][3], 'm',
                       N, cond[i][4], 'y',
                       linestyle=linestyle[i])
            if args.include_legendre:
                plt.loglog(N, cond[i][5], 'y', linestyle=linestyle[i])
            a2l.to_ltx(np.array(cond)[i], frmt='{:6.2e}', print_out=True, mathform=False)
    else:
        for basis in range(M):
            cond.append([])
            if args.verbose > 1:
                print('Method =', basis)

            for alpha in alphas:
                if args.verbose > 0:
                    print('alpha =', alpha)
                for n in N:
                    if args.verbose > 2:
                        print('N =', n)
                    cond[-1].append(main(n, basis, alpha, args.return_type))

        a2l.to_ltx(np.array(cond), frmt='{:6.2e}', print_out=True, mathform=False)

    if args.plot:
        plt.show()


import numpy as np
import scipy.sparse as sp

from sklearn.utils.testing import assert_array_almost_equal
from sklearn.utils.testing import assert_true
from sklearn.utils.testing import assert_raises

from sklearn.utils import check_random_state
from sklearn.datasets import load_iris
from sklearn.linear_model import Perceptron

iris = load_iris()
random_state = check_random_state(12)
indices = np.arange(iris.data.shape[0])
random_state.shuffle(indices)
X = iris.data[indices]
y = iris.target[indices]
X_csr = sp.csr_matrix(X)
X_csr.sort_indices()

class MyPerceptron(object):

    def __init__(self, n_iter=1):
        self.n_iter = n_iter

    def fit(self, X, y):
        n_samples, n_features = X.shape
        self.w = np.zeros(n_features, dtype=np.float64)
        self.b = 0.0

        for t in range(self.n_iter):
            for i in range(n_samples):
                if self.predict(X[i])[0] != y[i]:
                    self.w += y[i] * X[i]
                    self.b += y[i]

    def project(self, X):
        return np.dot(X, self.w) + self.b

    def predict(self, X):
        X = np.atleast_2d(X)
        return np.sign(self.project(X))

def test_perceptron_accuracy():
    for data in (X, X_csr):
        clf = Perceptron(n_iter=30, shuffle=False)
        clf.fit(data, y)
        score = clf.score(data, y)
        assert_true(score >= 0.7)

def test_perceptron_correctness():
    y_bin = y.copy()
    y_bin[y != 1] = -1

    clf1 = MyPerceptron(n_iter=2)
    clf1.fit(X, y_bin)

    clf2 = Perceptron(n_iter=2, shuffle=False)
    clf2.fit(X, y_bin)

    assert_array_almost_equal(clf1.w, clf2.coef_.ravel())

def test_undefined_methods():
    clf = Perceptron()
    for meth in ("predict_proba", "predict_log_proba"):
        assert_raises(AttributeError, lambda x: getattr(clf, x), meth)


"""Test the search module"""

from collections import Iterable, Sized
from sklearn.externals.six.moves import cStringIO as StringIO
from sklearn.externals.six.moves import xrange
from itertools import chain, product
import pickle
import sys

import numpy as np
import scipy.sparse as sp

from sklearn.utils.fixes import sp_version
from sklearn.utils.testing import assert_equal
from sklearn.utils.testing import assert_not_equal
from sklearn.utils.testing import assert_raises
from sklearn.utils.testing import assert_warns
from sklearn.utils.testing import assert_raise_message
from sklearn.utils.testing import assert_false, assert_true
from sklearn.utils.testing import assert_array_equal
from sklearn.utils.testing import assert_almost_equal
from sklearn.utils.testing import assert_array_almost_equal
from sklearn.utils.testing import assert_no_warnings
from sklearn.utils.testing import ignore_warnings
from sklearn.utils.mocking import CheckingClassifier, MockDataFrame

from scipy.stats import bernoulli, expon, uniform

from sklearn.externals.six.moves import zip
from sklearn.base import BaseEstimator
from sklearn.datasets import make_classification
from sklearn.datasets import make_blobs
from sklearn.datasets import make_multilabel_classification

from sklearn.model_selection import KFold
from sklearn.model_selection import StratifiedKFold
from sklearn.model_selection import StratifiedShuffleSplit
from sklearn.model_selection import LeaveOneLabelOut
from sklearn.model_selection import LeavePLabelOut
from sklearn.model_selection import LabelKFold
from sklearn.model_selection import LabelShuffleSplit
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import RandomizedSearchCV
from sklearn.model_selection import ParameterGrid
from sklearn.model_selection import ParameterSampler

# TODO Import from sklearn.exceptions once merged.
from sklearn.base import ChangedBehaviorWarning
from sklearn.model_selection._validation import FitFailedWarning

from sklearn.svm import LinearSVC, SVC
from sklearn.tree import DecisionTreeRegressor
from sklearn.tree import DecisionTreeClassifier
from sklearn.cluster import KMeans
from sklearn.neighbors import KernelDensity
from sklearn.metrics import f1_score
from sklearn.metrics import make_scorer
from sklearn.metrics import roc_auc_score
from sklearn.preprocessing import Imputer
from sklearn.pipeline import Pipeline

# Neither of the following two estimators inherit from BaseEstimator,
# to test hyperparameter search on user-defined classifiers.
class MockClassifier(object):
    """Dummy classifier to test the parameter search algorithms"""
    def __init__(self, foo_param=0):
        self.foo_param = foo_param

    def fit(self, X, Y):
        assert_true(len(X) == len(Y))
        return self

    def predict(self, T):
        return T.shape[0]

    predict_proba = predict
    decision_function = predict
    transform = predict

    def score(self, X=None, Y=None):
        if self.foo_param > 1:
            score = 1.
        else:
            score = 0.
        return score

    def get_params(self, deep=False):
        return {'foo_param': self.foo_param}

    def set_params(self, **params):
        self.foo_param = params['foo_param']
        return self

class LinearSVCNoScore(LinearSVC):
    """An LinearSVC classifier that has no score method."""
    @property
    def score(self):
        raise AttributeError

X = np.array([[-1, -1], [-2, -1], [1, 1], [2, 1]])
y = np.array([1, 1, 2, 2])

def assert_grid_iter_equals_getitem(grid):
    assert_equal(list(grid), [grid[i] for i in range(len(grid))])

def test_parameter_grid():
    # Test basic properties of ParameterGrid.
    params1 = {"foo": [1, 2, 3]}
    grid1 = ParameterGrid(params1)
    assert_true(isinstance(grid1, Iterable))
    assert_true(isinstance(grid1, Sized))
    assert_equal(len(grid1), 3)
    assert_grid_iter_equals_getitem(grid1)

    params2 = {"foo": [4, 2],
               "bar": ["ham", "spam", "eggs"]}
    grid2 = ParameterGrid(params2)
    assert_equal(len(grid2), 6)

    # loop to assert we can iterate over the grid multiple times
    for i in xrange(2):
        # tuple + chain transforms {"a": 1, "b": 2} to ("a", 1, "b", 2)
        points = set(tuple(chain(*(sorted(p.items())))) for p in grid2)
        assert_equal(points,
                     set(("bar", x, "foo", y)
                         for x, y in product(params2["bar"], params2["foo"])))
    assert_grid_iter_equals_getitem(grid2)

    # Special case: empty grid (useful to get default estimator settings)
    empty = ParameterGrid({})
    assert_equal(len(empty), 1)
    assert_equal(list(empty), [{}])
    assert_grid_iter_equals_getitem(empty)
    assert_raises(IndexError, lambda: empty[1])

    has_empty = ParameterGrid([{'C': [1, 10]}, {}, {'C': [.5]}])
    assert_equal(len(has_empty), 4)
    assert_equal(list(has_empty), [{'C': 1}, {'C': 10}, {}, {'C': .5}])
    assert_grid_iter_equals_getitem(has_empty)

def test_grid_search():
    # Test that the best estimator contains the right value for foo_param
    clf = MockClassifier()
    grid_search = GridSearchCV(clf, {'foo_param': [1, 2, 3]}, verbose=3)
    # make sure it selects the smallest parameter in case of ties
    old_stdout = sys.stdout
    sys.stdout = StringIO()
    grid_search.fit(X, y)
    sys.stdout = old_stdout
    assert_equal(grid_search.best_estimator_.foo_param, 2)

    for i, foo_i in enumerate([1, 2, 3]):
        assert_true(grid_search.grid_scores_[i][0]
                    == {'foo_param': foo_i})
    # Smoke test the score etc:
    grid_search.score(X, y)
    grid_search.predict_proba(X)
    grid_search.decision_function(X)
    grid_search.transform(X)

    # Test exception handling on scoring
    grid_search.scoring = 'sklearn'
    assert_raises(ValueError, grid_search.fit, X, y)

@ignore_warnings
def test_grid_search_no_score():
    # Test grid-search on classifier that has no score function.
    clf = LinearSVC(random_state=0)
    X, y = make_blobs(random_state=0, centers=2)
    Cs = [.1, 1, 10]
    clf_no_score = LinearSVCNoScore(random_state=0)
    grid_search = GridSearchCV(clf, {'C': Cs}, scoring='accuracy')
    grid_search.fit(X, y)

    grid_search_no_score = GridSearchCV(clf_no_score, {'C': Cs},
                                        scoring='accuracy')
    # smoketest grid search
    grid_search_no_score.fit(X, y)

    # check that best params are equal
    assert_equal(grid_search_no_score.best_params_, grid_search.best_params_)
    # check that we can call score and that it gives the correct result
    assert_equal(grid_search.score(X, y), grid_search_no_score.score(X, y))

    # giving no scoring function raises an error
    grid_search_no_score = GridSearchCV(clf_no_score, {'C': Cs})
    assert_raise_message(TypeError, "no scoring", grid_search_no_score.fit,
                         [[1]])

def test_grid_search_score_method():
    X, y = make_classification(n_samples=100, n_classes=2, flip_y=.2,
                               random_state=0)
    clf = LinearSVC(random_state=0)
    grid = {'C': [.1]}

    search_no_scoring = GridSearchCV(clf, grid, scoring=None).fit(X, y)
    search_accuracy = GridSearchCV(clf, grid, scoring='accuracy').fit(X, y)
    search_no_score_method_auc = GridSearchCV(LinearSVCNoScore(), grid,
                                              scoring='roc_auc').fit(X, y)
    search_auc = GridSearchCV(clf, grid, scoring='roc_auc').fit(X, y)

    # Check warning only occurs in situation where behavior changed:
    # estimator requires score method to compete with scoring parameter
    score_no_scoring = assert_no_warnings(search_no_scoring.score, X, y)
    score_accuracy = assert_warns(ChangedBehaviorWarning,
                                  search_accuracy.score, X, y)
    score_no_score_auc = assert_no_warnings(search_no_score_method_auc.score,
                                            X, y)
    score_auc = assert_warns(ChangedBehaviorWarning,
                             search_auc.score, X, y)
    # ensure the test is sane
    assert_true(score_auc < 1.0)
    assert_true(score_accuracy < 1.0)
    assert_not_equal(score_auc, score_accuracy)

    assert_almost_equal(score_accuracy, score_no_scoring)
    assert_almost_equal(score_auc, score_no_score_auc)

def test_grid_search_labels():
    # Check if ValueError (when labels is None) propagates to GridSearchCV
    # And also check if labels is correctly passed to the cv object
    rng = np.random.RandomState(0)

    X, y = make_classification(n_samples=15, n_classes=2, random_state=0)
    labels = rng.randint(0, 3, 15)

    clf = LinearSVC(random_state=0)
    grid = {'C': [1]}

    label_cvs = [LeaveOneLabelOut(), LeavePLabelOut(2), LabelKFold(),
                 LabelShuffleSplit()]
    for cv in label_cvs:
        gs = GridSearchCV(clf, grid, cv=cv)
        assert_raise_message(ValueError,
                             "The labels parameter should not be None",
                             gs.fit, X, y)
        gs.fit(X, y, labels)

    non_label_cvs = [StratifiedKFold(), StratifiedShuffleSplit()]
    for cv in non_label_cvs:
        gs = GridSearchCV(clf, grid, cv=cv)
        # Should not raise an error
        gs.fit(X, y)

def test_trivial_grid_scores():
    # Test search over a "grid" with only one point.
    # Non-regression test: grid_scores_ wouldn't be set by GridSearchCV.
    clf = MockClassifier()
    grid_search = GridSearchCV(clf, {'foo_param': [1]})
    grid_search.fit(X, y)
    assert_true(hasattr(grid_search, "grid_scores_"))

    random_search = RandomizedSearchCV(clf, {'foo_param': [0]}, n_iter=1)
    random_search.fit(X, y)
    assert_true(hasattr(random_search, "grid_scores_"))

def test_no_refit():
    # Test that grid search can be used for model selection only
    clf = MockClassifier()
    grid_search = GridSearchCV(clf, {'foo_param': [1, 2, 3]}, refit=False)
    grid_search.fit(X, y)
    assert_true(hasattr(grid_search, "best_params_"))

def test_grid_search_error():
    # Test that grid search will capture errors on data with different
    # length
    X_, y_ = make_classification(n_samples=200, n_features=100, random_state=0)

    clf = LinearSVC()
    cv = GridSearchCV(clf, {'C': [0.1, 1.0]})
    assert_raises(ValueError, cv.fit, X_[:180], y_)

def test_grid_search_iid():
    # test the iid parameter
    # noise-free simple 2d-data
    X, y = make_blobs(centers=[[0, 0], [1, 0], [0, 1], [1, 1]], random_state=0,
                      cluster_std=0.1, shuffle=False, n_samples=80)
    # split dataset into two folds that are not iid
    # first one contains data of all 4 blobs, second only from two.
    mask = np.ones(X.shape[0], dtype=np.bool)
    mask[np.where(y == 1)[0][::2]] = 0
    mask[np.where(y == 2)[0][::2]] = 0
    # this leads to perfect classification on one fold and a score of 1/3 on
    # the other
    svm = SVC(kernel='linear')
    # create "cv" for splits
    cv = [[mask, ~mask], [~mask, mask]]
    # once with iid=True (default)
    grid_search = GridSearchCV(svm, param_grid={'C': [1, 10]}, cv=cv)
    grid_search.fit(X, y)
    first = grid_search.grid_scores_[0]
    assert_equal(first.parameters['C'], 1)
    assert_array_almost_equal(first.cv_validation_scores, [1, 1. / 3.])
    # for first split, 1/4 of dataset is in test, for second 3/4.
    # take weighted average
    assert_almost_equal(first.mean_validation_score,
                        1 * 1. / 4. + 1. / 3. * 3. / 4.)

    # once with iid=False
    grid_search = GridSearchCV(svm, param_grid={'C': [1, 10]}, cv=cv,
                               iid=False)
    grid_search.fit(X, y)
    first = grid_search.grid_scores_[0]
    assert_equal(first.parameters['C'], 1)
    # scores are the same as above
    assert_array_almost_equal(first.cv_validation_scores, [1, 1. / 3.])
    # averaged score is just mean of scores
    assert_almost_equal(first.mean_validation_score,
                        np.mean(first.cv_validation_scores))

def test_grid_search_one_grid_point():
    X_, y_ = make_classification(n_samples=200, n_features=100, random_state=0)
    param_dict = {"C": [1.0], "kernel": ["rbf"], "gamma": [0.1]}

    clf = SVC()
    cv = GridSearchCV(clf, param_dict)
    cv.fit(X_, y_)

    clf = SVC(C=1.0, kernel="rbf", gamma=0.1)
    clf.fit(X_, y_)

    assert_array_equal(clf.dual_coef_, cv.best_estimator_.dual_coef_)

def test_grid_search_bad_param_grid():
    param_dict = {"C": 1.0}
    clf = SVC()
    assert_raises(ValueError, GridSearchCV, clf, param_dict)

    param_dict = {"C": []}
    clf = SVC()
    assert_raises(ValueError, GridSearchCV, clf, param_dict)

    param_dict = {"C": np.ones(6).reshape(3, 2)}
    clf = SVC()
    assert_raises(ValueError, GridSearchCV, clf, param_dict)

def test_grid_search_sparse():
    # Test that grid search works with both dense and sparse matrices
    X_, y_ = make_classification(n_samples=200, n_features=100, random_state=0)

    clf = LinearSVC()
    cv = GridSearchCV(clf, {'C': [0.1, 1.0]})
    cv.fit(X_[:180], y_[:180])
    y_pred = cv.predict(X_[180:])
    C = cv.best_estimator_.C

    X_ = sp.csr_matrix(X_)
    clf = LinearSVC()
    cv = GridSearchCV(clf, {'C': [0.1, 1.0]})
    cv.fit(X_[:180].tocoo(), y_[:180])
    y_pred2 = cv.predict(X_[180:])
    C2 = cv.best_estimator_.C

    assert_true(np.mean(y_pred == y_pred2) >= .9)
    assert_equal(C, C2)

def test_grid_search_sparse_scoring():
    X_, y_ = make_classification(n_samples=200, n_features=100, random_state=0)

    clf = LinearSVC()
    cv = GridSearchCV(clf, {'C': [0.1, 1.0]}, scoring="f1")
    cv.fit(X_[:180], y_[:180])
    y_pred = cv.predict(X_[180:])
    C = cv.best_estimator_.C

    X_ = sp.csr_matrix(X_)
    clf = LinearSVC()
    cv = GridSearchCV(clf, {'C': [0.1, 1.0]}, scoring="f1")
    cv.fit(X_[:180], y_[:180])
    y_pred2 = cv.predict(X_[180:])
    C2 = cv.best_estimator_.C

    assert_array_equal(y_pred, y_pred2)
    assert_equal(C, C2)
    # Smoke test the score
    # np.testing.assert_allclose(f1_score(cv.predict(X_[:180]), y[:180]),
    #                            cv.score(X_[:180], y[:180]))

    # test loss where greater is worse
    def f1_loss(y_true_, y_pred_):
        return -f1_score(y_true_, y_pred_)
    F1Loss = make_scorer(f1_loss, greater_is_better=False)
    cv = GridSearchCV(clf, {'C': [0.1, 1.0]}, scoring=F1Loss)
    cv.fit(X_[:180], y_[:180])
    y_pred3 = cv.predict(X_[180:])
    C3 = cv.best_estimator_.C

    assert_equal(C, C3)
    assert_array_equal(y_pred, y_pred3)

def test_grid_search_precomputed_kernel():
    # Test that grid search works when the input features are given in the
    # form of a precomputed kernel matrix
    X_, y_ = make_classification(n_samples=200, n_features=100, random_state=0)

    # compute the training kernel matrix corresponding to the linear kernel
    K_train = np.dot(X_[:180], X_[:180].T)
    y_train = y_[:180]

    clf = SVC(kernel='precomputed')
    cv = GridSearchCV(clf, {'C': [0.1, 1.0]})
    cv.fit(K_train, y_train)

    assert_true(cv.best_score_ >= 0)

    # compute the test kernel matrix
    K_test = np.dot(X_[180:], X_[:180].T)
    y_test = y_[180:]

    y_pred = cv.predict(K_test)

    assert_true(np.mean(y_pred == y_test) >= 0)

    # test error is raised when the precomputed kernel is not array-like
    # or sparse
    assert_raises(ValueError, cv.fit, K_train.tolist(), y_train)

def test_grid_search_precomputed_kernel_error_nonsquare():
    # Test that grid search returns an error with a non-square precomputed
    # training kernel matrix
    K_train = np.zeros((10, 20))
    y_train = np.ones((10, ))
    clf = SVC(kernel='precomputed')
    cv = GridSearchCV(clf, {'C': [0.1, 1.0]})
    assert_raises(ValueError, cv.fit, K_train, y_train)

def test_grid_search_precomputed_kernel_error_kernel_function():
    # Test that grid search returns an error when using a kernel_function
    X_, y_ = make_classification(n_samples=200, n_features=100, random_state=0)
    kernel_function = lambda x1, x2: np.dot(x1, x2.T)
    clf = SVC(kernel=kernel_function)
    cv = GridSearchCV(clf, {'C': [0.1, 1.0]})
    assert_raises(ValueError, cv.fit, X_, y_)

class BrokenClassifier(BaseEstimator):
    """Broken classifier that cannot be fit twice"""

    def __init__(self, parameter=None):
        self.parameter = parameter

    def fit(self, X, y):
        assert_true(not hasattr(self, 'has_been_fit_'))
        self.has_been_fit_ = True

    def predict(self, X):
        return np.zeros(X.shape[0])

@ignore_warnings
def test_refit():
    # Regression test for bug in refitting
    # Simulates re-fitting a broken estimator; this used to break with
    # sparse SVMs.
    X = np.arange(100).reshape(10, 10)
    y = np.array([0] * 5 + [1] * 5)

    clf = GridSearchCV(BrokenClassifier(), [{'parameter': [0, 1]}],
                       scoring="precision", refit=True)
    clf.fit(X, y)

def test_gridsearch_nd():
    # Pass X as list in GridSearchCV
    X_4d = np.arange(10 * 5 * 3 * 2).reshape(10, 5, 3, 2)
    y_3d = np.arange(10 * 7 * 11).reshape(10, 7, 11)
    check_X = lambda x: x.shape[1:] == (5, 3, 2)
    check_y = lambda x: x.shape[1:] == (7, 11)
    clf = CheckingClassifier(check_X=check_X, check_y=check_y)
    grid_search = GridSearchCV(clf, {'foo_param': [1, 2, 3]})
    grid_search.fit(X_4d, y_3d).score(X, y)
    assert_true(hasattr(grid_search, "grid_scores_"))

def test_X_as_list():
    # Pass X as list in GridSearchCV
    X = np.arange(100).reshape(10, 10)
    y = np.array([0] * 5 + [1] * 5)

    clf = CheckingClassifier(check_X=lambda x: isinstance(x, list))
    cv = KFold(n_folds=3)
    grid_search = GridSearchCV(clf, {'foo_param': [1, 2, 3]}, cv=cv)
    grid_search.fit(X.tolist(), y).score(X, y)
    assert_true(hasattr(grid_search, "grid_scores_"))

def test_y_as_list():
    # Pass y as list in GridSearchCV
    X = np.arange(100).reshape(10, 10)
    y = np.array([0] * 5 + [1] * 5)

    clf = CheckingClassifier(check_y=lambda x: isinstance(x, list))
    cv = KFold(n_folds=3)
    grid_search = GridSearchCV(clf, {'foo_param': [1, 2, 3]}, cv=cv)
    grid_search.fit(X, y.tolist()).score(X, y)
    assert_true(hasattr(grid_search, "grid_scores_"))

@ignore_warnings
def test_pandas_input():
    # check cross_val_score doesn't destroy pandas dataframe
    types = [(MockDataFrame, MockDataFrame)]
    try:
        from pandas import Series, DataFrame
        types.append((DataFrame, Series))
    except ImportError:
        pass

    X = np.arange(100).reshape(10, 10)
    y = np.array([0] * 5 + [1] * 5)

    for InputFeatureType, TargetType in types:
        # X dataframe, y series
        X_df, y_ser = InputFeatureType(X), TargetType(y)
        check_df = lambda x: isinstance(x, InputFeatureType)
        check_series = lambda x: isinstance(x, TargetType)
        clf = CheckingClassifier(check_X=check_df, check_y=check_series)

        grid_search = GridSearchCV(clf, {'foo_param': [1, 2, 3]})
        grid_search.fit(X_df, y_ser).score(X_df, y_ser)
        grid_search.predict(X_df)
        assert_true(hasattr(grid_search, "grid_scores_"))

def test_unsupervised_grid_search():
    # test grid-search with unsupervised estimator
    X, y = make_blobs(random_state=0)
    km = KMeans(random_state=0)
    grid_search = GridSearchCV(km, param_grid=dict(n_clusters=[2, 3, 4]),
                               scoring='adjusted_rand_score')
    grid_search.fit(X, y)
    # ARI can find the right number :)
    assert_equal(grid_search.best_params_["n_clusters"], 3)

    # Now without a score, and without y
    grid_search = GridSearchCV(km, param_grid=dict(n_clusters=[2, 3, 4]))
    grid_search.fit(X)
    assert_equal(grid_search.best_params_["n_clusters"], 4)

def test_gridsearch_no_predict():
    # test grid-search with an estimator without predict.
    # slight duplication of a test from KDE
    def custom_scoring(estimator, X):
        return 42 if estimator.bandwidth == .1 else 0
    X, _ = make_blobs(cluster_std=.1, random_state=1,
                      centers=[[0, 1], [1, 0], [0, 0]])
    search = GridSearchCV(KernelDensity(),
                          param_grid=dict(bandwidth=[.01, .1, 1]),
                          scoring=custom_scoring)
    search.fit(X)
    assert_equal(search.best_params_['bandwidth'], .1)
    assert_equal(search.best_score_, 42)

def test_param_sampler():
    # test basic properties of param sampler
    param_distributions = {"kernel": ["rbf", "linear"],
                           "C": uniform(0, 1)}
    sampler = ParameterSampler(param_distributions=param_distributions,
                               n_iter=10, random_state=0)
    samples = [x for x in sampler]
    assert_equal(len(samples), 10)
    for sample in samples:
        assert_true(sample["kernel"] in ["rbf", "linear"])
        assert_true(0 <= sample["C"] <= 1)

    # test that repeated calls yield identical parameters
    param_distributions = {"C": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}
    sampler = ParameterSampler(param_distributions=param_distributions,
                               n_iter=3, random_state=0)
    assert_equal([x for x in sampler], [x for x in sampler])

    if sp_version >= (0, 16):
        param_distributions = {"C": uniform(0, 1)}
        sampler = ParameterSampler(param_distributions=param_distributions,
                                   n_iter=10, random_state=0)
        assert_equal([x for x in sampler], [x for x in sampler])

def test_randomized_search_grid_scores():
    # Make a dataset with a lot of noise to get various kind of prediction
    # errors across CV folds and parameter settings
    X, y = make_classification(n_samples=200, n_features=100, n_informative=3,
                               random_state=0)

    # XXX: as of today (scipy 0.12) it's not possible to set the random seed
    # of scipy.stats distributions: the assertions in this test should thus
    # not depend on the randomization
    params = dict(C=expon(scale=10),
                  gamma=expon(scale=0.1))
    n_cv_iter = 3
    n_search_iter = 30
    search = RandomizedSearchCV(SVC(), n_iter=n_search_iter, cv=n_cv_iter,
                                param_distributions=params, iid=False)
    search.fit(X, y)
    assert_equal(len(search.grid_scores_), n_search_iter)

    # Check consistency of the structure of each cv_score item
    for cv_score in search.grid_scores_:
        assert_equal(len(cv_score.cv_validation_scores), n_cv_iter)
        # Because we set iid to False, the mean_validation score is the
        # mean of the fold mean scores instead of the aggregate sample-wise
        # mean score
        assert_almost_equal(np.mean(cv_score.cv_validation_scores),
                            cv_score.mean_validation_score)
        assert_equal(list(sorted(cv_score.parameters.keys())),
                     list(sorted(params.keys())))

    # Check the consistency with the best_score_ and best_params_ attributes
    sorted_grid_scores = list(sorted(search.grid_scores_,
                              key=lambda x: x.mean_validation_score))
    best_score = sorted_grid_scores[-1].mean_validation_score
    assert_equal(search.best_score_, best_score)

    tied_best_params = [s.parameters for s in sorted_grid_scores
                        if s.mean_validation_score == best_score]
    assert_true(search.best_params_ in tied_best_params,
                "best_params_={0} is not part of the"
                " tied best models: {1}".format(
                    search.best_params_, tied_best_params))

def test_grid_search_score_consistency():
    # test that correct scores are used
    clf = LinearSVC(random_state=0)
    X, y = make_blobs(random_state=0, centers=2)
    Cs = [.1, 1, 10]
    for score in ['f1', 'roc_auc']:
        grid_search = GridSearchCV(clf, {'C': Cs}, scoring=score)
        grid_search.fit(X, y)
        cv = StratifiedKFold(n_folds=3)
        for C, scores in zip(Cs, grid_search.grid_scores_):
            clf.set_params(C=C)
            scores = scores[2]  # get the separate runs from grid scores
            i = 0
            for train, test in cv.split(X, y):
                clf.fit(X[train], y[train])
                if score == "f1":
                    correct_score = f1_score(y[test], clf.predict(X[test]))
                elif score == "roc_auc":
                    dec = clf.decision_function(X[test])
                    correct_score = roc_auc_score(y[test], dec)
                assert_almost_equal(correct_score, scores[i])
                i += 1

def test_pickle():
    # Test that a fit search can be pickled
    clf = MockClassifier()
    grid_search = GridSearchCV(clf, {'foo_param': [1, 2, 3]}, refit=True)
    grid_search.fit(X, y)
    pickle.dumps(grid_search)  # smoke test

    random_search = RandomizedSearchCV(clf, {'foo_param': [1, 2, 3]},
                                       refit=True, n_iter=3)
    random_search.fit(X, y)
    pickle.dumps(random_search)  # smoke test

def test_grid_search_with_multioutput_data():
    # Test search with multi-output estimator

    X, y = make_multilabel_classification(return_indicator=True,
                                          random_state=0)

    est_parameters = {"max_depth": [1, 2, 3, 4]}
    cv = KFold(random_state=0)

    estimators = [DecisionTreeRegressor(random_state=0),
                  DecisionTreeClassifier(random_state=0)]

    # Test with grid search cv
    for est in estimators:
        grid_search = GridSearchCV(est, est_parameters, cv=cv)
        grid_search.fit(X, y)
        for parameters, _, cv_validation_scores in grid_search.grid_scores_:
            est.set_params(**parameters)

            for i, (train, test) in enumerate(cv.split(X, y)):
                est.fit(X[train], y[train])
                correct_score = est.score(X[test], y[test])
                assert_almost_equal(correct_score,
                                    cv_validation_scores[i])

    # Test with a randomized search
    for est in estimators:
        random_search = RandomizedSearchCV(est, est_parameters,
                                           cv=cv, n_iter=3)
        random_search.fit(X, y)
        for parameters, _, cv_validation_scores in random_search.grid_scores_:
            est.set_params(**parameters)

            for i, (train, test) in enumerate(cv.split(X, y)):
                est.fit(X[train], y[train])
                correct_score = est.score(X[test], y[test])
                assert_almost_equal(correct_score,
                                    cv_validation_scores[i])

def test_predict_proba_disabled():
    # Test predict_proba when disabled on estimator.
    X = np.arange(20).reshape(5, -1)
    y = [0, 0, 1, 1, 1]
    clf = SVC(probability=False)
    gs = GridSearchCV(clf, {}, cv=2).fit(X, y)
    assert_false(hasattr(gs, "predict_proba"))

def test_grid_search_allows_nans():
    # Test GridSearchCV with Imputer
    X = np.arange(20, dtype=np.float64).reshape(5, -1)
    X[2, :] = np.nan
    y = [0, 0, 1, 1, 1]
    p = Pipeline([
        ('imputer', Imputer(strategy='mean', missing_values='NaN')),
        ('classifier', MockClassifier()),
    ])
    GridSearchCV(p, {'classifier__foo_param': [1, 2, 3]}, cv=2).fit(X, y)

class FailingClassifier(BaseEstimator):
    """Classifier that raises a ValueError on fit()"""

    FAILING_PARAMETER = 2

    def __init__(self, parameter=None):
        self.parameter = parameter

    def fit(self, X, y=None):
        if self.parameter == FailingClassifier.FAILING_PARAMETER:
            raise ValueError("Failing classifier failed as required")

    def predict(self, X):
        return np.zeros(X.shape[0])

def test_grid_search_failing_classifier():
    # GridSearchCV with on_error != 'raise'
    # Ensures that a warning is raised and score reset where appropriate.

    X, y = make_classification(n_samples=20, n_features=10, random_state=0)

    clf = FailingClassifier()

    # refit=False because we only want to check that errors caused by fits
    # to individual folds will be caught and warnings raised instead. If
    # refit was done, then an exception would be raised on refit and not
    # caught by grid_search (expected behavior), and this would cause an
    # error in this test.
    gs = GridSearchCV(clf, [{'parameter': [0, 1, 2]}], scoring='accuracy',
                      refit=False, error_score=0.0)

    assert_warns(FitFailedWarning, gs.fit, X, y)

    # Ensure that grid scores were set to zero as required for those fits
    # that are expected to fail.
    assert all(np.all(this_point.cv_validation_scores == 0.0)
               for this_point in gs.grid_scores_
               if this_point.parameters['parameter'] ==
               FailingClassifier.FAILING_PARAMETER)

    gs = GridSearchCV(clf, [{'parameter': [0, 1, 2]}], scoring='accuracy',
                      refit=False, error_score=float('nan'))
    assert_warns(FitFailedWarning, gs.fit, X, y)
    assert all(np.all(np.isnan(this_point.cv_validation_scores))
               for this_point in gs.grid_scores_
               if this_point.parameters['parameter'] ==
               FailingClassifier.FAILING_PARAMETER)

def test_grid_search_failing_classifier_raise():
    # GridSearchCV with on_error == 'raise' raises the error

    X, y = make_classification(n_samples=20, n_features=10, random_state=0)

    clf = FailingClassifier()

    # refit=False because we want to test the behaviour of the grid search part
    gs = GridSearchCV(clf, [{'parameter': [0, 1, 2]}], scoring='accuracy',
                      refit=False, error_score='raise')

    # FailingClassifier issues a ValueError so this is what we look for.
    assert_raises(ValueError, gs.fit, X, y)

def test_parameters_sampler_replacement():
    # raise error if n_iter too large
    params = {'first': [0, 1], 'second': ['a', 'b', 'c']}
    sampler = ParameterSampler(params, n_iter=7)
    assert_raises(ValueError, list, sampler)
    # degenerates to GridSearchCV if n_iter the same as grid_size
    sampler = ParameterSampler(params, n_iter=6)
    samples = list(sampler)
    assert_equal(len(samples), 6)
    for values in ParameterGrid(params):
        assert_true(values in samples)

    # test sampling without replacement in a large grid
    params = {'a': range(10), 'b': range(10), 'c': range(10)}
    sampler = ParameterSampler(params, n_iter=99, random_state=42)
    samples = list(sampler)
    assert_equal(len(samples), 99)
    hashable_samples = ["a%db%dc%d" % (p['a'], p['b'], p['c'])
                        for p in samples]
    assert_equal(len(set(hashable_samples)), 99)

    # doesn't go into infinite loops
    params_distribution = {'first': bernoulli(.5), 'second': ['a', 'b', 'c']}
    sampler = ParameterSampler(params_distribution, n_iter=7)
    samples = list(sampler)
    assert_equal(len(samples), 7)


#!/usr/bin/env python
#
# Copyright 2009,2012,2013 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING.  If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#

from gnuradio import gr
from gnuradio import blocks
from gnuradio import filter
import sys, time

try:
    from gnuradio import analog
except ImportError:
    sys.stderr.write("Error: Program requires gr-analog.\n")
    sys.exit(1)

try:
    import scipy
    from scipy import fftpack
except ImportError:
    sys.stderr.write("Error: Program requires scipy (see: www.scipy.org).\n")
    sys.exit(1)

try:
    import pylab
    from pylab import mlab
except ImportError:
    sys.stderr.write("Error: Program requires matplotlib (see: matplotlib.sourceforge.net).\n")
    sys.exit(1)

class pfb_top_block(gr.top_block):
    def __init__(self):
        gr.top_block.__init__(self)

        self._N = 2000000        # number of samples to use
        self._fs = 1000          # initial sampling rate
        self._M = M = 9          # Number of channels to channelize
        self._ifs = M*self._fs   # initial sampling rate

        # Create a set of taps for the PFB channelizer
        self._taps = filter.firdes.low_pass_2(1, self._ifs, 475.50, 50,
                                              attenuation_dB=100,
                                              window=filter.firdes.WIN_BLACKMAN_hARRIS)

        # Calculate the number of taps per channel for our own information
        tpc = scipy.ceil(float(len(self._taps)) /  float(self._M))
        print "Number of taps:     ", len(self._taps)
        print "Number of channels: ", self._M
        print "Taps per channel:   ", tpc

        # Create a set of signals at different frequencies
        #   freqs lists the frequencies of the signals that get stored
        #   in the list "signals", which then get summed together
        self.signals = list()
        self.add = blocks.add_cc()
        freqs = [-70, -50, -30, -10, 10, 20, 40, 60, 80]
        for i in xrange(len(freqs)):
            f = freqs[i] + (M/2-M+i+1)*self._fs
            self.signals.append(analog.sig_source_c(self._ifs, analog.GR_SIN_WAVE, f, 1))
            self.connect(self.signals[i], (self.add,i))

        self.head = blocks.head(gr.sizeof_gr_complex, self._N)

        # Construct the channelizer filter
        self.pfb = filter.pfb.channelizer_ccf(self._M, self._taps, 1)

        # Construct a vector sink for the input signal to the channelizer
        self.snk_i = blocks.vector_sink_c()

        # Connect the blocks
        self.connect(self.add, self.head, self.pfb)
        self.connect(self.add, self.snk_i)

        # Use this to play with the channel mapping
        #self.pfb.set_channel_map([5,6,7,8,0,1,2,3,4])

        # Create a vector sink for each of M output channels of the filter and connect it
        self.snks = list()
        for i in xrange(self._M):
            self.snks.append(blocks.vector_sink_c())
            self.connect((self.pfb, i), self.snks[i])

def main():
    tstart = time.time()

    tb = pfb_top_block()
    tb.run()

    tend = time.time()
    print "Run time: %f" % (tend - tstart)

    if 1:
        fig_in = pylab.figure(1, figsize=(16,9), facecolor="w")
        fig1 = pylab.figure(2, figsize=(16,9), facecolor="w")
        fig2 = pylab.figure(3, figsize=(16,9), facecolor="w")

        Ns = 1000
        Ne = 10000

        fftlen = 8192
        winfunc = scipy.blackman
        fs = tb._ifs

        # Plot the input signal on its own figure
        d = tb.snk_i.data()[Ns:Ne]
        spin_f = fig_in.add_subplot(2, 1, 1)

        X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
                          window = lambda d: d*winfunc(fftlen),
                          scale_by_freq=True)
        X_in = 10.0*scipy.log10(abs(X))
        f_in = scipy.arange(-fs/2.0, fs/2.0, fs/float(X_in.size))
        pin_f = spin_f.plot(f_in, X_in, "b")
        spin_f.set_xlim([min(f_in), max(f_in)+1])
        spin_f.set_ylim([-200.0, 50.0])

        spin_f.set_title("Input Signal", weight="bold")
        spin_f.set_xlabel("Frequency (Hz)")
        spin_f.set_ylabel("Power (dBW)")

        Ts = 1.0/fs
        Tmax = len(d)*Ts

        t_in = scipy.arange(0, Tmax, Ts)
        x_in = scipy.array(d)
        spin_t = fig_in.add_subplot(2, 1, 2)
        pin_t = spin_t.plot(t_in, x_in.real, "b")
        pin_t = spin_t.plot(t_in, x_in.imag, "r")

        spin_t.set_xlabel("Time (s)")
        spin_t.set_ylabel("Amplitude")

        Ncols = int(scipy.floor(scipy.sqrt(tb._M)))
        Nrows = int(scipy.floor(tb._M / Ncols))
        if(tb._M % Ncols != 0):
            Nrows += 1

        # Plot each of the channels outputs. Frequencies on Figure 2 and
        # time signals on Figure 3
        fs_o = tb._fs
        Ts_o = 1.0/fs_o
        Tmax_o = len(d)*Ts_o
        for i in xrange(len(tb.snks)):
            # remove issues with the transients at the beginning
            # also remove some corruption at the end of the stream
            #    this is a bug, probably due to the corner cases
            d = tb.snks[i].data()[Ns:Ne]

            sp1_f = fig1.add_subplot(Nrows, Ncols, 1+i)
            X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs_o,
                              window = lambda d: d*winfunc(fftlen),
                              scale_by_freq=True)
            X_o = 10.0*scipy.log10(abs(X))
            f_o = scipy.arange(-fs_o/2.0, fs_o/2.0, fs_o/float(X_o.size))
            p2_f = sp1_f.plot(f_o, X_o, "b")
            sp1_f.set_xlim([min(f_o), max(f_o)+1])
            sp1_f.set_ylim([-200.0, 50.0])

            sp1_f.set_title(("Channel %d" % i), weight="bold")
            sp1_f.set_xlabel("Frequency (Hz)")
            sp1_f.set_ylabel("Power (dBW)")

            x_o = scipy.array(d)
            t_o = scipy.arange(0, Tmax_o, Ts_o)
            sp2_o = fig2.add_subplot(Nrows, Ncols, 1+i)
            p2_o = sp2_o.plot(t_o, x_o.real, "b")
            p2_o = sp2_o.plot(t_o, x_o.imag, "r")
            sp2_o.set_xlim([min(t_o), max(t_o)+1])
            sp2_o.set_ylim([-2, 2])

            sp2_o.set_title(("Channel %d" % i), weight="bold")
            sp2_o.set_xlabel("Time (s)")
            sp2_o.set_ylabel("Amplitude")

        pylab.show()

if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        pass


import os
import sys
import glob
import shutil
import subprocess

def cmd(c):
    x = os.system(c)
    assert x == 0, c

def fail(subject, email=None, filename='/dev/null', mailer='mail'):
    assert mailer in ['mailx', 'mail', 'mutt']
    import os
    if email is not None:
        if filename == '/dev/null':
            assert os.system('mail -s "%s" %s < %s' %
                             (subject, email, filename)) == 0
        else: # attachments
            filenames = filename.split()
            if mailer == 'mailx': # new mailx (12?)
                attach = ''
                for f in filenames:
                    attach += ' -a %s ' % f
                # send with empty body
                assert os.system('echo | mail %s -s "%s" %s' %
                                 (attach, subject, email)) == 0
            elif mailer == 'mail': # old mailx (8?)
                attach = '('
                for f in filenames:
                    ext = os.path.splitext(f)[-1]
                    if ext:
                        flog = os.path.basename(f).replace(ext, '.log')
                    else:
                        flog = f
                    attach += 'uuencode %s %s&&' % (f, flog)
                # remove final &&
                attach = attach[:-2]
                attach += ')'
                assert os.system('%s | mail -s "%s" %s' %
                                 (attach, subject, email)) == 0
            else: # mutt
                attach = ''
                for f in filenames:
                    attach += ' -a %s ' % f
                # send with empty body
                assert os.system('mutt %s -s "%s" %s < /dev/null' %
                                 (attach, subject, email)) == 0
    raise SystemExit

if '--dir' in sys.argv:
    i = sys.argv.index('--dir')
    dir = os.path.abspath(sys.argv[i+1])
else:
    dir = 'agts'

if '--email' in sys.argv:
    i = sys.argv.index('--email')
    email = sys.argv[i+1]
else:
    email = None

assert os.path.isdir(dir)

gpawdir = os.path.join(dir, 'gpaw')

# remove the old run directory
if os.path.isdir(dir):
    shutil.rmtree(dir)

os.mkdir(dir)
os.chdir(dir)

cmd('svn checkout https://svn.fysik.dtu.dk/projects/gpaw/trunk gpaw')

# a version of gpaw is needed for imports from within this script!
cmd("\
cd " + gpawdir + "&& \
source /home/camp/modulefiles.sh&& \
module load NUMPY&& \
python setup.py build_ext 2>&1 > build_ext.log")

# import gpaw from where it was installed
sys.path.insert(0, gpawdir)

cmd("echo '\
cd '" + gpawdir + "'&& \
source /home/camp/modulefiles.sh&& \
module load NUMPY&& \
module load open64/4.2.3-0 && \
module load openmpi/1.3.3-1.el5.fys.open64.4.2.3 && \
module load hdf5/1.8.6-5.el5.fys.open64.4.2.3.openmpi.1.3.3 && \
python setup.py --remove-default-flags --customize=\
doc/install/Linux/Niflheim/el5-xeon-open64-acml-4.4.0-acml-4.4.0-hdf-SL-2.0.1.py \
build_ext 2>&1 > thul.log' | ssh thul bash")

cmd("echo '\
cd '" + gpawdir + "'&& \
source /home/camp/modulefiles.sh&& \
module load NUMPY&& \
module load open64/4.2.3-0 && \
python setup.py --remove-default-flags --customize=\
doc/install/Linux/Niflheim/el5-opteron-open64-acml-4.4.0-acml-4.4.0-hdf-SL-2.0.1.py \
build_ext 2>&1 > fjorm.log' | ssh fjorm bash")

cmd("""wget --no-check-certificate --quiet \
http://wiki.fysik.dtu.dk/gpaw-files/gpaw-setups-latest.tar.gz && \
tar xzf gpaw-setups-latest.tar.gz && \
rm gpaw-setups-latest.tar.gz && \
mv gpaw-setups-[0-9]* gpaw/gpaw-setups""")

cmd('svn export https://svn.fysik.dtu.dk/projects/ase/trunk ase')

# ase needed
sys.path.insert(0, '%s/ase' % dir)

from gpaw.test.big.agts import AGTSQueue
from gpaw.test.big.niflheim import NiflheimCluster

queue = AGTSQueue()
queue.collect()
cluster = NiflheimCluster(asepath=os.path.join(dir, 'ase'),
                          setuppath=os.path.join(gpawdir, 'gpaw-setups'))
# Example below is confusing: job.script must NOT be the *.agts.py script,
# but the actual python script to be run!
# testsuite.agts.py does both: see gpaw/test/big/miscellaneous/testsuite.agts.py
#queue.jobs = [job for job in queue.jobs if job.script == 'testsuite.agts.py']

nfailed = queue.run(cluster)

gfiles = os.path.join(dir, 'gpaw-files')
if not os.path.isdir(gfiles):
    os.mkdir(gfiles)

queue.copy_created_files(gfiles)

# make files readable by go
files = glob.glob(gfiles + '/*')
for f in files:
    os.chmod(f, 0644)

from gpaw.version import version

subject = 'AGTS GPAW %s: ' % str(version)
# Send mail:
sfile = os.path.join(dir, 'status.log')
attach = sfile
if not nfailed:
    subject += ' succeeded'
    fail(subject, email, attach, mailer='mutt')
else:
    subject += ' failed'
    # attach failed tests error files
    ft = [l.split()[0] for l in open(sfile).readlines() if 'FAILED' in l]
    for t in ft:
        ef = glob.glob(os.path.join(dir, t) + '.e*')
        for f in ef:
            attach += ' ' + f
    fail(subject, email, attach, mailer='mutt')

if 0:
    # Analysis:
    import matplotlib
    matplotlib.use('Agg')
    from gpaw.test.big.analysis import analyse
    user = os.environ['USER']
    analyse(queue,
            '../analysis/analyse.pickle',  # file keeping history
            '../analysis',                 # Where to dump figures
            rev=niflheim.revision,
            #mailto='gpaw-developers@listserv.fysik.dtu.dk',
            mailserver='servfys.fysik.dtu.dk',
            attachment='status.log')


"""
==============================
Lasso on dense and sparse data
==============================

We show that linear_model.Lasso provides the same results for dense and sparse
data and that in the case of sparse data the speed is improved.

"""
print(__doc__)

from time import time
from scipy import sparse
from scipy import linalg

from sklearn.datasets.samples_generator import make_regression
from sklearn.linear_model import Lasso

###############################################################################
# The two Lasso implementations on Dense data
print("--- Dense matrices")

X, y = make_regression(n_samples=200, n_features=5000, random_state=0)
X_sp = sparse.coo_matrix(X)

alpha = 1
sparse_lasso = Lasso(alpha=alpha, fit_intercept=False, max_iter=1000)
dense_lasso = Lasso(alpha=alpha, fit_intercept=False, max_iter=1000)

t0 = time()
sparse_lasso.fit(X_sp, y)
print("Sparse Lasso done in %fs" % (time() - t0))

t0 = time()
dense_lasso.fit(X, y)
print("Dense Lasso done in %fs" % (time() - t0))

print("Distance between coefficients : %s"
      % linalg.norm(sparse_lasso.coef_ - dense_lasso.coef_))

###############################################################################
# The two Lasso implementations on Sparse data
print("--- Sparse matrices")

Xs = X.copy()
Xs[Xs < 2.5] = 0.0
Xs = sparse.coo_matrix(Xs)
Xs = Xs.tocsc()

print("Matrix density : %s %%" % (Xs.nnz / float(X.size) * 100))

alpha = 0.1
sparse_lasso = Lasso(alpha=alpha, fit_intercept=False, max_iter=10000)
dense_lasso = Lasso(alpha=alpha, fit_intercept=False, max_iter=10000)

t0 = time()
sparse_lasso.fit(Xs, y)
print("Sparse Lasso done in %fs" % (time() - t0))

t0 = time()
dense_lasso.fit(Xs.toarray(), y)
print("Dense Lasso done in %fs" % (time() - t0))

print("Distance between coefficients : %s"
      % linalg.norm(sparse_lasso.coef_ - dense_lasso.coef_))


from __future__ import absolute_import

from distutils.version import LooseVersion

import numpy as np
import pandas as pd
from shapely.geometry import Point, Polygon

import geopandas
from geopandas import GeoDataFrame, GeoSeries, read_file, base
from geopandas import sjoin

import pytest
from pandas.util.testing import assert_frame_equal

pandas_0_18_problem = 'fails under pandas < 0.19 due to pandas issue 15692,'\
                        'not problem with sjoin.'

@pytest.fixture()
def dfs(request):
    polys1 = GeoSeries(
        [Polygon([(0, 0), (5, 0), (5, 5), (0, 5)]),
         Polygon([(5, 5), (6, 5), (6, 6), (5, 6)]),
         Polygon([(6, 0), (9, 0), (9, 3), (6, 3)])])

    polys2 = GeoSeries(
        [Polygon([(1, 1), (4, 1), (4, 4), (1, 4)]),
         Polygon([(4, 4), (7, 4), (7, 7), (4, 7)]),
         Polygon([(7, 7), (10, 7), (10, 10), (7, 10)])])

    df1 = GeoDataFrame({'geometry': polys1, 'df1': [0, 1, 2]})
    df2 = GeoDataFrame({'geometry': polys2, 'df2': [3, 4, 5]})
    if request.param == 'string-index':
        df1.index = ['a', 'b', 'c']
        df2.index = ['d', 'e', 'f']

    # construction expected frames
    expected = {}

    part1 = df1.copy().reset_index().rename(
        columns={'index': 'index_left'})
    part2 = df2.copy().iloc[[0, 1, 1, 2]].reset_index().rename(
        columns={'index': 'index_right'})
    part1['_merge'] = [0, 1, 2]
    part2['_merge'] = [0, 0, 1, 3]
    exp = pd.merge(part1, part2, on='_merge', how='outer')
    expected['intersects'] = exp.drop('_merge', axis=1).copy()

    part1 = df1.copy().reset_index().rename(
        columns={'index': 'index_left'})
    part2 = df2.copy().reset_index().rename(
        columns={'index': 'index_right'})
    part1['_merge'] = [0, 1, 2]
    part2['_merge'] = [0, 3, 3]
    exp = pd.merge(part1, part2, on='_merge', how='outer')
    expected['contains'] = exp.drop('_merge', axis=1).copy()

    part1['_merge'] = [0, 1, 2]
    part2['_merge'] = [3, 1, 3]
    exp = pd.merge(part1, part2, on='_merge', how='outer')
    expected['within'] = exp.drop('_merge', axis=1).copy()

    return [request.param, df1, df2, expected]

@pytest.mark.skipif(not base.HAS_SINDEX, reason='Rtree absent, skipping')
class TestSpatialJoin:

    @pytest.mark.parametrize('dfs', ['default-index', 'string-index'],
                             indirect=True)
    @pytest.mark.parametrize('op', ['intersects', 'contains', 'within'])
    def test_inner(self, op, dfs):
        index, df1, df2, expected = dfs

        res = sjoin(df1, df2, how='inner', op=op)

        exp = expected[op].dropna().copy()
        exp = exp.drop('geometry_y', axis=1).rename(
            columns={'geometry_x': 'geometry'})
        exp[['df1', 'df2']] = exp[['df1', 'df2']].astype('int64')
        if index == 'default-index':
            exp[['index_left', 'index_right']] = \
                exp[['index_left', 'index_right']].astype('int64')
        exp = exp.set_index('index_left')
        exp.index.name = None

        assert_frame_equal(res, exp)

    @pytest.mark.parametrize('dfs', ['default-index', 'string-index'],
                             indirect=True)
    @pytest.mark.parametrize('op', ['intersects', 'contains', 'within'])
    def test_left(self, op, dfs):
        index, df1, df2, expected = dfs

        res = sjoin(df1, df2, how='left', op=op)

        exp = expected[op].dropna(subset=['index_left']).copy()
        exp = exp.drop('geometry_y', axis=1).rename(
            columns={'geometry_x': 'geometry'})
        exp['df1'] = exp['df1'].astype('int64')
        if index == 'default-index':
            exp['index_left'] = exp['index_left'].astype('int64')
            # TODO: in result the dtype is object
            res['index_right'] = res['index_right'].astype(float)
        exp = exp.set_index('index_left')
        exp.index.name = None

        assert_frame_equal(res, exp)

    @pytest.mark.parametrize('dfs', ['default-index', 'string-index'],
                             indirect=True)
    @pytest.mark.parametrize('op', ['intersects', 'contains', 'within'])
    def test_right(self, op, dfs):
        index, df1, df2, expected = dfs

        res = sjoin(df1, df2, how='right', op=op)

        exp = expected[op].dropna(subset=['index_right']).copy()
        exp = exp.drop('geometry_x', axis=1).rename(
            columns={'geometry_y': 'geometry'})
        exp['df2'] = exp['df2'].astype('int64')
        if index == 'default-index':
            exp['index_right'] = exp['index_right'].astype('int64')
            res['index_left'] = res['index_left'].astype(float)
        exp = exp.set_index('index_right')
        exp = exp.reindex(columns=res.columns)

        assert_frame_equal(res, exp, check_index_type=False)

@pytest.mark.skipif(not base.HAS_SINDEX, reason='Rtree absent, skipping')
class TestSpatialJoinNYBB:

    def setup_method(self):
        nybb_filename = geopandas.datasets.get_path('nybb')
        self.polydf = read_file(nybb_filename)
        self.crs = self.polydf.crs
        N = 20
        b = [int(x) for x in self.polydf.total_bounds]
        self.pointdf = GeoDataFrame(
            [{'geometry': Point(x, y),
              'pointattr1': x + y, 'pointattr2': x - y}
             for x, y in zip(range(b[0], b[2], int((b[2]-b[0])/N)),
                             range(b[1], b[3], int((b[3]-b[1])/N)))],
            crs=self.crs)

    def test_geometry_name(self):
        # test sjoin is working with other geometry name
        polydf_original_geom_name = self.polydf.geometry.name
        self.polydf = (self.polydf.rename(columns={'geometry': 'new_geom'})
                                  .set_geometry('new_geom'))
        assert polydf_original_geom_name != self.polydf.geometry.name
        res = sjoin(self.polydf, self.pointdf, how="left")
        assert self.polydf.geometry.name == res.geometry.name

    def test_sjoin_left(self):
        df = sjoin(self.pointdf, self.polydf, how='left')
        assert df.shape == (21, 8)
        for i, row in df.iterrows():
            assert row.geometry.type == 'Point'
        assert 'pointattr1' in df.columns
        assert 'BoroCode' in df.columns

    def test_sjoin_right(self):
        # the inverse of left
        df = sjoin(self.pointdf, self.polydf, how="right")
        df2 = sjoin(self.polydf, self.pointdf, how="left")
        assert df.shape == (12, 8)
        assert df.shape == df2.shape
        for i, row in df.iterrows():
            assert row.geometry.type == 'MultiPolygon'
        for i, row in df2.iterrows():
            assert row.geometry.type == 'MultiPolygon'

    def test_sjoin_inner(self):
        df = sjoin(self.pointdf, self.polydf, how="inner")
        assert df.shape == (11, 8)

    def test_sjoin_op(self):
        # points within polygons
        df = sjoin(self.pointdf, self.polydf, how="left", op="within")
        assert df.shape == (21, 8)
        assert df.ix[1]['BoroName'] == 'Staten Island'

        # points contain polygons? never happens so we should have nulls
        df = sjoin(self.pointdf, self.polydf, how="left", op="contains")
        assert df.shape == (21, 8)
        assert np.isnan(df.ix[1]['Shape_Area'])

    def test_sjoin_bad_op(self):
        # AttributeError: 'Point' object has no attribute 'spandex'
        with pytest.raises(ValueError):
            sjoin(self.pointdf, self.polydf, how="left", op="spandex")

    def test_sjoin_duplicate_column_name(self):
        pointdf2 = self.pointdf.rename(columns={'pointattr1': 'Shape_Area'})
        df = sjoin(pointdf2, self.polydf, how="left")
        assert 'Shape_Area_left' in df.columns
        assert 'Shape_Area_right' in df.columns

    def test_sjoin_values(self):
        # GH190
        self.polydf.index = [1, 3, 4, 5, 6]
        df = sjoin(self.pointdf, self.polydf, how='left')
        assert df.shape == (21, 8)
        df = sjoin(self.polydf, self.pointdf, how='left')
        assert df.shape == (12, 8)

    @pytest.mark.skipif(str(pd.__version__) < LooseVersion('0.19'),
                        reason=pandas_0_18_problem)
    @pytest.mark.xfail
    def test_no_overlapping_geometry(self):
        # Note: these tests are for correctly returning GeoDataFrame
        # when result of the join is empty

        df_inner = sjoin(self.pointdf.iloc[17:], self.polydf, how='inner')
        df_left = sjoin(self.pointdf.iloc[17:], self.polydf, how='left')
        df_right = sjoin(self.pointdf.iloc[17:], self.polydf, how='right')

        # Recent Pandas development has introduced a new way of handling merges
        # this change has altered the output when no overlapping geometries
        if str(pd.__version__) > LooseVersion('0.18.1'):
            right_idxs = pd.Series(range(0, 5), name='index_right',
                                   dtype='int64')
        else:
            right_idxs = pd.Series(name='index_right', dtype='int64')

        expected_inner_df = pd.concat(
            [self.pointdf.iloc[:0],
             pd.Series(name='index_right', dtype='int64'),
             self.polydf.drop('geometry', axis=1).iloc[:0]],
            axis=1)

        expected_inner = GeoDataFrame(
            expected_inner_df, crs={'init': 'epsg:4326', 'no_defs': True})

        expected_right_df = pd.concat(
            [self.pointdf.drop('geometry', axis=1).iloc[:0],
             pd.concat([pd.Series(name='index_left', dtype='int64'),
                        right_idxs],
                       axis=1),
             self.polydf],
            axis=1)

        expected_right = GeoDataFrame(
            expected_right_df, crs={'init': 'epsg:4326', 'no_defs': True})\
            .set_index('index_right')

        expected_left_df = pd.concat(
            [self.pointdf.iloc[17:],
             pd.Series(name='index_right', dtype='int64'),
             self.polydf.iloc[:0].drop('geometry', axis=1)],
            axis=1)

        expected_left = GeoDataFrame(
            expected_left_df, crs={'init': 'epsg:4326', 'no_defs': True})

        assert expected_inner.equals(df_inner)
        assert expected_right.equals(df_right)
        assert expected_left.equals(df_left)

    @pytest.mark.skip("Not implemented")
    def test_sjoin_outer(self):
        df = sjoin(self.pointdf, self.polydf, how="outer")
        assert df.shape == (21, 8)