## introduction

I want to work a major exercise from Wyszecki & Stiles. Actually, it will be one calculation repeated for 12 gray spectra. Given each spectrum, I will calculate the tristimulus values XYZ. (We first did this, here.)

The key is that these 12 spectra are supposed to be metameric. This exercise is interesting for three reasons:

- 10 of the 12 spectra have virtually identical XYZ values;
- I am encouraged that those virtually identical answers come from using linear algebra — without numerical integration;
- I believe that the other two spectra have typos in them — and I think I found (most of) them!

My starting point is Wyszecki & Stiles, page 784. The table heading says that the 12 spectra on that page are metameric with respect to standard illuminant D65 and the CIE 1931 standard observer.

I will show you that they are indeed metameric under D65. I will also show you that they cease to be metameric under D50.

Because I intend to change two data points (in columns 5 and 8), I am going to show you both of those spectra, as well as one typical spectrum — that is, complete data data for three of the twelve.

The gray data dictates everything else: the wavelength ranges from 400 to 700 nm, in 10 nm intervals. They are quite a varied collection of spectra:

I construct the two illuminant spectra, over the same 400-700 nm range at the same 10 nm intervals. Red is D65, blue is D50. They can be found here.

Create the A matrix, from the 1931 XYZ (i.e. xbar etc).

As usual in such cases, I will not show you all of the values — but here are the first five entries, corresponding to wavelengths 400-440 nm.

Here are the spectral reflectances for their grays 1,5,8 (with associated wavelength):

Let’s take a look at them (black, red, blue are gray 1,5,8 respectively).

## all 12 under D65

I am going to compute XYZ tristimulus values for all 12 spectra, but let’s review the calculation as applied to the first gray spectrum.

We need three things: a reflectance spectrum, an illuminant spectrum, and a color matching matrix A. In fact, we have 12 reflectance spectra — but the matrix A and the illuminant are common to all 12 computations.

Recall that we set the scale by applying the transpose A’ to the illuminant spectrum… and taking the middle number as maximum illumination:

scale65 = 1056.47 .

Then we get the reflected spectrum as the pointwise product of the illuminant and the reflectance spectra, and apply A’ to the reflected spectrum. For the first gray spectrum, I get

components = {30092.2, 31694.3, 34461.}

We recall that these three numbers are the components of the fundamental of that reflected spectrum with respect to the basis E which is dual to A’. We will use this fact later.

To get from those components to XYZ, we scale the results, dividing by the maximum illumination, that scale factor, scale 65, getting:

XYZ = {28.4836, 30.0001, 32.6189}.

Fair enough? Let’s do it for all 12 gray spectra. I get

(I am showing 4 digits; the spectra were given as percentages — if I had divided by 100, we would be looking at, e.g. .2848 .)

The Z column is either 32.61 or 32.62; with two exceptions, the other numbers are the same. That is, 10 of these 12 are exactly metameric, and two of them are a little off.

Having worked two examples from Wyszecki & Stiles (pp. 160-161 and pp. 162-163, although I only published the first), and having found typos in both, I strongly suspect that the discrepancies we see are caused by typos.

Let me get the chromaticity coordinates xy. To do that, we scale each set of XYZ to a sum of 1, and then display xy:

The two black dots represents 10 of the 12 xy pairs; the red dot, in the southwest corner, is column 5; the blue is column 8. Before I show you how to find the alleged typos, let’s demonstrate that these 12 spectra are not metameric under a D50 illuminant. That, after all, was half the purpose of these 12 spectra. (Metameric under D65 was the other half of the purpose.)

## all 12 under D50

We do the same calculation, replacing D65 by D50. This affects the scale. A’ applied to D50 yields…

{1011.5, 1050.21, 865.424}

and the middle number is the value for full illumination:

scale50 = 1050.21 .

Now we get 12 reflected spectra as the pointwise product of D50 and the 12 gray spectra, apply A’ to the reflected spectrum, and divide by the scale.

Our XYZ tristimulus values are…

From them, we get xyz by dividing each row by its sum, and the xy are:

That is:

