## introduction

(Notation: It has become my custom to use, for example, N’ to denote the transpose of N.)

This post has two purposes.

1. To show you Giorgianni & Madden’s (see bibliography) version of the calculation I first found in Glassner (see bibliography; and there is a link below).
2. To show you what happens when we change the white point — only the white point.

I want to show you Giorgianni & Madden’s version of the calculation because they do it slightly differently — they compute a transition matrix. As always, the surest way to avoid misunderstanding is to show you a calculation. You may not know why I did something, but there should be no doubt about what I did.

And I want to show you what happens when we change the white point. I talked about this at the end of the “color primary” post (okay, what I still think of as the “Glassner” post); the link is below.

I can spare you some suspense, but I’m going to do the calculation anyway.

One disadvantage of having Mathematica at my fingertips is that I can compute before I think. (There are advantages to walking around the block every so often, and they’re not just physical; it gives me a chance to think, stuck in circumstances where I cannot compute.)

Let us first review the calculation as Glassner presented it.

## review Glassner

Let’s recall his discussion of his recipe. (The original is in here.)

Let the matrix K contain the x, y, z coordinates of the three phosphors. To be specific, let the first row — there it is, K is an attitude matrix — contain the xyz coordinates for the red phosphor (so K is an attitude matrix with xyz as the new basis), and so on. Let the vector W contain the X, Y, Z components of the white point. Let G be a diagonal matrix constructed from the vector V — whatever it is. Let F = (1, 1, 1).

The key is that we assume each row of N is proportional to a row of K:

N = G K.

That is, we are planning to change the lengths of the basis vectors but not their directions. This is crucial.

It is also significant that F = (1, 1, 1), because it gives us a simple relationship between V and G:

V = FG.

We have that N maps the white point F to W (but it’s an attitude matrix, hence post-multiply):

W = FN.

Then

W = FN = F(GK) = (FG)K = VK

and finally

$V = W\ K^{-1}\$.

Having gotten there, we reverse ourselves: from W and K we compute V, then G, then N.

To be explicit, from K and W we find N as follows:

$V = W\ K^{-1}\$.

G = DiagonalMatrix[V]

N = G K.

Okay, having reviewed that calculation, let us ask: what will happen if we change the white point?

We get a new basis. Big deal. We could figure out the relationship between two new bases having different white points.

Perfectly straightforward, and that’s exactly what I did a week or so ago. And when I saw the answer, my first response was “Fascinating” — and my second response was, “Duh, of course.”

Any idea why, “Duh”?

Go back to that relationship

N = G K,

where G was a diagonal matrix. We understood that to mean we are not changing the directions of the basis vectors, just their lengths.

When we change the white point, we will have two new bases, of pairs of vectors having the same direction but different lengths.

Just as G is a diagonal matrix, so will be the transition matrix between our two new bases.

As I said, I’ll compute it anyway.

But before that, let’s look at…

Their example (on p. 384) uses different phosphors. More importantly, they use different notation. It is valuable, therefore, to work out their example so that I can clearly identify and point out the changes in notation. (One of them is non-trivial.)

The phosphors are specified by “ITU-R BT.709”.

As usual, they provide xy, we need xyz.

Here’s the red phosphor…

xy = {0.64, 0.33}

r = xyz = {0.64, 0.33, 0.03}.

The green…

xy = {0.3, 0.6}

g = xyz = {0.3, 0.6, 0.1}.

The blue…

xy = {0.15, 0.06}

b = xyz = {0.15, 0.06, 0.79}.

And the white point (which they say is, and which I recognize as, D65)…

xy = {0.3127, 0.329}

w = xyz = {0.3127, 0.329, 0.3583}.

In contrast to Glassner, they set the scale so that Y = 100 instead of 1. No big deal. Multiply by 100 and divide by the y value…

$W = 100\ w\ / w_2$

W = {95.0456, 100., 108.906}.

What we have called K is their “primary chromaticity matrix C” (I know this from seeing their C matrix):

$K = C = \left(\begin{array}{ccc} 0.64 & 0.33 & 0.03 \\ 0.3 & 0.6 & 0.1 \\ 0.15 & 0.06 & 0.79\end{array}\right)$

What we have called $V = W\ K^{-1}\$, they call p, but we agree on the computation:

V = {64.4361, 119.195, 120.321}.

They do construct a diagonal matrix, but they don’t explicitly name it or show it. No big deal. As usual, let

$G = \left(\begin{array}{ccc} 64.4361 & 0. & 0. \\ 0. & 119.195 & 0. \\ 0. & 0. & 120.321\end{array}\right)$

Finally they compute “a phosphor matrix M” as

M = C’ G = K’ G.

$M = \left(\begin{array}{ccc} 41.24 & 35.76 & 18.05 \\ 21.26 & 71.52 & 7.22 \\ 1.93 & 11.92 & 95.05\end{array}\right)$

On the other hand, our recipe called for

N = G K.

Transpose:

N’ = K’ G’ = K’ G = C’ G = M.

So if we compute N = G K by Glassner’s recipe, we should find ourselves looking at the transpose of their answer M = C’ G = K’ G.

