error in procedure for minimizing sum of square differences

Hello,

I am trying to write a procedure for finding the sum of squared differences for 2 data sets (experimental and model). However, I get an error when I try to compile the procedure. Any help on what I might be doing wrong will be appreciated.

#pragma rtGlobals=1 // Use modern global access method.
Function myOptimizeFunc(wave1,zz1)
matrixop wve5=wave1
wve5=(wave1-wave2)^2
print wve5
matrixop zz1=sum(wve5)
return zz1
print zz1
End

The error I get is "parameter not declared"

Error in Procedure:myOptimizeFunc
matrixop wve5=wave1

I tried to delete the above line and instead use Make /O /N=5 wve5. The error I get is the same as above.

Additional info: I am using Igor Pro 6.12A on Windows 7.

Thank you very much in advance for your help.
Ram
Hello Ram,

First, if you are still running IP 6.12 you should go to our web site and update to the latest version. This is a free update for you.

It seems to me that you are complicating things too much. There is no need to write a function for this. Instead, for the square magnitude of the waves wave1 and wave2 try:

MatrixOP/O aa=Sum(magsqr(wave1,wave2))


As for your own attempt, note you need to declare function arguments, i.e.,
Function myOptimizeFunc(wave1,wave2)
  Wave wave1,wave2
  // now do something like:
  MatrixOP/O aa=Sum(magsqr(wave1,wave2))
return aa[0]
End


I hope this helps,

A.G.
WaveMetrics, Inc.
Ram-

AG is correct, of course. But to answer the actual question you asked, you must declare the types of the input parameters. Your function would look something like this:
Function myOptimizeFunc(wave1,zz1)
    Wave wave1
    Wave zz1

    matrixop wve5=wave1
    wve5=(wave1-wave2)^2
    print wve5
    matrixop zz1=sum(wve5)
    return zz1
    print zz1       // execution will never get here because of the return statement before it
End

But (depending on the Igor version you are using) it still may not compile because wave2 is never declared.

I have declared zz1 as a wave because you are assigning a MatrixOp result to it. A function with two waves as input is a valid format for the object function of Optimize, but you shouldn't try to change the inputs. Optimize doesn't work that way. You take the inputs, compute some merit score, and then return the merit score as your function result.

But why do you want to use Optimize? If you are trying to fit a model to a data set, you are better off doing it with Igor's built-in curve fitting.

Optimize is not the best choice for curve fitting, unless you want to do Maximum Likelihood fitting, but that's not generally Least Squares fitting. If you want to do curve fitting with Optimize, you will write a function that's something like this:
Function LeastSquaresOptimize(w, coefs)
    Wave w
    Wave coefs      // the actual model coefficients

    Wave data           // look up your data wave.
    Duplicate data, tempmodel
    tempmodel = myModelFunction(coefs, x)   // this assumes the X values are coded in the data wave's X scaling.
    tempmodel = (tempmodel-data)^2
    return sum(tempmodel)
end


If your data are in the form of an XY pair of waves, you might use this instead:
Function LeastSquaresOptimize(w, coefs)
    Wave w
    Wave coefs      // the actual model coefficients

    Wave dataY, dataX   // look up your data wave.
    Duplicate dataY, tempmodel
    tempmodel = myModelFunction(coefs, dataX)
    tempmodel = (tempmodel-data)^2
    return sum(tempmodel)
end


I haven't tried it, so there might be problems with it. But it is at least close.

Again, you probably don't want to do this. You want to use Igor's built-in curve fitting. The manual has a whole chapter devoted to it.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
Hi,

Thank you very much for all these replies. What I am trying to do:

I have two datasets (an experimental, and a code result). I need to find a polynomial function as a function of two variables (lets say temperature and pressure) by fitting the experimental dataset. The experimental dataset consists of a bunch of values taken at different pressures and temperatures, as is the dataset obtained using a code.

May be I should just use a Global fit or a curve fit with a user-defined function.
Hello,

Thanks for all help. I tried using John's suggestion. The procedure is as follows:

Function Leastsq(w,coefs)
wave w
wave coefs
wave wave2,wave1
duplicate wave2,tempmodel
tempmodel=myFunc(coefs,wave1)
tempmodel=(tempmodel-wave2)^2
print sum(tempmodel)
return sum(tempmodel)
end

I used curve fititng to generate a user-defined function.

After I compiled the procedure, I closed the windows. But I dont even see an error message. Am I doing something wrong?

Thank you in advance for any help.
ramya.r wrote:
After I compiled the procedure, I closed the windows. But I dont even see an error message. Am I doing something wrong?

If the compile was successful, you won't see anything until you try to run the function. You would do that by invoking it on the command line, using a command something like this:
Leastsq(mydatawave, mycoefswave)

Naturally, you need to substitute the names of your actual waves for "mydatawave" and "mycoefswave".

When you do that, you should see a number printed out by the print statement in your function.

I'm still puzzled why you want to do it this way.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
Hi John,

Thanks very much for your continued help. To explain more fully what I am trying to do:

I have an experimental dataset and a code generated dataset. For 5 temperatures , I have experiemntal data for 10 pressure readings (for each temperature). I have similar values from the code. Now, I want to find a function (such as polynomial) solely as a function of temperature. To do so, I was trying to minimize the sum of squared differences for each temperature (for all pressures within that temperature). With this appraoch, I will get 5 values (minimized sum of squared differences), each value corresponding to a temperature. Then I was trying to fit a polynomial to those five values. This polynomial will then be solely a function of temp.
If I have understood you correctly, you need to form an average value for each temperature, averaging all data for a given temperature and at all pressures. Then you need to do a least-squares fit to the result.

I can think of at least three ways to go about doing that without using the Optimize operation.

1) Use the Average Waves package to get the average value for each temperature. To load the package, select Analysis->Packages->Average Waves. There is a demo experiment showing how to use it: select File->Example Experiments->Analysis->Ave, Box Plot, Percentile. Be sure to save the standard error from the averaging. Then do a curve fit to the averaged data, using the standard error as weighting.

2) Concatenate the waves using Concatenate/NP to put all the data for all pressures into a new wave, one data set after another. You will also need to create a corresponding Temperature wave with repeated values of temperature to go with the concatenated data set. Then do a curve fit to the combined data set. I prefer this to method 1) as it lets the curve fit effectively do the averaging and statistical analysis.

3) Use the Global Fit package (Analysis->Packages->Global Fit). Select each of your data sets at a given pressure and link the coefficients for the model function between the data sets. There is a demo experiment for this as well: File->Curve Fitting->Global Fit Demo. This is really just the same as method 2) but using the interface of the Global Fit package to do some of the work for you. The disadvantage is having to learn how to use the Global Fit package.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com