"""
Tests for the implementation of feature sign search.
"""

__authors__ = "David Warde-Farley"
__copyright__ = "Copyright 2010-2011, Universite de Montreal"
__credits__ = ["David Warde-Farley"]
__license__ = "3-clause BSD"
__maintainer__ = "David Warde-Farley"
__email__ = "wardefar@iro"

import numpy as np
from pylearn2.optimization.feature_sign import feature_sign_search


class TestFeatureSign(object):
    @classmethod
    def setup_class(cls):
        rng = np.random.RandomState(0)
        cls.dictionary = rng.normal(size=(100, 500)) / 1000
        cls.dictionary /= np.sqrt((cls.dictionary ** 2).sum(axis=0))
        cls.gram = np.dot(cls.dictionary.T, cls.dictionary)
        cls.signal = rng.normal(size=100) / 1000
        cls.corr = np.dot(cls.dictionary.T, cls.signal)
        cls.nzi = [np.array([0, 6, 15, 30, 31, 34,
                             36, 48, 52, 53, 62, 94,
                             99, 103, 105, 107, 124, 131,
                             133, 137, 142, 145, 171, 178,
                             190, 206, 207, 214, 221, 226,
                             228, 229, 231, 234, 246, 255,
                             257, 258, 261, 265, 268, 269,
                             279, 281, 282, 288, 289, 293,
                             294, 296, 297, 302, 303, 306,
                             319, 322, 328, 329, 331, 335,
                             337, 351, 353, 355, 362, 368,
                             369, 372, 375, 380, 390, 392,
                             394, 397, 405, 410, 412, 420,
                             421, 422, 425, 430, 432, 435,
                             439, 443, 449, 451, 455, 456,
                             457, 458, 463, 479, 484, 485,
                             492, 493, 496]),
                   np.array([0, 6, 15, 30, 31, 34,
                             40, 52, 62, 84, 99, 103,
                             107, 131, 133, 137, 142, 145,
                             171, 190, 207, 221, 226, 228,
                             229, 231, 234, 243, 255, 257,
                             258, 261, 265, 268, 279, 281,
                             284, 288, 289, 293, 294, 296,
                             297, 302, 303, 306, 308, 319,
                             322, 329, 331, 335, 337, 351,
                             353, 355, 357, 362, 369, 371,
                             372, 375, 380, 390, 392, 394,
                             397, 405, 412, 420, 422, 430,
                             435, 439, 443, 451, 455, 456,
                             457, 463, 479, 483, 484, 485,
                             492, 493, 497]),
                   np.array([0, 6, 15, 21, 28, 31,
                             34, 40, 52, 62, 75, 103,
                             133, 164, 171, 190, 226, 228,
                             229, 231, 234, 255, 258, 261,
                             265, 268, 279, 284, 289, 293,
                             294, 296, 303, 306, 308, 319,
                             322, 335, 351, 355, 360, 369,
                             371, 372, 375, 380, 392, 394,
                             397, 420, 422, 430, 435, 439,
                             443, 451, 455, 456, 457, 463,
                             479, 483, 485, 492, 493, 497]),
                   np.array([0, 15, 21, 28, 31, 34,
                             40, 52, 62, 103, 164, 171,
                             190, 206, 226, 228, 229, 231,
                             234, 255, 258, 261, 265, 268,
                             279, 294, 303, 308, 319, 322,
                             335, 355, 360, 369, 371, 372,
                             375, 380, 392, 420, 422, 430,
                             439, 443, 446, 451, 456, 457,
                             479, 483, 485, 492, 497]),
                   np.array([0, 15, 31, 32, 34, 40,
                             52, 62, 103, 164, 190, 206,
                             226, 228, 229, 231, 234, 261,
                             268, 279, 294, 303, 308, 319,
                             322, 335, 355, 360, 363, 369,
                             371, 372, 375, 392, 422, 430,
                             439, 451, 457, 479, 485, 492, 497]),
                   np.array([0, 32, 40, 52, 103, 164,
                             182, 190, 229, 234, 268, 294,
                             303, 319, 335, 355, 360, 363,
                             369, 371, 372, 375, 392, 422,
                             430, 439, 479, 485, 492, 497]),
                   np.array([0, 32, 52, 103, 190, 229,
                             234, 268, 303, 319, 335, 363,
                             369, 371, 372, 375, 392, 422,
                             430, 439, 479]),
                   np.array([52, 190, 229, 234, 319, 335,
                             369, 371, 372, 375, 392, 422,
                             430, 479]),
                   np.array([52, 229, 234, 335, 369, 371,
                             372, 375, 422, 430, 479]),
                   np.array([229, 234, 369, 372, 375, 422, 479]),
                   np.array([234, 369, 375, 479]),
                   np.array([234, 369, 375, 479]),
                   np.array([234, 369]),
                   np.array([], dtype=np.int32)]
        cls.nze = [np.array([-1.9348249481460072e-03, -2.6733387284447153e-04,
                             -1.3132617311436409e-03, -4.8160077424667838e-04,
                             -7.5839249350565386e-04, -1.5909426774904003e-03,
                              5.7527969676995383e-05, 7.9447260531266320e-05,
                              1.0451809037644966e-03, -4.1613884795362038e-04,
                              1.5212190467793459e-03, 1.7787664944475309e-04,
                             -4.8836751622554329e-04, 1.6494321148399042e-03,
                             -2.7677800129602731e-06, -5.3707951770584682e-04,
                             -6.5444024170409589e-05, -1.5828515693151556e-04,
                             -7.2127417409642656e-04, -5.1401896787202958e-04,
                              3.7758489731919223e-05, 6.6680708523377810e-04,
                              5.2900822039974530e-04, 3.0975349526476766e-05,
                              1.2917361992321301e-03, -2.6589905870352928e-04,
                              4.5817183084630225e-05, 1.3754030475796234e-04,
                             -1.6320053069891164e-03, 4.5131596808813552e-04,
                             -2.5421398951701307e-04, 1.8433162492285078e-03,
                             -9.1173071359616081e-04, 1.7471082488497108e-03,
                             -5.3360585337509928e-06, 9.1283752277065869e-04,
                              2.6051969664101067e-05, -2.4057039933035281e-04,
                              4.1276967786097276e-04, -7.2185718488784083e-04,
                              7.3222222810349295e-04, -1.1258619069166660e-03,
                             -5.9539175662470837e-05, 1.2020202196530964e-04,
                             -6.4852933217228329e-05, -3.6136499613693474e-04,
                             -2.7509451425501420e-04, 7.8402482743400567e-04,
                             -1.6375047820679251e-03, -7.6328448464493817e-05,
                              2.5201048678107204e-04, -5.3343888345009510e-04,
                              1.3637930948889019e-03, 4.1072719924889650e-05,
                             -1.5727527265822143e-03, -1.5471429922949904e-03,
                             -5.6998443448416484e-04, -3.1120566643703262e-04,
                             -5.6386207057422957e-05, 5.7371833193473369e-04,
                              3.6188962138560557e-04, -4.7316772908796121e-04,
                              2.9484545185290238e-04, -6.6535357340597704e-04,
                              8.4119874640662382e-04, -2.8329017840323988e-05,
                             -2.5306839397483431e-03, 2.4715013439992202e-03,
                             -1.1910480261999676e-03, -2.9709479220933098e-04,
                              6.8431258887171015e-04, -2.7295761244718773e-03,
                             -2.4093971793902772e-05, 6.2201228574189945e-04,
                              5.1780698320989707e-04, 2.6733781310107836e-04,
                              5.6336177344038440e-04, -1.0616591760754300e-03,
                              3.6947848006075820e-04, 6.7141992520493947e-05,
                              2.9771817071157870e-04, 5.9797094277252722e-04,
                             -3.9933204819632510e-04, 8.6517244244875048e-04,
                              4.4920353680412715e-04, -6.6808772499122302e-04,
                             -5.3361944478563209e-04, 1.5242227367637563e-03,
                              5.2896850426062208e-04, 8.9662346856869842e-04,
                              5.5085221933474243e-04, 6.6736148020986167e-05,
                              8.1560784413259606e-04, 2.6011480255750508e-04,
                              6.6830208202212017e-04, 4.1085940128486484e-04,
                             -1.7682961625122970e-03, 8.3934219900091750e-04,
                             -2.0873017058309116e-05]),
                  np.array([-1.1035294455088696e-03, -2.2000890007574505e-04,
                            -7.8903889419539659e-04, -2.1119535900836997e-04,
                            -5.8279291450617342e-04, -1.7080583717419850e-03,
                            -2.6627718634094304e-04, 1.2487012342411459e-03,
                             1.2674860805574550e-03, 1.0316196854953281e-04,
                            -3.8989827573487992e-05, 1.3959573167727619e-03,
                            -2.9263690772758253e-04, -7.5516160142673238e-05,
                            -3.2027802224615773e-04, -4.0194333313972751e-05,
                             5.2792602866442842e-05, 1.0030885855889520e-04,
                             3.4359859807725127e-04, 1.4202578828080572e-03,
                             4.9435053415793168e-05, -2.9342239639478933e-04,
                             3.7342261630825908e-04, -1.1357718570444337e-04,
                             1.4693020881404192e-03, -8.1038826473469011e-04,
                             1.8665829767200055e-03, -9.6714718311873344e-05,
                             5.6412327489350621e-04, 7.0701526303205728e-05,
                            -3.9516191942322022e-04, 6.3432608784393975e-04,
                            -6.3954164541396520e-04, 4.5235975549458074e-04,
                            -8.5992159621133923e-05, 1.4804790922793453e-05,
                             4.0644969429524014e-05, -5.2722126671811232e-05,
                            -3.6077541732844342e-04, 4.2575453908280664e-04,
                            -1.1487697489090171e-03, -4.2018807922097055e-04,
                             3.4790809594425012e-05, -1.6160032947381991e-04,
                             1.2440480492768469e-03, 1.1231144781693225e-04,
                            -3.1889994757268988e-05, -1.4839438754208341e-03,
                            -1.4511548747212302e-03, -1.3590898496856349e-04,
                            -1.1193045928555190e-04, 1.0102752291013409e-03,
                             8.5488972321372484e-05, -4.5029116166219244e-04,
                             1.2167805925053460e-04, -9.8493755243442174e-04,
                             1.2491091198674258e-04, 3.7378349690722683e-04,
                            -2.7075691573085138e-03, -4.8129161730357662e-05,
                             2.6410719309027152e-03, -1.4938221269370467e-03,