Statistics
| Revision:

root / tmp / org.txm.groovy.core / src / groovy / org / txm / macro / misc / Specif2CoinMacro.groovy @ 499

History | View | Annotate | Download (5.6 kB)

1
// Copyright © 2016 ENS de Lyon
2
//
3
// Authors:
4
// - Serge Heiden
5
//
6
// Licence:
7
// This file is part of the TXM platform.
8
// The TXM platform is free software: you can redistribute it
9
// and/or modify it under the terms of the GNU General Public
10
// License as published by the Free Software Foundation,
11
// either version 2 of the License, or (at your option) any
12
// later version.
13
//
14
// The TXM platform is distributed in the hope that it will be
15
// useful, but WITHOUT ANY WARRANTY; without even the implied
16
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
17
// PURPOSE. See the GNU General Public License for more
18
// details.
19
//
20
// You should have received a copy of the GNU General
21
// Public License along with the TXM platform. If not, see
22
// http://www.gnu.org/licenses.
23
//
24
// Version:
25
// $LastChangedDate: 2014-11-01 16:00:01 +0100 (sam., 1 nov. 2014) $
26
// $LastChangedRevision: XXXX $
27
// $LastChangedBy: sheiden $
28
//
29

    
30
/* --------------   Specif2Coin    --------------
31

32
FR:
33

34
Macro affichant la probabilité a priori (avant de faire les lancés) d'obtenir N faces 'pile' consécutives en lançant une pièce au pile ou face.
35

36
On considère qu'une pièce a 50% de chances (1 chance sur 2) de tomber sur la face 'pile' à chaque lancé (les lancés sont indépendants).
37

38
La probabilité est mise en regard avec la spécificité équivalente.
39

40
La macro prend un seul paramètre :
41

42
* nthrows : le nombre de lancés 'pile' consécutifs
43

44
La macro affiche - selon les options :
45

46
* displayProba : toutes les probabilités de 1 à nthrows lancés en détaillant :
47
-  n : le nombre de 'pile' consécutifs
48
-  p : la probabilité correspondante
49
-  % : le pourcentage correspondant
50
- pe : la probabilité exprimée en notation avec exposant en base 10
51
-  s : la spécificité équivalente (l'exposant de la probabilité, soit son logarithme en base 10)
52

53
* onlyMainRanks : s'utilise avec l'option displayProba pour n'afficher que les probabilités des rangs décimaux principaux (1, 2..., 10, 20..., 100, 200...)
54

55
* displayCoins : plutôt que le détail de la probabilité, liste pour une spécificité S- donnée, le nombre équivalent de lancés 'pile' consécutifs correspondants exprimé sous la forme d'un intervalle : nombre de lancés minimum - nombre de lancés maximum
56
Par exemple '-10 = 30-33' signifie : une spécificité S- de '-10' équivaut à entre 30 et 33 lancés 'pile' consécutifs
57

58
Les limites du calcul sont celles de la machine. Une machine 64-bit peut typiquement calculer la probabilité de 1023 lancés consécutifs.
59

60
*/
61

    
62
// STANDARD DECLARATIONS
63
package org.txm.macro.misc
64

    
65
import org.kohsuke.args4j.*
66
import groovy.transform.Field
67
import org.txm.rcp.swt.widget.parameters.*
68
import org.eclipse.ui.console.*
69

    
70
// BEGINNING OF PARAMETERS
71

    
72
@Field @Option(name="nthrows", usage="maximum number of throws", widget="Integer", required=true, def="99")
73
def nthrows
74

    
75
@Field @Option(name="displayProba", usage="display probabilities", widget="Boolean", required=false, def="true")
76
def displayProba
77

    
78
@Field @Option(name="onlyMainRanks", usage="only display main rank lines", widget="Boolean", required=false, def="false")
79
def onlyMainRanks
80

    
81
@Field @Option(name="displayCoins", usage="display equivalent of coin flipping", widget="Boolean", required=false, def="true")
82
def displayCoins
83

    
84
// Open the parameters input dialog box
85
if (!ParametersDialog.open(this)) return
86

    
87
// END OF PARAMETERS
88

    
89
def clearConsole = { ->
90
        // clear the console
91
        (ConsolePlugin.getDefault().getConsoleManager().getConsoles())[0].clearConsole()
92
}
93

    
94
clearConsole()
95

    
96
min = [:]
97
max = [:]
98

    
99
pow = 2**(nthrows)
100
powd = pow.doubleValue()
101

    
102
if (powd == Double.POSITIVE_INFINITY || powd == Double.NEGATIVE_INFINITY) {
103
        println sprintf("** Impossible to calculate probabilities for this value, try a lower value (impossible to represent 2 to the power of %d with this machine). Aborting.", nthrows)
104
        return
105
}
106

    
107
d = 1/powd
108

    
109
significandSize = ((-java.lang.Math.log10(d) as double)-1 as int)+4
110

    
111
format = sprintf("%%4d = %%%d.%df = %%0%d.%df%%%% = %%9.2e = %%4d", significandSize, significandSize-2, significandSize-1, significandSize-4)
112

    
113
unit = 1
114
dec = 1
115

    
116
if (displayProba) {
117
        println """Légende :
118
-  n : le nombre de 'pile' consécutifs
119
-  p : la probabilité correspondante
120
-  % : le pourcentage correspondant
121
- pe : la probabilité exprimée en notation avec exposant en base 10
122
-  s : la spécificité équivalente (l'exposant de la probabilité, soit son logarithme en base 10)
123
"""
124
        spc = ' ' * (significandSize+2)
125
        println "   n    p"+spc+" %"+spc+"  pe         s"
126
}
127

    
128
nthrows.times {
129
    n = it+1
130
        p = 1/2**(n) as double
131
        s = java.lang.Math.log10(p)-1 as int
132
        if (min[s]) { if (min[s] > n) min[s] = n } else min[s] = n
133
        if (max[s]) { if (max[s] < n) max[s] = n } else max[s] = n
134
        if (displayProba) {
135
                s = sprintf(format, n, p, p*100, p, s).replaceAll(/ = 0([^,])/, ' =  $1')
136
                m0 = s =~ /(....)0+ = ([^-])/
137
                if (m0.count > 0) {
138
                        spc0 = m0[0][1] + (' ' * (m0[0][0].size()-8)) + ' = ' + m0[0][2]
139
                        s = m0.replaceFirst(spc0)
140
                }
141
                m0p = s =~ /(....)0+% = /
142
                if (m0p.count > 0) {
143
                        spc0p = m0p[0][1] + '%' + (' ' * (m0p[0][0].size()-8)) + ' = '
144
                        s = m0p.replaceFirst(spc0p)
145
                }
146

    
147
                if (!onlyMainRanks || ((n % dec) == 0) || (n == nthrows)) {
148
                        println s
149
                }
150
                
151
                unit = unit+1
152
                if (unit >= dec * 10) {
153
                        dec = dec * 10
154
                        unit = 1
155
                }
156
        }
157
}
158

    
159
if (displayCoins) {
160

    
161
        if (displayProba) {
162
                println ""
163
        }
164

    
165
        println """Légende :
166
- -S      : spécificité équivalente
167
-  lancés : intervalle des lancés 'pile' consécutifs correspondant
168
"""
169
        println " -S   lancés"
170
        min.each { key, value -> if (min[key] != max[key]) println sprintf("%3d = %d-%d", key, min[key], max[key]) else println sprintf("%3d = %d", key, min[key])}
171
}