Finding the Isosbestic point

I need to find the isosbestic point between 20 pairs of UV spectra. This is too cumbersome to do it manually. Is there any way Igor can find the Isosbestic point between each pair automatically?
Assuming that your spectra are all measured with the same resolution you can concatenate the individual waves into a matrix and then look for a row that is a constant.

Identifying a constant row is easy in MatrixOP. Here is an example:

Suppose your data contains one constant row. You can generate such data using
make/n=(10,20) ddd=enoise(10)
ddd[5][]=ddd[5][0]
edit ddd


Finding if a row is a constant using IP7 code:
MatrixOP/o aa=equal(sumRows(abs(ddd-colRepeat(sumRows(ddd)/numcols(ddd),numcols(ddd)))),0)

Here aa will return the truth of a row being a constant.

Another possibility that is probably more efficient to calculate:
MatrixOP/O aa=equal(VarCols(ddd^t),0)^t


There are many other ways to determine if a row is constant but I hope this helps,

A.G.
WaveMetrics, Inc.
A.G.'s comments are clever and concise. However, for real-world data, measurement error and noise may cause problems. You should supplement both methods by adding a tolerance in the comparison tests. Or for the second method, finding the row with minimum variance, and returning it and the variance for your inspection would also work.
s.r.chinn wrote:
... for real-world data, measurement error and noise may cause problems. You should supplement both methods by adding a tolerance in the comparison tests.


Within MatrixOP, the floor function and a tolerance factor can be used to impose a tolerance:

MatrixOP/o dd=equal(floor((Tolerance/numcols(ddd))*sumRows(abs(ddd-colRepeat(sumRows(ddd)/numcols(ddd),numcols(ddd))))),0)

where numcols(ddd) converts the total variation to the average variation and a Tolerance of, say 100, restricts the average variation to be 0.01 or less.

Alternatively,

MatrixOP/o ee=(sumRows(abs(ddd-colRepeat(sumRows(ddd)/numcols(ddd),numcols(ddd))))/numcols(ddd))
dd = ee < .01 ? 1 : 0


would yield the same result and be slightly more legible, I think.

I don't have much experience with MatrixOP; are there easier ways to impose a tolerance?

This could also be done with

variance
MatrixOP/O ee=(VarCols(ddd^t))^t

or standard deviation
MatrixOP/O ee=sqrt((VarCols(ddd^t))^t)

depending on the desired result.
My comment is restricted to the MatrixOP expression above.
jtigor wrote:

MatrixOP/o ee=(sumRows(abs(ddd-colRepeat(sumRows(ddd)/numcols(ddd),numcols(ddd))))/numcols(ddd))
dd = ee < .01 ? 1 : 0


There is really no need for the outer-most parenthesis but since you already typed them:
MatrixOP/o ee=greater(0.01,sumRows(abs(ddd-colRepeat(sumRows(ddd)/numcols(ddd),numcols(ddd))))/numcols(ddd)))


and you can do away with the slow second line of your code.

AG
Igor wrote:
My comment is restricted to the MatrixOP expression above.

MatrixOP/o ee=greater(0.01,sumRows(abs(ddd-colRepeat(sumRows(ddd)/numcols(ddd),numcols(ddd))))/numcols(ddd)))



Ah, I looked for something like that (greater) but completely missed it. I see it's in IP6.38 as well as 7. Thanks.
jtigor wrote:


Ah, I looked for something like that (greater) but completely missed it. I see it's in IP6.38 as well as 7. Thanks.


MatrixOP has 162 functions so it is difficult to keep track. In IP7 you can execute
DisplayHelpTopic "MatrixOp Functions by Category"
which may help you find what you need.

AG