This time, the black points are the grays’ xy coordinates under D65; the blue points are the grays’ xy coordinates under D50. We see that the grays have all moved in the same general direction, and most of them are far more scattered than the D65 coordinates.

The point is made that the grays look much different from each under D50 than under D65. Nevertheless, I am bothered by the small discrepancies under D65.

My first suspicion is that two digits have been swapped in each of gray 5 and gray 8. It will turn out that the larger error is actually that 19.69 was transcribed as 16.69.

## Finding the fundamental, and changing gray 5 and gray 8.

How the heck would we find these?

Well, the truth is that I played around with them! Afterwards, I found a calculation that would have found the large single error in gray 5. Unfortunately, it doesn’t find the correction I made to gray 8, so I suspected that gray 8 had a second, smaller error. But then the calculation that worked on the one error for gray 5 should have worked on the partially corrected gray 8 — but it didn’t! If I ever figure it all out, I’ll probably post it.

Let’s get the fundamentals of all the spectra. (We first did this here for real spectra; here for a toy example.) That is, our spectra are vectors of length 31, but the null space of the matrix A’ is 28-dimensional: those 28 dimensions do not contribute at all to the tristimulus values XYZ.

In the past I have usually computed a projection operator onto the fundamental (3D) space, but I have said that we don’t need to — because the 3 numbers from which we got XYZ were the components of the fundamental with respect to the dual basis.

So if we get the dual basis E, we can get the fundamentals as linear combinations of those basis vectors. Let’s do it this way.

We’ve gotten the dual basis before. The defining equation is

E’ A = I

(or, equivalently, A’E = I)

where I is a 3×3 identity matrix. We want to write the utterly false

,

but we know we can’t because A isn’t square, hence not remotely invertible. But we know we should replace the non-existent A^-1 by the pseudo-inverse , getting

.

As I showed you the first five rows of the A matrix, let me show you the first five rows of the E matrix:

We can check E by computing E’A and seeing if we get a 3×3 identity matrix. (We do.)

So, each row of E’ is a basis vector. For the first gray reflected spectrum, we have components…

{30092.2, 31694.3, 34461.}

so we get the fundamental as a linear combination of the 3 rows of E’.

f1 = {156.896, 479.004, 1490.98, 3205.47, 4059.74, 4149.19, 3962.11, 3173.07, 2239.23,

1671.93, 1609.87, 1951.46, 2495.85, 3000.54, 3363.45, 3601.21, 3738.5, 3750.33,

3627.93, 3365.41, 2994.1, 2528.61, 2002.13, 1436.29, 970.151, 601.997, 346.194,

182.429, 97.2525, 47.0252, 23.5583}

The black curve is the reflected spectrum for gray 1 (i.e. d65 times gray1), and the red curve is its fundamental.

Now I get all 12 fundamentals… and I plot all 12. (I did, I really did.)

They look almost identical, but let’s subtract the first fundamental from each of the others to see how close they are….

Before I do that, I should emphasize two things. **First is that we have effectively one fundamental.** That should not surprise you, at least not for very long. The XYZ values are scaled from the 3 components of the fundamental wrt the E basis.

If we want the same XYZ, then we must have the same 3 components. And if we have the same 3 components, then the vector — the spectrum — they describe, is the same linear combination of the basis vectors. Metameric spectra must have identical fundamentals (and conversely).

**Second, note the interesting fact that the common fundamental is always positive.** (OK, the graph could be slightly negative at long wavelengths, but in fact the numbers are strictly positive.) That’s nice. That’s very nice. That’s a physically realizable spectrum, without having to add any residual to it. (Recall that a residual spectrum is an element of the null space; it contributes literally nothing — literally {0,0,0} — to the computed XYZ.)

Now I’m ready to see just how close those 12 fundamenal spectra are to each other. Subtract the first fundamental from each of the others…

.

We see that only the fundamentals for 5 and 8 differ from the fundamental for gray 1 by more than . Further, the fundamental for 5 is an order of magnitude further away from gray 1 than 8 is.

