The two possible modifications are:
pre-multiplication by a transmitting filter
post-multiplication by a matrix
Both of these are optional.
If neither of these modifications is enabled, the original x
is returned.
# S3 method for colorSpec
emulate( x, y, filter=FALSE, matrix=TRUE )
a colorSpec object close to y
, as in Details.
The quantity
is the same as y
.
The specnames()
are the same as those of y
,
except that ".em"
is appended to each one.
The function attaches attribute "emulate"
,
whose value is a list containing filter
and/or A
as appropriate.
a colorSpec responder with M spectra, to be modified.
The type
must be 'responsivity.light'
or 'responsivity.material'
a colorSpec responder with N spectra, to be emulated by a modified x
.
It must have the same type
and wavelength
vector as x
enable filter pre-multiplication.
enable matrix post-multiplication.
If matrix=TRUE
then the computed matrix A
is MxN.
see the vignette Emulation of one Camera by another Camera
If filter=FALSE
and matrix=TRUE
then
the returned value is multiply(x,A)
,
where the matrix A
is computed to minimize the difference with
y
, in the least squares sense (Frobenius matrix norm).
The function ginv()
is used here.
If filter=TRUE
and matrix=FALSE
then
the returned value is product(filter,x)
,
where the object filter
is computed to minimize the difference with
y
, in the least squares sense (Frobenius matrix norm).
This calculation is fairly straightforward,
but requires that the responsivity of x
does not vanish at any wavelength.
It also requires that M=N
.
The computed filter may be unrealistic, i.e. the transmittance may be > 1.
If this happens a WARN
message is issued.
If filter=TRUE
and matrix=TRUE
then
the returned value is product(filter,multiply(x,A))
,
where (filter,A)
are chosen with the above minimization criterion.
If N=1
then we must have M=1
as well;
the calculation is trivial and the emulation is exact.
If N
\(\ge\) 2
,
the calculation is iterative - solving alternatively for
filter
and A
until convergence.
The function ginv()
is used on each iteration.
This is a bilinear optimization.
If convergence fails, it is an error and the function returns NULL
.
If convergence succeeds, there is 1 degree of freedom in the (filter,A)
pair.
If one is scaled by a positive constant, the other can be scaled by the inverse,
and the returned object is the same.
The filter is scaled so the maximum transmittance is 1.
If filter=FALSE
and matrix=FALSE
then
the original x
is returned, with a WARN
message.
wavelength
,
type
,
quantity
,
multiply
,
product
,
specnames