visualdynamics.core.matrix_checks¶
matrix_checks
¶
Two checks on the matrices a multi-input test is built from, made at every frequency line before anything is inverted or played.
A multi-input test stands on two matrices per line. The plant matrix
H, one row per control channel and one column per drive, is what the
controller inverts to turn the control error into a drive correction.
The cross-spectral density matrix S, one row and one column per
channel, is what a specification asks the control channels to hold:
their autospectra on the diagonal and, off it, how each pair moves
together. Each can be wrong in a way no single record shows.
Conditioning
The singular values of H at a line are its gains in the combinations
of drives it responds to most and least, largest first. Their ratio is
the condition number,
kappa = sigma_max / sigma_min,
dimensionless. It bounds how much a relative error in the measured
plant can grow in its inverse: an estimate good to one percent, at a
condition number of 100, can give a drive wrong by up to a hundred
percent. Two drives that reach the control channels in nearly the same
proportions, such as two shakers under one stiff fixture below its first
flexible mode, make two nearly equal columns, a small sigma_min and a
large condition number, and the inverse that separates them is made of
noise. CONDITION_LIMIT is the threshold a line is flagged over, a
choice and not a law; a controller holds a setting of its own for it.
The effective rank at that threshold is the number of singular values
at least sigma_max / limit, so a line is flagged exactly where the
effective rank falls under the full rank. The same reading is made of
the cross-spectral matrix of the drives, Gff, whose singular values
are its eigenvalues: drives that are nearly copies of one another make
it nearly singular, and an FRF estimate from them inverts it.
read_conditioning reads an FRF (several references) or a CSD and
returns a Conditioning. The matrix is in one unit or the reading is
refused: a condition number of a matrix whose rows are in different
units changes when one row's unit does, so it would describe the units
and not the plant.
Realizability
The cross-spectral matrix of any set of signals is Hermitian (the term for channel j against i is the conjugate of i against j) and positive semi-definite (no combination of the channels has negative power) at every line. A specification that is not cannot be produced by any drive, and a controller asked for one fails at those lines, however long it runs. Each entry can look right on its own: three channels with every coherence 1 and phases of 0, 0 and 180 degrees ask for 1 in step with 2, 2 in step with 3, and 1 opposite 3, which no motion does.
The check is made on the coherence matrix, the cross-spectral matrix scaled by the root of its diagonal,
C_ij = S_ij / sqrt(S_ii S_jj),
which has ones on its diagonal, is free of units, and is positive
semi-definite exactly where S is (a scaling by a positive diagonal
does not change the signs of the eigenvalues). Its eigenvalues sum to
the number of channels. A line is realizable where the smallest is no
lower than minus tolerance times the largest and the matrix is
Hermitian to the same tolerance. The default REALIZABLE_TOLERANCE
passes a matrix written to six significant figures and refuses any
departure larger than that. The rank at a line counts the eigenvalues
over tolerance times the largest: one for fully coherent channels,
the number of channels for independent ones.
A matrix that fails is repaired to the nearest one that is realizable, in the Frobenius norm of the coherence matrix. Keeping the diagonal (the default), the autospectra stay exactly as written and only the cross terms move: the nearest unit-diagonal positive semi-definite matrix, found by alternating projections with Dykstra's correction. Not keeping it, the negative eigenvalues are set to zero and the matrix rebuilt, which also moves the autospectra. Lines that pass are left as they are, bit for bit. The reading reports the largest change in coherence and in phase the repair made, and where.
read_realizability reads a CSD and returns a Realizability;
SpecificationDraft refuses a sheet whose coherence and phase entries
cannot hold together, by the same check.
References
The singular value decomposition and the condition number are Golub and Van Loan's; the nearest positive semi-definite matrix is Higham's, in two papers; the properties of a cross-spectral density matrix are Bendat and Piersol's.
- Golub, G. H., & Van Loan, C. F. (2013). Matrix Computations, 4th ed. Johns Hopkins University Press. The singular value decomposition, the condition number, and the bound it puts on the error of a solution.
- Higham, N. J. (1988). "Computing a nearest symmetric positive semidefinite matrix." Linear Algebra and its Applications, 103, 103-118. doi:10.1016/0024-3795(88)90223-6 The nearest positive semi-definite matrix in the Frobenius norm, by setting the negative eigenvalues to zero.
- Higham, N. J. (2002). "Computing the nearest correlation matrix: a problem from finance." IMA Journal of Numerical Analysis, 22(3), 329-343. doi:10.1093/imanum/22.3.329 The alternating projections, with Dykstra's correction, that find the nearest unit-diagonal positive semi-definite matrix.
- Bendat, J. S., & Piersol, A. G. (2010). Random Data: Analysis and Measurement Procedures, 4th ed. Wiley. The cross-spectral density matrix of several records, Hermitian and non-negative definite, and the ordinary and multiple coherence read from it.
Classes:
| Name | Description |
|---|---|
ConditioningPoint |
The conditioning of the matrix at one line: what |
Conditioning |
The singular values and the condition number of a matrix at every |
RealizabilityPoint |
The realizability of the matrix at one line: what |
Realizability |
Whether a cross-spectral matrix can be produced by any set of |
Functions:
| Name | Description |
|---|---|
channel_labels |
A label per (DOF, quantity) channel: the DOF, with the quantity |
runs |
(first, last) index of each run of consecutive true flags. |
nearest_line |
The index of the line of |
frf_matrix |
The records of an FRF assembled into the response-by-reference |
entry_channels |
(row channel, column channel) of one record of a spectral matrix. |
matrix_entries |
Each record of a spectral matrix with the entry it holds. |
mirrors_disagree |
Whether a cross term and its mirror, read at the same lines, are |
spectral_matrix |
The records of a CSD assembled into its square matrix, at every |
flagged_runs |
(first, last) frequency of each run of consecutive flagged |
condition_matrix |
The singular values of a matrix at every line, as a |
read_conditioning |
The singular values and condition number of an FRF matrix, or of |
repair_coherence |
The nearest realizable matrix to each Hermitian coherence matrix, |
judge_lines |
Whether a cross-spectral matrix is realizable at every line, with |
check_spectral_matrix |
Whether a cross-spectral matrix is realizable at every line, and |
read_realizability |
Whether a CSD (a specification, or a measured cross-spectral |
made_realizable |
A copy of a CSD with the matrix the picked records make repaired |
entries_refusal |
Why a specification sheet's coherence and phase entries cannot |
Classes¶
ConditioningPoint
dataclass
¶
ConditioningPoint(frequency: float, singular: tuple[float, ...], condition: float, rank: int, size: int, limit: float)
The conditioning of the matrix at one line: what
Conditioning.at returns.
singular holds the singular values, largest first, in the
reading's units (SI); condition is the largest over the smallest,
infinite where the smallest is zero and not a number where the line
was not judged; rank is the effective rank at limit, of a full
rank of size.
Methods:
| Name | Description |
|---|---|
describe |
One line for a status bar: the condition number against the |
Attributes:
| Name | Type | Description |
|---|---|---|
ill |
bool
|
Whether the condition number is over the limit, or the |
Attributes¶
ill
property
¶
Whether the condition number is over the limit, or the smallest singular value is zero.
Methods:¶
describe
¶
One line for a status bar: the condition number against the
limit, the effective rank, and the singular values in unit
(scale converts the reading's SI into it).
Source code in src/visualdynamics/core/matrix_checks.py
Conditioning
dataclass
¶
Conditioning(frequency: ndarray, singular: ndarray, rows: tuple[str, ...], columns: tuple[str, ...], limit: float = CONDITION_LIMIT, dimension: str = UNKNOWN, kind: str = 'FRF', notes: tuple[str, ...] = ())
The singular values and the condition number of a matrix at every
line: what read_conditioning returns.
frequency holds the lines in Hz and singular the singular values
(one row per value, largest first; not a number on a line that was
not judged), in the matrix's units (SI, dimension). rows and
columns name the matrix's channels, responses and references for
an FRF, the channels twice for a CSD; kind is 'FRF' or 'CSD'.
limit is the condition number lines are flagged over. notes says
what the reading should be read with.
Methods:
| Name | Description |
|---|---|
bands |
The runs of flagged lines, as (first, last) frequencies. |
line |
The index of the line nearest |
at |
The reading at the line nearest |
describe |
The verdict in a sentence: where the condition number is over |
Attributes:
| Name | Type | Description |
|---|---|---|
size |
int
|
The full rank, the smaller of the rows and the columns. |
judged |
ndarray
|
The lines that were judged: every entry a finite number and |
condition |
ndarray
|
The condition number at every line, the largest singular value |
rank |
ndarray
|
The effective rank at every line: how many singular values are |
ill |
ndarray
|
The lines flagged: judged, with a condition number over the |
title |
str
|
What the matrix is, in words. |
Attributes¶
judged
property
¶
The lines that were judged: every entry a finite number and the matrix not all zero.
condition
property
¶
The condition number at every line, the largest singular value over the smallest: infinite where the smallest is zero, not a number where the line was not judged.
rank
property
¶
The effective rank at every line: how many singular values are
at least the largest over limit. Zero on a line not judged.
ill
property
¶
The lines flagged: judged, with a condition number over the limit (where the effective rank is under the full rank).
Methods:¶
bands
¶
line
¶
at
¶
at(frequency: float) -> ConditioningPoint
The reading at the line nearest frequency.
Source code in src/visualdynamics/core/matrix_checks.py
describe
¶
The verdict in a sentence: where the condition number is over the limit, or that it is nowhere, or that nothing was judged.
Source code in src/visualdynamics/core/matrix_checks.py
RealizabilityPoint
dataclass
¶
RealizabilityPoint(frequency: float, eigenvalues: tuple[float, ...], asymmetry: float, rank: int, realizable: bool, tolerance: float)
The realizability of the matrix at one line: what
Realizability.at returns. eigenvalues are those of the coherence
matrix, smallest first; asymmetry is its largest departure from
Hermitian; realizable says whether the line passes.
Methods:
| Name | Description |
|---|---|
describe |
One line for a status bar. |
Methods:¶
describe
¶
One line for a status bar.
Source code in src/visualdynamics/core/matrix_checks.py
Realizability
dataclass
¶
Realizability(frequency: ndarray, coherence: ndarray, scale: ndarray, eigenvalues: ndarray, asymmetry: ndarray, negative: ndarray, repaired: ndarray, channels: tuple[str, ...], tolerance: float = REALIZABLE_TOLERANCE, keep_diagonal: bool = True, notes: tuple[str, ...] = ())
Whether a cross-spectral matrix can be produced by any set of
signals, line by line, and the nearest one that can: what
read_realizability returns.
frequency holds the lines in Hz. coherence is the coherence
matrix at every line (lines x n x n, the cross-spectral matrix
scaled by the root of its diagonal) and scale that root (lines x
n), so the cross-spectral matrix is recovered as scale_i scale_j
coherence_ij. eigenvalues (n x lines, smallest first) are those of
the coherence matrix's Hermitian part; asymmetry is its largest
departure from Hermitian at each line; negative marks lines where
an autospectrum is below zero. repaired is the coherence matrix
after the repair, the same as coherence on every line that passes.
channels names the rows; tolerance is the check's.
Methods:
| Name | Description |
|---|---|
bands |
The runs of lines that are not realizable, as (first, last) |
matrix |
The cross-spectral matrix at every line (lines x n x n), as |
pair |
(coherence before, after, phase before, after) of channels |
worst |
(i, j, line) of the cross term the repair moved most, as a |
changes |
(coherence, phase in degrees): the largest change the repair |
line |
The index of the line nearest |
at |
The reading at the line nearest |
describe |
The verdict in a sentence: realizable, or the bands that are |
Attributes:
| Name | Type | Description |
|---|---|---|
judged |
ndarray
|
The lines judged: every entry a finite number. |
smallest |
ndarray
|
The smallest eigenvalue at every line. |
largest |
ndarray
|
The largest eigenvalue at every line. |
failing |
ndarray
|
The lines judged and not realizable: an eigenvalue below minus |
realizable |
bool
|
Whether every line was judged realizable. False when no line |
rank |
ndarray
|
The rank at every line: the eigenvalues over the tolerance |
Attributes¶
failing
property
¶
The lines judged and not realizable: an eigenvalue below minus the tolerance times the largest, a departure from Hermitian over the tolerance, or a negative autospectrum.
realizable
property
¶
Whether every line was judged realizable. False when no line could be judged: a check that judged nothing has not passed.
rank
property
¶
The rank at every line: the eigenvalues over the tolerance times the largest. Zero on a line not judged.
Methods:¶
bands
¶
The runs of lines that are not realizable, as (first, last) frequencies.
matrix
¶
The cross-spectral matrix at every line (lines x n x n), as
read or, with repaired, after the repair.
Source code in src/visualdynamics/core/matrix_checks.py
pair
¶
(coherence before, after, phase before, after) of channels i
and j at every line, the phase in degrees: what the repair did
to that pair. Coherence is data.ordinary_coherence of the
matrix before and after.
Source code in src/visualdynamics/core/matrix_checks.py
worst
¶
(i, j, line) of the cross term the repair moved most, as a complex coherence entry, or None when nothing moved.
changes
¶
(coherence, phase in degrees): the largest change the repair made to any pair's coherence and to any phase, over lines where the pair's coherence is not zero after (a phase is undefined without it).
Source code in src/visualdynamics/core/matrix_checks.py
line
¶
at
¶
at(frequency: float) -> RealizabilityPoint
The reading at the line nearest frequency.
Source code in src/visualdynamics/core/matrix_checks.py
describe
¶
The verdict in a sentence: realizable, or the bands that are not and the pair the repair moves most, or that nothing was judged.
Source code in src/visualdynamics/core/matrix_checks.py
Functions:¶
channel_labels
¶
A label per (DOF, quantity) channel: the DOF, with the quantity added only where one DOF carries two channels (an accelerometer and a force gauge at one drive point). The matrix checks, the matrix comparison and the drive prediction all name their channels here.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channels
|
sequence of (str, str)
|
The channels, as (DOF, quantity). |
required |
Returns:
| Type | Description |
|---|---|
list of str
|
One label per channel. |
Source code in src/visualdynamics/core/matrix_checks.py
runs
¶
(first, last) index of each run of consecutive true flags.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
flags
|
array_like
|
Booleans, one per line. |
required |
Returns:
| Type | Description |
|---|---|
list of (int, int)
|
Each run's first and last index, inclusive. |
Source code in src/visualdynamics/core/matrix_checks.py
nearest_line
¶
The index of the line of frequency nearest value.
frf_matrix
¶
frf_matrix(frf: Any, records: Any = None, values: Any = None) -> tuple[list[tuple[str, str]], list[tuple[str, str]], ndarray, ndarray]
The records of an FRF assembled into the response-by-reference matrix they belong to, at every line.
A row is a response channel and a column a reference channel, each
named (DOF, quantity) from the record's dimension, so a drive
point's accelerometer and force gauge are not one channel. records
picks the records (all of them when omitted) and values, when
given, are their values in that order (the display units, for a
plot); otherwise the stored SI values are used. Returns (rows,
columns, matrix of lines x rows x columns, filled), where filled
says which entries a record supplied; an entry no record supplied
is zero in the matrix. The CMIF and the conditioning reading both
assemble their matrix here.
Source code in src/visualdynamics/core/matrix_checks.py
entry_channels
¶
(row channel, column channel) of one record of a spectral matrix.
A channel is (DOF, quantity), read from the record's dimension
(channel_quantities): a cross term 'acceleration*force/frequency'
runs from an acceleration channel to a force channel, so a drive
point's accelerometer and its force gauge are two channels. A
record with no reference is its own channel's autospectrum.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
Psd or Specification
|
The matrix's records. |
required |
record
|
int
|
Which record. |
required |
Returns:
| Type | Description |
|---|---|
tuple of ((str, str), (str, str))
|
The row channel and the column channel. |
Source code in src/visualdynamics/core/matrix_checks.py
matrix_entries
¶
matrix_entries(data: Any, records: Any = None, quantity: str | None = None) -> list[tuple[int, tuple[str, str], tuple[str, str]]]
Each record of a spectral matrix with the entry it holds.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
Psd or Specification
|
The matrix's records. |
required |
records
|
sequence of int
|
Which records; all of them when omitted. |
None
|
quantity
|
str
|
Keep only the records whose two channels are both of this quantity. |
None
|
Returns:
| Type | Description |
|---|---|
list of (int, (str, str), (str, str))
|
The record, its row channel and its column channel
( |
Raises:
| Type | Description |
|---|---|
ValueError
|
If two records hold one entry: which of them is the matrix is not in the data. |
Source code in src/visualdynamics/core/matrix_checks.py
mirrors_disagree
¶
Whether a cross term and its mirror, read at the same lines, are not each other's conjugate, to a part in a million of the larger, on the lines where both are numbers. A line that is not a number is left to the note that says so.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
term
|
array_like
|
The two halves of one pair, complex, one value per line. |
required |
mirror
|
array_like
|
The two halves of one pair, complex, one value per line. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True when they disagree. |
Source code in src/visualdynamics/core/matrix_checks.py
spectral_matrix
¶
spectral_matrix(psd: Any, records: Any = None, quantity: str | None = None) -> tuple[list[tuple[str, str]], ndarray, ndarray]
The records of a CSD assembled into its square matrix, at every line.
A channel is (DOF, quantity), read from each record's dimension: a
cross term 'acceleration*force/frequency' runs from an acceleration
channel to a force channel. records picks the records (all when
omitted) and quantity keeps only the records whose two channels
are both of it. Returns (channels, matrix of lines x n x n, filled),
with an entry no record supplied zero and not filled; two records
for one entry are refused (matrix_entries). The principal shapes
and the realizability and conditioning readings all assemble their
matrix here.
Source code in src/visualdynamics/core/matrix_checks.py
flagged_runs
¶
(first, last) frequency of each run of consecutive flagged lines.
Source code in src/visualdynamics/core/matrix_checks.py
condition_matrix
¶
condition_matrix(frequency: Any, matrix: Any, rows: Any, columns: Any, *, limit: float = CONDITION_LIMIT, dimension: str = UNKNOWN, kind: str = 'FRF', notes: Any = (), progress: Callable[[int, int], None] | None = None) -> Conditioning
The singular values of a matrix at every line, as a
Conditioning.
matrix is lines x rows x columns, complex, one unit throughout.
A line holding any value that is not a finite number is not judged
(its singular values are not a number) and is noted with the first
entry that holds one; so is a line where the matrix is all zero, and
a column (or, for an FRF, a row) that is zero at every line is named.
limit is the condition number lines are flagged over, more than
one. progress, when given, is told (0, core.progress.BUSY)
before the decomposition, which cannot count itself.
Source code in src/visualdynamics/core/matrix_checks.py
read_conditioning
¶
read_conditioning(data: Any, records: Any = None, *, limit: float = CONDITION_LIMIT, progress: Callable[[int, int], None] | None = None) -> Conditioning
The singular values and condition number of an FRF matrix, or of a cross-spectral matrix, at every line.
An Frf gives the plant matrix, responses by references; it needs
two references or more, since a condition number compares drives.
A Psd with cross terms gives the square cross-spectral matrix of
its channels, such as the drives' Gff. records picks the records
(all of them when omitted): the matrix they make must be complete
(a CSD term held only by its mirror is taken as the mirror's
conjugate) and in one unit. limit is the condition number lines
are flagged over. progress is passed to condition_matrix.
Raises TypeError for an object of neither kind, and ValueError for an empty selection, records in different units, an incomplete matrix, an FRF with one reference, or a CSD of one channel.
Source code in src/visualdynamics/core/matrix_checks.py
repair_coherence
¶
repair_coherence(matrix: Any, keep_diagonal: bool = True, progress: Callable[[int, int], None] | None = None) -> ndarray
The nearest realizable matrix to each Hermitian coherence matrix, in the Frobenius norm.
matrix is lines x n x n. With keep_diagonal, the diagonal is
held where it is (zero stays zero, a negative entry goes to zero)
and the nearest positive semi-definite matrix with that diagonal is
found by alternating projections with Dykstra's correction (Higham,
2002), then scaled onto the diagonal exactly, which keeps it positive
semi-definite. A line still moving after REPAIR_ITERATIONS passes
is realizable all the same, if not quite the nearest. Without it,
the negative eigenvalues are set to zero (Higham, 1988) and the
diagonal moves too. progress, when given, is told (done,
total) pass by pass, out of REPAIR_ITERATIONS; whatever it
raises stops the repair.
Source code in src/visualdynamics/core/matrix_checks.py
judge_lines
¶
judge_lines(frequency: Any, matrix: Any, channels: Any, *, tolerance: float = REALIZABLE_TOLERANCE, keep_diagonal: bool = True) -> Realizability
Whether a cross-spectral matrix is realizable at every line, with
nothing repaired and nothing noted: check_spectral_matrix without
its repair. repaired is the coherence matrix as it stands.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frequency
|
array_like
|
The lines, in Hz. |
required |
matrix
|
array_like
|
Lines x n x n, complex, any units. |
required |
channels
|
sequence
|
A label per channel. |
required |
tolerance
|
float
|
As for |
REALIZABLE_TOLERANCE
|
keep_diagonal
|
bool
|
Carried into the reading. |
True
|
Returns:
| Type | Description |
|---|---|
Realizability
|
Its |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the tolerance is not between 0 and 1, or the matrix is not one square matrix per line, or is empty. |
Source code in src/visualdynamics/core/matrix_checks.py
1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 | |
check_spectral_matrix
¶
check_spectral_matrix(frequency: Any, matrix: Any, channels: Any, *, tolerance: float = REALIZABLE_TOLERANCE, keep_diagonal: bool = True, notes: Any = (), progress: Callable[[int, int], None] | None = None) -> Realizability
Whether a cross-spectral matrix is realizable at every line, and
the nearest that is, as a Realizability.
matrix is lines x n x n, complex, any units (the check is on the
coherence matrix). A line holding a value that is not a finite
number is not judged, and is noted with the first entry that holds
one; so is a line where the matrix is zero throughout, since a
matrix of nothing says nothing about how channels move together. A
channel with no power and no cross term at any line judged is named.
Lines that fail are repaired (repair_coherence, which progress
is passed to); the rest are left exactly as they are.
Source code in src/visualdynamics/core/matrix_checks.py
1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 | |
read_realizability
¶
read_realizability(psd: Any, records: Any = None, *, tolerance: float = REALIZABLE_TOLERANCE, keep_diagonal: bool = True, progress: Callable[[int, int], None] | None = None) -> Realizability
Whether a CSD (a specification, or a measured cross-spectral matrix) is realizable at every line, and the nearest that is.
records picks the records (all of them when omitted); the matrix
they make must be complete, a term held only by its mirror being
taken as the mirror's conjugate. The channels may be of different
quantities, since the check is on the coherence matrix, which has
no units; but the records are declared in units throughout or not
at all, since a coherence of a declared autospectrum against a cross
term in whatever units a file held is not a coherence. A
specification written at breakpoints is judged at its breakpoints.
progress is passed to the repair (repair_coherence).
Raises TypeError for an object that is not a Psd, and ValueError
for an empty selection, an object with no cross terms, records some
declared in units and some not, fewer than two channels, or an
incomplete matrix.
Source code in src/visualdynamics/core/matrix_checks.py
made_realizable
¶
made_realizable(psd: Any, records: Any = None, *, tolerance: float = REALIZABLE_TOLERANCE, keep_diagonal: bool = True, progress: Callable[[int, int], None] | None = None) -> tuple[Any, Realizability]
A copy of a CSD with the matrix the picked records make repaired at every line that is not realizable, and the reading that says what moved.
Every record keeps its place, its DOFs and its units; only the
values at failing lines change, the cross terms and, without
keep_diagonal, the autospectra. A specification's limits follow an
autospectrum that moved, so its bands stay where they were in
decibels about it. progress is passed to the repair.
Source code in src/visualdynamics/core/matrix_checks.py
entries_refusal
¶
entries_refusal(channels: Any, pairs: Any, frequencies: Any, tolerance: float = REALIZABLE_TOLERANCE) -> str | None
Why a specification sheet's coherence and phase entries cannot hold together, or None when they can.
pairs is {(i, j): (coherence, phase_degrees) or None} for i <
j, as SpecificationDraft holds it. The entries do not change with
frequency and a scaling by the autospectra does not change the
verdict, so the coherence matrix they make is judged once, for every
line from the first breakpoint to the last. A pair not entered is
not judged: each largest group of channels whose pairs are all
entered is judged on its own. The reason names the channels the
failure is in, the eigenvalue, the band, and the nearest entries
that would hold.
Source code in src/visualdynamics/core/matrix_checks.py
1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 | |