But why do those two fundamentals differ in so many places (assuming that the original spectra have no more than a few typos)? Because they’re multiplied by basis vectors. That is, the components for the first two basis vectors are slightly off — but each component multiples the entire basis vector, so we see discrepancies at many wavelengths rather than at only one.

But — this is a linear calculation, and we should be able to isolate the error, if there is only one. Well, it this idea seems to work for gray 5, which can be “corrected” by changing one digit in the spectrum. But it doesn’t seem to work for gray 8 — not even after I find one plausible typo, and look for a second. I think I’ll bail on showing this to you — after all, I actually found the two “corrections” by trial-and-error.

Here are the two changes I would make. First, in gray 5, change the 17th entry (wavelength 560) from 16.69 to 19.69. Not a swap, but a match to a wrong number.

Second, in gray 8, change the 21st row (wavelength 600)… from 22.31 to 22.13, i.e. this time I swap two digits.

Now, let’s do it all again. If you want, go ahead and skip two sections, down to “the fundamental”.

## all revised spectra under D65

I am going to compute XYZ tristimulus values for all 12 spectra.

Recall that we set the scale by applying the transpose A’ to the illuminant spectrum… and taking the middle number as maximum illumination:

scale65 = 1056.47

Then we get the reflected spectrum as the pointwise product of the illuminant and the reflectance spectra, and apply A’ to the reflected spectrum. That gives us three numbers which are the components of the fundamental of each reflected spectrum with respect to the basis E which is dual to A’.

To get from those components to XYZ, we scale the results, dividing by the maximum illumination, scale65.

Fair enough? Let’s do it for all 12 gray spectra. Only two rows should change, namely rows 5 and 8.

The X and Y values are identical to 4 digits. I do seem to have fixed gray 5 and gray 8.

The Z column is still either 32.61 or 32.62.

Let me get the chromaticity coordinates xy. To do that, we scale each set of XYZ to a sum of 1, and then display xy:

There appear to be only two distinct xy pairs (Mathematica’s Union command confirms this — it finds the set union, and shows only 2 values):

Those two points are very close together. I’m not even going to plot them. They are different because Z was either 32.61 or 32.62 . (In fact, we will see these xy values later.)

## all revised under D50

We do the same calculation, replacing D65 by D50. This affects the scale. A’ applied to D50 yields… and the middle number is the value for full illumination:

scale50 = 1050.21 .

Now we get 12 reflected spectra as the pointwise product of D50 and the 12 gray spectra, apply A’ to the reflected spectrum, and divide by the scale.

Our XYZ tristimulus values are…

From them, we get xyz by dividing each set of three by their sum, and xy are:

As before, the fuzzy black point — recall that there are actually two of them, very close — is the xy coordinates under D65; the blue points are the xy coordinates under D50. We still see that the grays have all moved in the same general direction, but now all of them are far more scattered than the D65 coordinates.

## the fundamental

We really only reviewed a computation we have done before: getting from spectra to XYZ to xy. But we have now explicitly seen 12 metameric spectra: **their metamerism is characterized by their having the same XYZ values. **

Equivalently, they have the same components wrt the E basis, which is the basis dual to the A basis.

**Equivalently, they have the same fundamental.**

So. Given XYZ, we could get a reflected spectrum just by computing the fundamental, as a linear combination of the E basis vectors. It really is trivial.

There are, however, a couple of issues.

**First, there is no guarantee that the fundamnetal is physically realizable.** Let’s look at the 3 E basis spectra.

Every one of them is negative somewhere — just as the columns of A, the color matching functions, are negative somewhere — so in principle linear combinations of these three vectors can also be negative somewhere.

If the fundamental is negative, we will want to add a residual spectrum to it in order that the combination be always positive. This may be easier said than done.

**Second, we are specifying a reflected spectrum.** That’s easy enough to change: the reflectance spectrum is the reflected spectrum divided pointwise by the illuminant spectrum. That is,

reflected = illuminant * reflectance

so

reflectance = reflected / illuminant.

Third, what scattered those 12 grays under d50 was their residual spectra under d65. Not only will we get just one spectrum for all 12 under d65, but whatever residual I choose to add (and the zero vector was a possible residual), will affect what happens under a different illuminant.

