```
## S3 method for class 'colorSpec':
product( \ldots )
```

...

Unnamed arguments are **colorSpec** objects,
and possibly a single character string, see **Details**.
Named arguments (if any) are passed to

`resample`

.
The most important `product()`

returns a**colorSpec**object or a matrix, see**Details**. In case of a**colorSpec**object, the`organization`

is`'matrix'`

or`'vector'`

; any`extradata`

is lost. However, all terms in the product are saved in`attr(*,'sequence')`

. One can use`str`

to inspect this attribute. All terms are converted to`radiometric`

on-the-fly and the returned**colorSpec**object is also radiometric. In case of ERROR it returns`NULL`

.

- \times
- \bullet
- \mapsto

- latex
- latex
- latex

- $\times$
- ×
- $\bullet$
- •
- $\mapsto$
- ↦

- html
- html
- html

`type`

`light`

a light source
$M$ `material`

a material
$R_L$ `responsivity.light`

a light responder (aka detector)
$R_M$ `responsivity.material`

a material responder
}
It is also helpful to define a sequence of positive integers
to be `c(1,3)`

and `c(1,1,4,1,1,4,1)`

are conformable,
but `c(1,1,4,1,3,4,1)`

is not.
There are 6 types of sequences for which the product is defined:
1. `*`

- the Hadamard product.
The numbers of spectra in the terms must be conformable.
If some objects have 1 spectrum and all the others have $q$,
then the column-vector spectrums are repeated $q$ times to form a
matrix with $q$ columns.
If the numbers of spectra are not conformable,
it is an ERROR and the function returns `NULL`

.
As an example, suppose $M_1$ has 1 spectrum and $M_2$ has $q$ spectra,
and $m=2$.
Then the product is a material with $q$ spectra.
Think of an IR-blocking filter followed by the RGB filters in a 3-CCD camera.
2. `%*%`

of the transpose of the left part times and right part,
which is $p$`c(1,24,3)`

which is splittable into `c(1,24)`

and `c(3)`

.
The product matrix is 24`product()`

the location of the `scanner = product( A.1nm, 'photo', Flea2.RGB, wave='auto')`

to model a scanner that is most commonly used to scan photographs.
Other possible strings could be `'artwork'`

, `'varmaterial'`

,
or even `'slot'`

.
See the `calibrate`

the material responder separately in a customizable way.
See the `%*%`

.
The argument `wavelength`

can also be `'auto'`

or `NULL`

.
In this case the intersection of all the wavelength ranges of the objects is computed.
If the intersection is empty, it is an ERROR and the function returns `NULL`

.
The wavelength step `step.wl`

is taken to be the smallest over all the object wavelength sequences.
If the minimum `step.wl`

is less than 1 nanometer,
it is rounded off to the nearest power of 2 (e.g 1, 0.5, 0.25, ...).
Although the function signature shows the `wavelength`

, followed by more arguments,
actually they can come in any order.
The unnamed arguments are taken to be `resample`

.`wavelength`

,
`type`

,
`resample`

,
`calibrate`

,
`radiometric`

,
`step.wl`

# sequence 1. path = system.file( "extdata/filters/Midwest-SP700-2014.txt", package='colorSpec' ) blocker.IR = readSpectra( path ) product( blocker.IR, Hoya, wave='auto' ) # sequence 2. product( subset(solar.irradiance,1), atmosphere2003, blocker.IR, Hoya, wave='auto' ) # sequence 3. plumbicon = readSpectra( system.file( "extdata/cameras/plumbicon30mm.txt", package='colorSpec' ) ) product( blocker.IR, subset(Hoya,1:3), plumbicon, wave='auto' ) # sequence 4. product( D65.1nm, Flea2.RGB ) # a 1x3 matrix, no materials product( D65.1nm, neutralMaterial(0.01), Flea2.RGB, wave='auto' ) # a 1x3 matrix, 1 material path = system.file( "extdata/sources/Lumencor-SpectraX.txt", package='colorSpec' ) lumencor = readSpectra( path, wave=340:660 ) product( lumencor, Flea2.RGB, wave='auto' ) # a 7x3 matrix, no materials # sequence 5. # make an RGB scanner bluebalancer = subset(Hoya,'LB') # combine tungsten light source A.1nm with blue light-balance filter # use the string 'artwork' to mark the variable material slot scanner = product( A.1nm, bluebalancer, 'artwork', Flea2.RGB, wave='auto' ) # sequence 6. scanner = calibrate( scanner ) target = readSpectra( system.file( "extdata/targets/N130501.txt", package='colorSpec') ) product( target, scanner, wave='auto' ) # a 288x3 matrix