From 6668744fd20e8f385ebcb6b5337bdd219d5cea15 Mon Sep 17 00:00:00 2001
From: "valentin.emiya" <valentin.emiya@lif.univ-mrs.fr>
Date: Sat, 28 Nov 2020 21:38:56 +0100
Subject: [PATCH] add variance exp

---
 python/tffpy/experiments/exp_solve_tff.py   |   7 +-
 python/tffpy/experiments/exp_variance.py    |  88 +++++++++++++
 python/tffpy/scripts/script_exp_variance.py | 130 ++++++++++++++++++++
 python/tffpy/tf_fading.py                   |  26 +++-
 4 files changed, 245 insertions(+), 6 deletions(-)
 create mode 100644 python/tffpy/experiments/exp_variance.py
 create mode 100644 python/tffpy/scripts/script_exp_variance.py

diff --git a/python/tffpy/experiments/exp_solve_tff.py b/python/tffpy/experiments/exp_solve_tff.py
index 188c0c0..88daa6d 100644
--- a/python/tffpy/experiments/exp_solve_tff.py
+++ b/python/tffpy/experiments/exp_solve_tff.py
@@ -802,10 +802,12 @@ class Solver:
         :py:meth:`~tffpy.tf_fading.GabMulTff.compute_decomposition`.
     """
 
-    def __init__(self, tol_subregions, tolerance_arrf, proba_arrf):
+    def __init__(self, tol_subregions, tolerance_arrf, proba_arrf,
+                 rand_state=0):
         self.tol_subregions = tol_subregions
         self.tolerance_arrf = tolerance_arrf
         self.proba_arrf = proba_arrf
+        self.rand_state = rand_state
 
     def __call__(self, x_mix, mask, dgt_params, signal_params):
         """
@@ -853,7 +855,8 @@ class Solver:
                         signal_params=signal_params,
                         tol_subregions=self.tol_subregions)
         gmtff.compute_decomposition(tolerance_arrf=self.tolerance_arrf,
-                                  proba_arrf=self.proba_arrf)
+                                    proba_arrf=self.proba_arrf,
+                                    rand_state=self.rand_state)
 
         # Estimate energy and lambda
         lambda_tff, t_lambda_tff = gmtff.compute_lambda(x_mix=x_mix)