Their M is not Glassner’s M. Do not get confused about that. Frankly, it’s very convenient that Glassner computed N first before his own M. (I don’t have to muddy the waters by actually computing Glassner’s M.) Here then is Glassner’s N:

$N = \left(\begin{array}{ccc} 41.24 & 21.26 & 1.93 \\ 35.76 & 71.52 & 11.92 \\ 18.05 & 7.22 & 95.05\end{array}\right)$

Yes. Glassner’s N is the transpose of Giorgianni & Madden’s M.

(Oh, maybe now is good time to remind you that Glassner’s N is the inverse of Glassner’s M.)

Since Glassner’s N and M are inverses, and their M is his N’, then their M is the inverse transpose of Glassner’s M. That should be no big deal; you should just write out the algebra in a way that suits you, and then be clear about what’s what. It’s the algebra that’s important, of course, not the names.

Of course, we always need to remember whether we have an attitude matrix or a transition matrix, and which way it goes (“new” and “old”).

We can recall that Glassner’s set up is that N is an attitude matrix mapping RGB to XYZ; therefore XYZ is the new basis. Therefore N’ is a transition matrix with XYZ as old components of vectors. (If you need to, hit the tag cloud for “attitude or transition matrices”.)

Confused? Check it! Apply N’ to the (“new”) components of the RGB basis vector namely (1, 0, 0). We get XYZ…

XYZ = {41.2391, 21.2639, 1.93308}

(Yes, the first column of N’; equivalently, the first row of N; equivalently, the first column of G&M’s M.)

But what we know is xyz, so… normalize that XYZ to a sum of 1…

xyz = {0.64, 0.33, 0.03}

and compare that to the xyz cooordinates of the red phosphor…

r = {0.64, 0.33, 0.03}.

They match. Good. N’ does what I expected.

Incidentally, that means G&M computed the matrix I am most interested in, whether we call it N’ or M.

Let me save N’ (as T1), the transition matrix with XYZ as old components of vectors. And let’s save G, too (as G1).

## Glassner’s recipe with white point A

(Can I call one Glassner’s recipe and the other G&M’s recipe?)

Let’s just change the white point to Standard Illumninant A. From Hunt I can read xy as…

xy = {0.4476, 0.4074}

and compute xyz:

w = xyz = {0.4476, 0.4074, 0.145}.

(We know how to compute the white point of an illuminant, but that requires my initializing the color-matching functions, and setting the A and A’ matrices…. Besides, I’ve done that, and Hunt and I agree on every white point he shows! I can safely copy them from him.)

We set the scale to 100:

$W = 100\ w / w_2$

W = {109.867, 100., 35.5916}.

We still have the same K, but $V = W\ K^{-1}\$ changes…

V = {118.944, 98.4399, 28.075}.

And G changes…

$G_2 = \left(\begin{array}{ccc} 118.944 & 0. & 0. \\ 0. & 98.4399 & 0. \\ 0. & 0. & 28.075\end{array}\right)$

I am used to writing N = G K, but I want N’, and I might as well also name T2 = N’…

$T_2 = \left(\begin{array}{ccc} 76.1242 & 29.532 & 4.21125 \\ 39.2516 & 59.0639 & 1.6845 \\ 3.56832 & 9.84399 & 22.1792\end{array}\right)$

Now I have two transition matrices, one mapping RGB d65 to XYZ and the other mapping RGB A to XYZ. What’s the transition matrix from d65 to A?

XYZ = T2 A
XYZ = T1 d65
$d65 = T_1^{-1}\ XYZ = T_1^{-1}\ T_2\ A\$;

so we compute

$T_1^{-1}\ T_2 = \left(\begin{array}{ccc} 1.84592 & 0 & 0 \\ 0 & 0.825874 & 0 \\ 0 & 0 & 0.233335\end{array}\right)$

Diagonal. (I told you so.)

I quote myself from my original (unpublished) calculation a week or two ago:

“fascinating.

of course. the basis vectors are scaled, not rotated, so a transition between white points is diagonal — just scaling.

damn.”

Now confirm that I could have computed the analagous $G_1^{-1}\ G_2\$, instead of $T_1^{-1}\ T_2\$:

$G_1^{-1}\ G_2 = \left(\begin{array}{ccc} 1.84592 & 0. & 0. \\ 0. & 0.825874 & 0. \\ 0. & 0. & 0.233335\end{array}\right)$

## closing remarks

Gorgianni & Madden refer to this calculation as a “color-primary conversion”, whence my titles.

I could say, “Move along. There’s nothing to see here.” — but that’s not true. For one thing, it confirms our original belief that N = G K is changing only the lengths of the basis vectors. (It may have been an elementary observation, but reinforcement is a good thing.)

For another, perhaps more important, it tells me that whatever the von Kries and Bradford transforms are — since about all I know is that they are not diagonal, they cannot be the result of simply changing the white point, as we just did. There’s more to them than that.

No, I’ve never really talked about them. They have to do with “chromatic adaptation”, which is the human eye coping with changes in illuminant. We now know they are more than a change-of-basis.