visualdynamics.core.chance¶
chance
¶
How many lines of a comparison fall outside its bands by chance.
An averaged autospectrum is an estimate. Every line of it scatters
about the true level, and the estimate over the truth is a chi-square
variable over its statistical degrees of freedom (DOF), the same law
the confidence band on an averaged PSD is drawn from
(core.averaging.chi_square_factors). So a response whose true level
sits exactly on its specification still puts some lines outside a band
about it, and how many depends on nothing but the band's width in
decibels and the DOF. A line reads more than b dB high when the
chi-square variable exceeds
dof · 10^(b/10)
and more than b dB low when it falls under dof · 10^(-b/10). At 120
DOF about 0.85 % of lines fall outside plus or minus 1.5 dB, four in
five of them low, and about one in a million outside plus or minus
3 dB. On a 400-line comparison that is three or four lines outside the
narrower band on any one average, in different places on the next.
A comparison counts the lines outside each pair of limits
(compliance.compare). compare_chance sets beside each count the
number chance alone would put there at the comparison's DOF, with the
true level exactly on the target: the sum over the judged lines of
each line's chance of reading past each edge (chance_outside). A
count near its expectation is the scatter of the estimate. A count
well above it, from a group of adjacent lines on one side of the
target, is a real excursion.
Combining lines. Some test documents allow adjacent control lines
to be combined for judging the tolerance: their powers added into one
wider band, judged against the limits' power over the same band. The
sum of N independent lines' estimates is worth about N times a line's
DOF, so the chance scatter shrinks, while a real excursion spread
across neighboring lines survives the combination. compare_chance
with combine N judges the comparison in groups of N adjacent lines.
A group's DOF is Satterthwaite's for a sum of independent chi-square
estimates weighted by the power each line was asked for,
(sum of a_i)² / (sum of a_i² / dof_i)
which is exactly N times a line's on a flat stretch and a little less where the target slopes across the group, since the louder lines carry more of the sum. That holds for independent lines, which a windowed average's are not.
Neighboring lines are not independent. A window spreads each line's
power into its neighbors, so the estimates at adjacent lines vary
together, and a sum of them steadies less than independent lines would.
The PSD carries how much (Psd.line_correlation, worked out from its
window, hop and frame count by core.averaging.line_correlation): 0
for a rectangle without overlap, 0.44 at one line apart for a Hann
window. With it the variance of a sum of lines weighted a_i is
sum over i, j of a_i a_j r(|i - j|) / n
and its degrees of freedom are (sum of a_i)² n over that sum, which is Satterthwaite's above when r is 0 past the line itself. Eight lines of a Hann window at half overlap are worth 4.3 times a line's, not eight; white noise averaged that way measures the same. The same holds for a cell of the specification coarser than the lines, which is a sum of the lines under it. A PSD that does not carry its correlation (read from a file without it, or built by hand) has its lines taken as independent, and the result says so.
References
That an averaged autospectrum is the true one times a chi-square variable over its degrees of freedom is the standard result for the averaged periodogram, and this is where it is set out. The degrees of freedom of a weighted sum of such estimates (Satterthwaite's approximation) and the correlation a window leaves between adjacent lines are worked out above, from the variance of the sum and from the window itself.
- Bendat, J. S., & Piersol, A. G. (2010). Random Data: Analysis and Measurement Procedures, 4th ed. Wiley. The sampling distribution of an autospectral density estimate and its random error.
Classes:
| Name | Description |
|---|---|
ChanceShare |
The share of lines that read outside a band by chance alone: |
Functions:
| Name | Description |
|---|---|
chance_outside |
The share of an averaged autospectrum's lines that read outside a |
compare_chance |
The lines of one comparison outside each pair of limits, beside how |
describe_chance |
One pair of a |
expected_text |
An expected count in words: one decimal from 0.1 up, and a share |
Classes¶
ChanceShare
¶
Bases: NamedTuple
The share of lines that read outside a band by chance alone:
below its lower edge and above its upper one, as fractions
between 0 and 1.
Attributes:
| Name | Type | Description |
|---|---|---|
total |
Any
|
The share outside either edge. |
Functions:¶
chance_outside
¶
chance_outside(dof: ArrayLike, lower_db: ArrayLike | None = None, upper_db: ArrayLike | None = None) -> ChanceShare
The share of an averaged autospectrum's lines that read outside a band about the true level by chance alone.
A line averaged to dof statistical degrees of freedom reads the
true level times a chi-square variable over dof. It reads below
lower_db (a negative number of dB from the truth) when that
variable falls under dof · 10^(lower_db/10), and above upper_db
when it exceeds dof · 10^(upper_db/10). Either edge may be None
(or infinite) for a band with no edge on that side. The arguments
broadcast against each other, so a band whose edges vary along the
frequency axis gives a share per line.
It is the same law as core.averaging.chi_square_factors, read the
other way: that gives where the truth lies about an estimate at a
confidence level, this the chance of an estimate reading a given
distance from the truth. At the band chi_square_factors gives for
a level, turned about, each side holds half of one minus the level.
Examples: at two degrees of freedom (one frame, an exponential variable) a line reads more than 3 dB low with probability 1 - exp(-10^-0.3), 0.394, and more than 3 dB high with probability exp(-10^0.3), 0.136. At 120 the shares outside plus or minus 1.5 dB are 0.65 % below and 0.20 % above.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dof
|
float or array_like
|
The statistical degrees of freedom, more than zero; need not be whole. |
required |
lower_db
|
float or array_like
|
The band's edges in dB from the true level. A lower edge at or above zero, or an upper edge at or below it, is a band the truth itself is outside, and gives a share of a half or more. |
None
|
upper_db
|
float or array_like
|
The band's edges in dB from the true level. A lower edge at or above zero, or an upper edge at or below it, is a band the truth itself is outside, and gives a share of a half or more. |
None
|
Returns:
| Type | Description |
|---|---|
ChanceShare
|
|
Source code in src/visualdynamics/core/chance.py
compare_chance
¶
compare_chance(specification: Specification, measured: DataArray, spec_record: int = 0, measured_record: int = 0, *, dof: float | None = None, combine: int = 1, scale_db: float | None = None) -> dict[str, Any]
The lines of one comparison outside each pair of limits, beside how many chance alone would put there at the comparison's degrees of freedom.
The comparison is compliance.compare's, cell for cell: the same
cells, the same scale, the same areas. For each pair of limits the
specification carries, the lines outside its lower and its upper
edge are counted, and the number expected outside each by chance is
the sum over the judged lines of chance_outside at that line's
edges, in dB from the target over the same cell, with the true level
taken to sit exactly on the target. With combine 1 the counts are
compare's own.
With combine N the judged lines are taken N adjacent at a time,
their powers added and judged against the limits' power over the
same stretch, each group at its own degrees of freedom: those of a
sum of correlated lines (Satterthwaite's, with the PSD's
line_correlation), N times a line's only for independent lines on
a flat stretch. A group does not
reach across a gap the specification leaves unwritten, and the last
one in a stretch may hold fewer lines. Some test documents allow this
for judging a tolerance; it changes how the test is judged, not the
test.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
specification
|
(Specification, Psd)
|
The pair: an autospectrum on narrowband lines and the specification it was controlled to. |
required |
measured
|
(Specification, Psd)
|
The pair: an autospectrum on narrowband lines and the specification it was controlled to. |
required |
spec_record
|
int
|
Which record of each. |
0
|
measured_record
|
int
|
Which record of each. |
0
|
dof
|
float
|
The statistical degrees of freedom of one line of the
measurement; read from the PSD ( |
None
|
combine
|
int
|
How many adjacent lines are judged together. |
1
|
scale_db
|
float
|
The comparison's scale in dB, added to the measurement; resolved
through |
None
|
Returns:
| Type | Description |
|---|---|
dict
|
'lines' (how many lines, or groups, were judged), 'band' (low and
high, Hz), 'scale_db', 'dof' (one line's), 'combine', 'judged_dof'
(the median group's DOF: one line's times A pair that cannot be compared returns {'lines': 0, 'refused':
reason}, as |
Raises:
| Type | Description |
|---|---|
ValueError
|
When |
Source code in src/visualdynamics/core/chance.py
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 | |
describe_chance
¶
One pair of a compare_chance result in words, as the plot's
title and the reading's pane give it: '5 of 389 lines outside the
warning band (5 below, 0 above), 3.3 expected by chance (2.5
below, 0.8 above)'. Groups are named as groups when lines were
combined. A pair the result does not carry is said to be absent.
Source code in src/visualdynamics/core/chance.py
expected_text
¶
An expected count in words: one decimal from 0.1 up, and a share too small for that given to two significant figures ('0.00041'), or '0' when it is under one in a billion, so a band chance never reaches does not read as one it sometimes does.