prober.py 3.83 KB
Newer Older
Theo Steininger's avatar
Theo Steininger committed
1
2
3
4
# -*- coding: utf-8 -*-

import abc

5
6
import numpy as np

7
8
from nifty.field_types import FieldType
from nifty.spaces import Space
Theo Steininger's avatar
Theo Steininger committed
9
from nifty.field import Field
10
11
12
import nifty.nifty_utilities as utilities

from nifty import nifty_configuration as nc
Theo Steininger's avatar
Theo Steininger committed
13
14
15
16

from d2o import STRATEGIES as DISTRIBUTION_STRATEGIES


17
class Prober(object):
Theo Steininger's avatar
Theo Steininger committed
18
    """
19
20
21
22
23
24
    See the following webpages for the principles behind the usage of
    mixin-classes

    https://www.python.org/download/releases/2.2.3/descrintro/#cooperation
    https://rhettinger.wordpress.com/2011/05/26/super-considered-super/

Theo Steininger's avatar
Theo Steininger committed
25
26
    """

27
    __metaclass__ = abc.ABCMeta
Theo Steininger's avatar
Theo Steininger committed
28

29
30
31
    def __init__(self, domain=None, field_type=None,
                 distribution_strategy=None, probe_count=8,
                 random_type='pm1', compute_variance=False):
32

33
34
        self._domain = utilities.parse_domain(domain)
        self._field_type = utilities.parse_field_type(field_type)
Theo Steininger's avatar
Theo Steininger committed
35
36
        self._distribution_strategy = \
            self._parse_distribution_strategy(distribution_strategy)
37
38
        self._probe_count = self._parse_probe_count(probe_count)
        self._random_type = self._parse_random_type(random_type)
Theo Steininger's avatar
Theo Steininger committed
39
40
        self.compute_variance = bool(compute_variance)

41
42
43
        super(Prober, self).__init__()

    # ---Properties---
44

45
    @property
Theo Steininger's avatar
Theo Steininger committed
46
    def domain(self):
47
48
49
        return self._domain

    @property
Theo Steininger's avatar
Theo Steininger committed
50
    def field_type(self):
51
52
53
        return self._field_type

    @property
Theo Steininger's avatar
Theo Steininger committed
54
    def distribution_strategy(self):
55
        return self._distribution_strategy
Theo Steininger's avatar
Theo Steininger committed
56

Theo Steininger's avatar
Theo Steininger committed
57
    def _parse_distribution_strategy(self, distribution_strategy):
58
59
60
61
        if distribution_strategy is None:
            distribution_strategy = nc['default_distribution_strategy']
        else:
            distribution_strategy = str(distribution_strategy)
62
        if distribution_strategy not in DISTRIBUTION_STRATEGIES['global']:
63
64
            raise ValueError("distribution_strategy must be a global-type "
                             "strategy.")
65
        self._distribution_strategy = distribution_strategy
66

Theo Steininger's avatar
Theo Steininger committed
67
    @property
68
69
    def probe_count(self):
        return self._probe_count
Theo Steininger's avatar
Theo Steininger committed
70

71
72
    def _parse_probe_count(self, probe_count):
        return int(probe_count)
73
74
75
76
77

    @property
    def random_type(self):
        return self._random_type

78
    def _parse_random_type(self, random_type):
79
        if random_type not in ["pm1", "normal"]:
80
81
            raise ValueError(
                "unsupported random type: '" + str(random_type) + "'.")
82
        return random_type
83
84
85

    # ---Probing methods---

86
    def probing_run(self, callee):
87
        """ controls the generation, evaluation and finalization of probes """
88
        self.reset()
89
90
        for index in xrange(self.probe_count):
            current_probe = self.get_probe(index)
91
            pre_result = self.process_probe(callee, current_probe, index)
92
            self.finish_probe(current_probe, pre_result)
93

94
95
    def reset(self):
        super(Prober, self).reset()
96
97
98
99

    def get_probe(self, index):
        """ layer of abstraction for potential probe-caching """
        return self.generate_probe()
Theo Steininger's avatar
Theo Steininger committed
100

Theo Steininger's avatar
Theo Steininger committed
101
102
    def generate_probe(self):
        """ a random-probe generator """
103
        f = Field.from_random(random_type=self.random_type,
Theo Steininger's avatar
Theo Steininger committed
104
105
                              domain=self.domain,
                              field_type=self.field_type,
Theo Steininger's avatar
Theo Steininger committed
106
                              distribution_strategy=self.distribution_strategy)
107
108
        uid = np.random.randint(1e18)
        return (uid, f)
Theo Steininger's avatar
Theo Steininger committed
109

110
111
112
    def process_probe(self, callee, probe, index):
        """ layer of abstraction for potential result-caching/recycling """
        return self.evaluate_probe(callee, probe[1])
113

114
    def evaluate_probe(self, callee, probe, **kwargs):
115
        """ processes a probe """
116
        return callee(probe, **kwargs)
117

Theo Steininger's avatar
Theo Steininger committed
118
    def finish_probe(self, probe, pre_result):
119
        super(Prober, self).finish_probe(probe, pre_result)
Theo Steininger's avatar
Theo Steininger committed
120

121
122
    def __call__(self, callee):
        return self.probing_run(callee)