Let me be clear about that. The first point is not an issue here: we have one fundamental and it is positive everywhere. That fundamental is a physically realizable spectrum — in principle, at least. If necessary I take 31 monochromatic lasers at each wavelength! But how in heck would I generate a reflected spectrum that had negative amounts of some wavelengths?

So in this case we have a possible reflected spectrum, namely the common fundamental of those 12 grays.

How would we find the reflectance spectrum corresponding to the fundamental? Divide by D65, pointwise.

new reflectance = {1.89488, 5.23502, 15.9634, 36.972, 38.701, 35.4632, 33.6342,

27.616, 19.3204, 15.367, 14.7155, 18.1026, 23.8153, 27.8602, 32.217, 34.6271,

37.385, 38.9442, 37.8699, 37.9415, 33.2678, 28.2211, 22.8293, 17.2424, 11.5908, 7.52497, 4.31663, 2.21663, 1.24205, 0.67468, 0.329027}

Here then are two reflectance spectra: red is the one we have just constructed, black is gray 1.

For comparison, here is the gray 1 reflected spectrum (black) and its fundamental (red):

You know what? We really ought to find the XYZ of that fundamental (reflectance) spectrum under d50.

Let me emphasize: do not be mislead by my sloppy terminology. The fundamental is, properly, a possible reflected spectrum under some illuminant; but there is an associated reflectance spectrum – which is not a fundamental, i.e. not in the 3D fundamental color space – and it makes sense to look at that associated reflectance spectrum under a different illuminant.

We recall the scale for d50:

scale50 = 1050.21

Take the pointwise product of this reflectance spectrum with d50, and apply A’ to that.

components = {29781.7, 31586.1, 25772.}

Divide by the scale to get XYZ.

XYZ = {28.358, 30.0761, 24.5399}

Normalize to a sum of 1 to get xyz…

xyz = {0.341769, 0.362476, 0.295755}

Recall the 12 xy for the 12 spectra under d50, and the slightly fuzzy one for the 12 spectra under d65 — and add the xy for the fundamental.

The blue points are the (corrected) 12 grays under d50; the fuzzy black point is under d65. The red point is the common fundamental under d50.

It’s sitting right over there with the other 12 grays.

Maybe I should put it this way: the residual spectra are not metameric under d50, and it’s the residual spectra that scatter the blue points. The distiction between the red and black points is the difference between the “fundamental” seen under two illuminants.

I wrote “fundamental” because I was being sloppy, deliberately. The fundamental is that of a reflected spectrum. In order to view it under a different illuminant, I have to convert it to a reflectance spectrum — and that changes it.

The fundamental of the reflectance spectrum is not the fundamental of the reflected spectrum.

I need to do one more calculation. Let’s look at one residual, rather than all of them. And I don’t know how many times I’ve forgotten to use the reflected spectrum instead of the reflectance spectrum!

To get the residual reflected spectrum, I need to subtract the fundamental from the reflected spectrum: that’s… t

hen to get the residual reflectance spectrum (so I can change illumninant), I need to divide by d65…

r = {33.2151, 38.985, 31.7766, 9.46805, 3.70895, 0.376848, -5.5942, -10.876,

-10.2704, -8.49704, -7.68547, -10.6926, -16.0853, -19.8502, -16.987, 23.4029,

31.395, 22.1158, 10.5801, -2.74148, -9.7878, -14.1311, -14.9893, -13.2224,

-9.86082, -6.67497, -4.04663, -2.07663, -1.24205, -0.66468, 0.270973}

What are the XYZ tristimulus values for this, under D65? (This is just a sanity check.)

{1.90348*10^-15, -1.38898*10^-14, -1.18386*10^-14}

Yes, zero.

Now what are its tristimulus values under d50?

{-0.695522, 0.150297, -0.714491}

Recall the XYZ tristimulus values of the fundamental under d50…

{28.358, 30.0761, 24.5399}

of residual 1 under d50…

{-0.695522, 0.150297, -0.714491}

add them (that’s the XYZ for the fundamental plus the XYZ for the residual)…