diff --git a/python/tffpy/experiments/exp_variance.py b/python/tffpy/experiments/exp_variance.py
new file mode 100644
index 0000000..1e70180
--- /dev/null
+++ b/python/tffpy/experiments/exp_variance.py
@@ -0,0 +1,88 @@
+# -*- coding: utf-8 -*-
+"""
+
+.. moduleauthor:: Valentin Emiya
+"""
+import numpy as np
+
+from yafe import Experiment
+
+from tffpy.datasets import get_mix, get_dataset
+from tffpy.experiments.exp_solve_tff import SolveTffExperiment
+
+
+class VarianceExperiment(SolveTffExperiment):
+    def __init__(self, force_reset=False, suffix=''):
+        SolveTffExperiment.__init__(self,
+                                    force_reset=force_reset,
+                                    suffix='Variance' + suffix)
+
+    @staticmethod
+    def get_experiment(setting='full', force_reset=False):
+        assert setting in ('full', 'light')
+
+        dataset = get_dataset()
+        # Set task parameters
+        data_params = dict(loc_source='bird',
+                           wideband_src='car')
+        problem_params = dict(win_choice='gauss 256',
+                              # win_choice=['gauss 256', 'hann 512'],
+                              wb_to_loc_ratio_db=8,
+                              n_iter_closing=3, n_iter_opening=3,
+                              closing_first=True,
+                              delta_mix_db=0,
+                              delta_loc_db=40,
+                              or_mask=True,
+                              crop=None,
+                              fig_dir=None)
+        solver_params = dict(tol_subregions=None,
+                             tolerance_arrf=1e-3,
+                             proba_arrf=1 - 1e-4,
+                             rand_state=np.arange(100))
+        if setting == 'light':
+            problem_params['win_choice'] = 'gauss 64',
+            problem_params['crop'] = 4096
+            problem_params['delta_loc_db'] = 20
+            problem_params['wb_to_loc_ratio_db'] = 16
+            solver_params['tolerance_arrf'] = 1e-2
+            solver_params['proba_arrf'] = 1 - 1e-2
+            solver_params['rand_state'] = np.arange(3)
+
+        # Create Experiment
+        suffix = '' if setting == 'full' else '_Light'
+        exp = VarianceExperiment(force_reset=force_reset,
+                                 suffix=suffix)
+        exp.add_tasks(data_params=data_params,
+                      problem_params=problem_params,
+                      solver_params=solver_params)
+        exp.generate_tasks()
+        return exp
+
+
+def create_and_run_light_experiment():
+    """
+    Create a light experiment and run it
+    """
+    exp = VarianceExperiment.get_experiment(setting='light', force_reset=True)
+    print('*' * 80)
+    print('Created experiment')
+    print(exp)
+    print(exp.display_status())
+
+    print('*' * 80)
+    print('Run task 0')
+    task_data = exp.get_task_data_by_id(idt=0)
+    print(task_data.keys())
+    print(task_data['task_params']['data_params'])
+
+    problem = exp.get_problem(
+        **task_data['task_params']['problem_params'])
+    print(problem)
+
+    print('*' * 80)
+    print('Run all')
+    exp.launch_experiment()
+
+    print('*' * 80)
+    print('Collect and plot results')
+    exp.collect_results()
diff --git a/python/tffpy/scripts/script_exp_variance.py b/python/tffpy/scripts/script_exp_variance.py
new file mode 100644
index 0000000..8557490
--- /dev/null
+++ b/python/tffpy/scripts/script_exp_variance.py
@@ -0,0 +1,130 @@
+# -*- coding: utf-8 -*-
+# ######### COPYRIGHT #########
+# Credits
+# #######
+#
+# Copyright(c) 2020-2020
+# ----------------------
+#
+# * Laboratoire d'Informatique et Systèmes <http://www.lis-lab.fr/>
+# * Université d'Aix-Marseille <http://www.univ-amu.fr/>
+# * Centre National de la Recherche Scientifique <http://www.cnrs.fr/>
+# * Université de Toulon <http://www.univ-tln.fr/>
+#
+# Contributors
+# ------------
+#
+# * `Valentin Emiya <mailto:valentin.emiya@lis-lab.fr>`_
+# * `Ama Marina Krémé <mailto:ama-marina.kreme@lis-lab.fr>`_
+#
+# This package has been created thanks to the joint work with Florent Jaillet
+# and Ronan Hamon on other packages.
+#
+# Description
+# -----------
+#
+# Time frequency fading using Gabor multipliers
+#
+# Version
+# -------
+#
+# * tffpy version = 0.1.3
+#
+# Licence
+# -------
+#
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# ######### COPYRIGHT #########
+"""
+Run this script to handle the main experiment :class:`SolveTffExperiment`.
+
+.. moduleauthor:: Valentin Emiya
+"""
+from yafe.utils import generate_oar_script
+
+import matplotlib.pyplot as plt
+
+from tffpy.experiments.exp_variance import \
+    VarianceExperiment, create_and_run_light_experiment
+
+
+try:
+    experiment = VarianceExperiment.get_experiment(setting='full',
+                                                   force_reset=False)
+except RuntimeError:
+    experiment = None
+except FileNotFoundError:
+    experiment = None
+
+if __name__ == '__main__':
+    answer = 1
+    while answer > 0:
+        input_msg = '\n'.join(['1 - Create and run light experiment',
+                               '2 - Display results of light experiment',
+                               '3 - Full experiment: create full experiment',
+                               '4 - Generate OAR script',
+                               '5 - Full experiment: collect results',
+                               '6 - Full experiment: download results',
+                               '7 - Full experiment: display results',
+                               '0 - Exit',
+                               ])
+        answer = int(input(input_msg))
+        if answer == 0:
+            break
+        elif answer == 1:
+            create_and_run_light_experiment()
+        elif answer == 2:
+            light_exp = VarianceExperiment.get_experiment(
+                setting='light', force_reset=False)
+            for idt in range(light_exp.n_tasks):
+                light_exp.plot_task(idt=idt, fontsize=16)
+                plt.close('all')
+            light_exp.plot_results()
+        elif answer == 3:
+            experiment = VarianceExperiment.get_experiment(
+                setting='full', force_reset=True)
+            experiment.display_status()
+        elif answer == 4:
+            experiment.display_status()
+            batch_size = int(input('Batch size (#tasks per job)?'))
+            generate_oar_script(script_file_path=__file__,
+                                xp_var_name='experiment',
+                                batch_size=batch_size,
+                                oar_walltime='01:00:00',
+                                activate_env_command='source activate py36',
+                                use_gpu=False)
+        elif answer == 5:
+            experiment.collect_results()
+            experiment.display_status()
+        elif answer == 6:
+            to_dir = str(experiment.xp_path)
+            from_dir = \
+                '/data1/home/valentin.emiya/data_exp/SolveTffExperiment/'
+            print('Run:')
+            print(' '.join(['rsync', '-rv',
+                            'valentin.emiya@sms-ext.lis-lab.fr:'
+                            + from_dir,
+                            to_dir]))
+            print('Or (less files):')
+            print(' '.join(['rsync', '-rv',
+                            'valentin.emiya@sms-ext.lis-lab.fr:'
+                            + from_dir
+                            + '*.*',
+                            to_dir]))
+        elif answer == 7:
+            experiment.plot_results()
+            experiment.display_status()
+        else:
+            print('Unknown answer: ' + str(answer))
diff --git a/python/tffpy/tf_fading.py b/python/tffpy/tf_fading.py
index 7051633..1981b0c 100644
--- a/python/tffpy/tf_fading.py
+++ b/python/tffpy/tf_fading.py
@@ -138,7 +138,7 @@ class GabMulTff:
         """
         return len(self.u_mat_list)
 
-    def compute_decomposition(self, tolerance_arrf, proba_arrf):
+    def compute_decomposition(self, tolerance_arrf, proba_arrf, rand_state=0):
         """
         Decompose each Gabor multiplier using a random EVD
 