{27.6624, 30.2264, 23.8255}

and round…

{27.66, 30.23, 23.83}

and recall the XYZ values for gray 1…

{27.66, 30.23, 23.83}

Of course, we get the same XYZ values. All these operations are linear, so we get the same answer for gray 1 under d50 directly, as for the sum of the two answers for its fundamental and its residual under d50.

Not that there is any good reason to doing it that way. We have fewer computations if we work with gray 1.

But I found it very helpful to actually see the pieces.

November 6, 2012 at 10:17 am

I have been trying to understand your spectral – XYZ conversion formula, but am unable. Could you please take a moment and explain it to me? Assume my spectrophotometer has recorded the following data, how do I reach to XYZ values and or RGB. The data in question is:

0.037232 0.036242 0.040033 0.054985 0.074327 0.079029 0.076763 0.070326 0.061865 0.05216 0.042767 0.036455 0.031032 0.027289 0.026551 0.027377 0.027014 0.027413 0.033219 0.068501 0.193892 0.424054 0.642052 0.761764 0.814238 0.839155 0.855824 0.866927 0.873529 0.872115 0.870875 0.874229 0.881973 0.888872 0.892176 0.894116

Its not that am not cracking it totally, its that the colors am getting from the above formula, are not matching with what is given. For example, when I read the spectral data of a pantone and try converting it to XYZ, I get wrong color and/hence wrong L*a*b* values eventually. Could you just get me step by step how to go through the above data to arrive at a the correct

Your help will be highly appreciated.

The above Color is PANTONE RED 32C

Kind Regards

Cruize

November 6, 2012 at 4:25 pm

HI,

I don’t know anything about spectrophotometers per se, but i presume your numbers are associated with some wavelengths…. what are those wavelengths?

November 7, 2012 at 2:12 am

Rip,

Those are spectral data from a single reading, that is one batch. They are ranging from 380 to 730 at a 10n interval. So I guess they are the same values you are using for the above formula.

November 7, 2012 at 4:10 pm

what else do we need? i need the illuminant, in order to get the scale factor… we apply the middle row of A’ to the illuminant spectrum. does you spectrophotometer know the illuminant?

meantime, i’ll see what i can learn about how spectrophotometers work.

November 8, 2012 at 3:49 am

The Illuminant is D50 or daylight, at an of 2, I got the illuminant values online.

November 7, 2012 at 8:31 pm

The Illuminant is D50 or daylight, at an of 2, I got the illuminant values online.

November 10, 2012 at 9:06 am

I know what I’m going to try, when I get a little time. My guess – from reading Wikipedia! – is that the illuminant is actually equal-intensity (not D50), and the numbers you gave me are a reflectance spectrum. If so, we have all we need to compute XYZ.

You might try the calculations with these two assumptions. If this post isn’t clear, try a different post: I’ve explained and illustrated this calculation half a dozen times, and I have no idea how to say it again differently.

In the meantime, if I cannot get a red output, then you’ll have to talk to the manufacturer. I’ll post as soon as I get an answer; I hope that will be sometime this weekend.

November 10, 2012 at 2:11 pm

Hi Cruize,

I _do get_ red. i suspect that’s all the confidence you need to work it out, but keep reading.

the numbers you have are the reflectance spectrum – the fraction reflected at each wavelength.

the illuminant is effectively equal intensity (call it 100 at every wavelength) because the device works one wavelength at a time.

i recommend the example in this this post.

November 11, 2012 at 11:39 pm

Hi rip,

I think you are right, I could be low in confidence, its just that am trying a lot of options at the same time perhaps killing my momentum. I will try your suggestions and see what comes up, because if i was not clear the first, its that, from the X-Rite aIone, the values it reads confirm the required L*a*b* required to give the Red, the 528 reads read from the same batch but when I try converting the read reflectance by myself, they give wrong figures.

I have appreciated your help, infact with your knowledge I may need to contact you soon for more research.

Thank you very much

November 19, 2012 at 4:11 pm

Hi Cruize,

I have now run your data using D50 instead of equal-intensity. I still get a red color.