@@ -160,8 +160,16 @@ class GabMulTff:
         proba_arrf : float
             Probability of error for
             :py:func:`~skpomade.range_approximation.adaptive_randomized_range_finder`
+        rand_state : RandomState, int or None
+            If RandomState, random generator.
+            If int or None, random seed used to initialize the pseudo-random
+            number generator.
 
         """
+        if rand_state is None:
+            rand_state = np.random.RandomState(None)
+        if np.issubdtype(type(rand_state), np.dtype(int).type):
+            rand_state = np.random.RandomState(rand_state)
         for i in range(self.n_areas):
             print('Random EVD of Gabor multiplier #{}'.format(i))
             print('#coefs in mask: {} ({:.1%} missing)'
@@ -172,7 +180,8 @@ class GabMulTff:
             q_mat = adaptive_randomized_range_finder(a=self.gabmul_list[i],
                                                      tolerance=tolerance_arrf,
                                                      proba=proba_arrf, r=None,
-                                                     rand_state=0, n_cols_Q=32)
+                                                     rand_state=rand_state,
+                                                     n_cols_Q=32)
             self.t_arrf[i] = perf_counter() - t0
             print('Q shape:', q_mat.shape)
             t0 = perf_counter()
@@ -188,7 +197,7 @@ class GabMulTff:
             self.uh_x_list[i] = self.u_mat_list[i].T.conj() @ self.x_mix
             self.t_uh_x[i] = perf_counter() - t0
 
-    def compute_decomposition_fixed_rank(self, rank):
+    def compute_decomposition_fixed_rank(self, rank, rand_state=0):
         """
         Decompose each Gabor multiplier using a random EVD with given rank
 
@@ -201,7 +210,16 @@ class GabMulTff:
         ----------
         rank : int
             Rank of the decompostion
+        rand_state : RandomState, int or None
+            If RandomState, random generator.
+            If int or None, random seed used to initialize the pseudo-random
+            number generator.
         """
+        if rand_state is None:
+            rand_state = np.random.RandomState(None)
+        if np.issubdtype(type(rand_state), np.dtype(int).type):
+            rand_state = np.random.RandomState(rand_state)
+
         t_rrf = [None for i in range(self.n_areas)]
         t_evdn = [None for i in range(self.n_areas)]
         t_uh_x = [None for i in range(self.n_areas)]
@@ -214,7 +232,7 @@ class GabMulTff:
             t0 = perf_counter()
             q_mat = randomized_range_finder(a=self.gabmul_list[i],
                                             n_l=rank,
-                                            rand_state=0)
+                                            rand_state=rand_state)
             t_rrf[i] = perf_counter() - t0
             print('Q shape:', q_mat.shape)
             t0 = perf_counter()
-- 
GitLab