Curvefitter / Interpreter request.

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Curvefitter / Interpreter request.

Fred Damen
Greetings,

I have a request...

The Curvefitter can fit to an enumerated erf function, albeit, when the
given string equation is fit, or evaluated using the Interpreter, the erf
function is unknown.  Could it be that the Interpreter does understand the
erf???.

Bonus question:  Why 21 in  macro.run(21); ???

Bonus bug report, i.e., discovered due to fumble on my part.
Given the string equations:
y=a*(1-1/(1+exp(-(x-b)/c)))+d
and
cf.setOffsetMultiplySlopeParams(3,3,-1);
gives:
java.lang.ArrayinexOutOfBoundsExceptions: -1
from either setOffsetMultiplySlopeParams or doCustomFit

Thanks in Advance,

Fred

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Curvefitter / Interpreter request.

Schmid, Michael
Hi Fred,

concerning the erf: Maybe it would be better to have that as Math.erf in
the macro language, just in case someone already has a function named
"erf" in a plugin, but that's a question to Wayne.
It would be easy to implement (Functions.java, somewhere around line 378)

                else if (name.equals("erf"))
                        return IJMath.erf(arg);

Note that the rather simple erf implementation in ImageJ does not have
full machine accuracy, absolute and relative errors are below 1e-12,
however (I am not aware of a public-domain implementation of the erf
with better accuracy; if you know one, let me know  please!)

---
 > Bonus question:  Why 21 in  macro.run(21); ???
I guess you refer to the macroStartProgramCounter in CurveFitter?
I think it's because there are 20 tokens in the prefix of the macro
interpreter code (comas, brackets, etc. are counted as tokens)
"var x, a, b, c, d, e, f; function dummy() {}"
  1   2  4  6  7  9 11 13  15       16       20

---
 > y=a*(1-1/(1+exp(-(x-b)/c)))+d
 > curveFitter.setOffsetMultiplySlopeParams(3,3,-1);

For this equation, the offset is 'd', so #3, but the multiply factor is
'a', so #0, not 3.
It should be
curveFitter.setOffsetMultiplySlopeParams(3, 0, -1);

I hope that it does not cast an exception with that.

Michael
____________________________________________________________

On 03/04/2020 6:30 am, Fred Damen wrote:

> Greetings,
>
> I have a request...
>
> The Curvefitter can fit to an enumerated erf function, albeit, when the
> given string equation is fit, or evaluated using the Interpreter, the erf
> function is unknown.  Could it be that the Interpreter does understand the
> erf???.
>
> Bonus question:  Why 21 in  macro.run(21); ???
>
> Bonus bug report, i.e., discovered due to fumble on my part.
> Given the string equations:
> y=a*(1-1/(1+exp(-(x-b)/c)))+d
> and
> cf.setOffsetMultiplySlopeParams(3,3,-1);
> gives:
> java.lang.ArrayinexOutOfBoundsExceptions: -1
> from either setOffsetMultiplySlopeParams or doCustomFit
>
> Thanks in Advance,
>
> Fred
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Curvefitter / Interpreter request.

Wayne Rasband-2
In reply to this post by Fred Damen
> On Apr 3, 2020, at 12:30 AM, Fred Damen <[hidden email]> wrote:
>
> Greetings,
>
> I have a request...
>
> The Curvefitter can fit to an enumerated erf function, albeit, when the
> given string equation is fit, or evaluated using the Interpreter, the erf
> function is unknown.  Could it be that the Interpreter does understand the
> erf???.

The latest ImageJ daily build (1.52v14) adds a Math.erf(x) macro function.

-wayne

>
> Bonus question:  Why 21 in  macro.run(21); ???
>
> Bonus bug report, i.e., discovered due to fumble on my part.
> Given the string equations:
> y=a*(1-1/(1+exp(-(x-b)/c)))+d
> and
> cf.setOffsetMultiplySlopeParams(3,3,-1);
> gives:
> java.lang.ArrayinexOutOfBoundsExceptions: -1
> from either setOffsetMultiplySlopeParams or doCustomFit
>
> Thanks in Advance,
>
> Fred

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Curvefitter / Interpreter request.

Fred Damen
In reply to this post by Schmid, Michael
Greetings Michael,

The reason for my request was that doFit with CurveFitter.ERF works as
expected, but doCustomFit with "y =
a+b*erf((x-c)/d)"(CurveFitter.fList[ERF]) yields a popup error message
stating that the <erf> is unrecognized, and, then both
cf.getResultString() and cf.f(x) throw a
java.lang.ArrayIndexOutOfBoundsException: -1 exception. It would be nice
if the popup message was (instead if possible) included in the results
string, and NaN was returned, respectively. I also evaluate the the string
equations directly the same way Curvefitter does under the hood, (the
impetus for the question), and I get the same popup. Does
Interperter.setIgnoreErrors(true) just prevent this popup, i.e., can I get
the same effective nonpopup results using wasError() and
getErrorMessage().

Generally I don't report bugs that were discovered due to my fumbles, but
since I appreciate your work and I was sending the email anyways...

Thanks,

Fred

On Fri, April 3, 2020 2:49 am, Michael Schmid wrote:

> Hi Fred,
>
> concerning the erf: Maybe it would be better to have that as Math.erf in
> the macro language, just in case someone already has a function named
> "erf" in a plugin, but that's a question to Wayne.
> It would be easy to implement (Functions.java, somewhere around line 378)
>
> else if (name.equals("erf"))
> return IJMath.erf(arg);
>
> Note that the rather simple erf implementation in ImageJ does not have
> full machine accuracy, absolute and relative errors are below 1e-12,
> however (I am not aware of a public-domain implementation of the erf
> with better accuracy; if you know one, let me know  please!)
>
> ---
>  > Bonus question:  Why 21 in  macro.run(21); ???
> I guess you refer to the macroStartProgramCounter in CurveFitter?
> I think it's because there are 20 tokens in the prefix of the macro
> interpreter code (comas, brackets, etc. are counted as tokens)
> "var x, a, b, c, d, e, f; function dummy() {}"
>   1   2  4  6  7  9 11 13  15       16       20
>
> ---
>  > y=a*(1-1/(1+exp(-(x-b)/c)))+d
>  > curveFitter.setOffsetMultiplySlopeParams(3,3,-1);
>
> For this equation, the offset is 'd', so #3, but the multiply factor is
> 'a', so #0, not 3.
> It should be
> curveFitter.setOffsetMultiplySlopeParams(3, 0, -1);
>
> I hope that it does not cast an exception with that.
>
> Michael
> ____________________________________________________________
>
> On 03/04/2020 6:30 am, Fred Damen wrote:
>> Greetings,
>>
>> I have a request...
>>
>> The Curvefitter can fit to an enumerated erf function, albeit, when the
>> given string equation is fit, or evaluated using the Interpreter, the
>> erf
>> function is unknown.  Could it be that the Interpreter does understand
>> the
>> erf???.
>>
>> Bonus question:  Why 21 in  macro.run(21); ???
>>
>> Bonus bug report, i.e., discovered due to fumble on my part.
>> Given the string equations:
>> y=a*(1-1/(1+exp(-(x-b)/c)))+d
>> and
>> cf.setOffsetMultiplySlopeParams(3,3,-1);
>> gives:
>> java.lang.ArrayinexOutOfBoundsExceptions: -1
>> from either setOffsetMultiplySlopeParams or doCustomFit
>>
>> Thanks in Advance,
>>
>> Fred
>>
>> --
>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Curvefitter / Interpreter request.

Schmid, Michael
Hi Fred,

just for clarification, most of the CurveFitter's function Strings are
not usable as macro code; they are meant for humans reading them.
E.g., all the polynomials (including the linear fit) are written like this:
   "y = a+bx"       (linear fit; not "y = a+b*x")
   "y = a+bx+cx^2"  (2nd-order polynomial)
   ...
   "y = a+bx+cx^2+dx^3+ex^4+fx^5+gx^6+hx^7+ix^8"
and also the fits with a log are not macro-compatible because they are
written with 'ln', not 'log', and everything with exponentiation uses
the caret '^'.

If you would consider it helpful (and if Wayne agrees), we could add the
equivalent macro code for the CurveFitter's function types, as a
separate (public static final String) array. For the error function,
this would then be
   "y = a+b*Math.erf((x-c)/d)"

[Such macro equations would be also handy if my dream of having the Plot
class accepting macro equations for plotting functions ever becomes
true; then the CurveFitter could pass the fit parameters and equation to
the Plot, so we could see the extrapolated fit function and also have a
smooth curve when zooming in, no 'corners' due to the finite spacing of
the calculated points of the fit]

Note, however, that a fit with that macro code will not necessarily
yield the same result as what you get from the built-in function, e.g.
"Power" and "Power (linear regression)" both have the same function
   "y = a*x^b"
but they yield different results because "Power (linear regression)"
does the actual fit for
   log y = log a + b * log x


Concerning bug reports:

In my view, we should have a culture where bug reports are encouraged.
ImageJ would not be such a great piece of software without users
reporting bugs and Wayne fixing them within a few hours in most cases!

Concerning suggestions for improvements, like having the macro error
message in the Minimizer's status String, it depends a bit on the ratio
between cost and benefit, and whether someone is willing to do it.  I
fear that this one is not so easy to do...

By the way, my suspicion that the ArrayIndexOutOfBoundsException in the
CurveFitter had been caused by the incorrect
setOffsetMultiplySlopeParams arguments was wrong; it was due to the
macro Exception (and Wayne was very fast in fixing it)!


Best,

Michael
___________________________________________________________________________

On 03/04/2020 9:36 pm, Fred Damen wrote:

> Greetings Michael,
>
> The reason for my request was that doFit with CurveFitter.ERF works as
> expected, but doCustomFit with "y =
> a+b*erf((x-c)/d)"(CurveFitter.fList[ERF]) yields a popup error message
> stating that the <erf> is unrecognized, and, then both
> cf.getResultString() and cf.f(x) throw a
> java.lang.ArrayIndexOutOfBoundsException: -1 exception. It would be nice
> if the popup message was (instead if possible) included in the results
> string, and NaN was returned, respectively. I also evaluate the the string
> equations directly the same way Curvefitter does under the hood, (the
> impetus for the question), and I get the same popup. Does
> Interperter.setIgnoreErrors(true) just prevent this popup, i.e., can I get
> the same effective nonpopup results using wasError() and
> getErrorMessage().
>
> Generally I don't report bugs that were discovered due to my fumbles, but
> since I appreciate your work and I was sending the email anyways...
>
> Thanks,
>
> Fred
>
> On Fri, April 3, 2020 2:49 am, Michael Schmid wrote:
>> Hi Fred,
>>
>> concerning the erf: Maybe it would be better to have that as Math.erf in
>> the macro language, just in case someone already has a function named
>> "erf" in a plugin, but that's a question to Wayne.
>> It would be easy to implement (Functions.java, somewhere around line 378)
>>
>> else if (name.equals("erf"))
>> return IJMath.erf(arg);
>>
>> Note that the rather simple erf implementation in ImageJ does not have
>> full machine accuracy, absolute and relative errors are below 1e-12,
>> however (I am not aware of a public-domain implementation of the erf
>> with better accuracy; if you know one, let me know  please!)
>>
>> ---
>>   > Bonus question:  Why 21 in  macro.run(21); ???
>> I guess you refer to the macroStartProgramCounter in CurveFitter?
>> I think it's because there are 20 tokens in the prefix of the macro
>> interpreter code (comas, brackets, etc. are counted as tokens)
>> "var x, a, b, c, d, e, f; function dummy() {}"
>>    1   2  4  6  7  9 11 13  15       16       20
>>
>> ---
>>   > y=a*(1-1/(1+exp(-(x-b)/c)))+d
>>   > curveFitter.setOffsetMultiplySlopeParams(3,3,-1);
>>
>> For this equation, the offset is 'd', so #3, but the multiply factor is
>> 'a', so #0, not 3.
>> It should be
>> curveFitter.setOffsetMultiplySlopeParams(3, 0, -1);
>>
>> I hope that it does not cast an exception with that.
>>
>> Michael
>> ____________________________________________________________
>>
>> On 03/04/2020 6:30 am, Fred Damen wrote:
>>> Greetings,
>>>
>>> I have a request...
>>>
>>> The Curvefitter can fit to an enumerated erf function, albeit, when the
>>> given string equation is fit, or evaluated using the Interpreter, the
>>> erf
>>> function is unknown.  Could it be that the Interpreter does understand
>>> the
>>> erf???.
>>>
>>> Bonus question:  Why 21 in  macro.run(21); ???
>>>
>>> Bonus bug report, i.e., discovered due to fumble on my part.
>>> Given the string equations:
>>> y=a*(1-1/(1+exp(-(x-b)/c)))+d
>>> and
>>> cf.setOffsetMultiplySlopeParams(3,3,-1);
>>> gives:
>>> java.lang.ArrayinexOutOfBoundsExceptions: -1
>>> from either setOffsetMultiplySlopeParams or doCustomFit
>>>
>>> Thanks in Advance,
>>>
>>> Fred
>>>
>>> --
>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>>
>>
>> --
>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Curvefitter / Interpreter request.

Fred Damen
Greetings Michael,

First thanks to you and Wayne.

Your suggestion of executable macro equations would be a great help.
Unless someone beats me to it I will provide (probably Monday) a list of
string macro equations that compile and produce the same evaluated
results, i.e., not necessarily fitted results.

I stare at plots of data a lot and wonder what the equation and/or
parameters that describe that data, so I wrote a plugin that fits and/or
lets you specify the parameters and plots the results; stole the idea/code
from your PlotWindow::Data>Add Fit...  Its nice to be able to fit first
and then modify the parameters...  I will try and release the plugin soon.

Given that it is hard to predict user oops...  Is it possible to shut off
those popup error message and detect and display it through programmatic
means; is this what Interpreter wasError(), getErrorString(),
setIgnoreErrors() is for???  Does cf.getStatus() return a value that means
don't try to call the f(.) or getParams(.), etc. Getting only one popup is
ok, but, calling a routine over and over again that requires user GUI
interactions is annoying.

Again Thanks,

Fred


On Sat, April 4, 2020 11:59 am, Michael Schmid wrote:

> Hi Fred,
>
> just for clarification, most of the CurveFitter's function Strings are
> not usable as macro code; they are meant for humans reading them.
> E.g., all the polynomials (including the linear fit) are written like
> this:
>    "y = a+bx"       (linear fit; not "y = a+b*x")
>    "y = a+bx+cx^2"  (2nd-order polynomial)
>    ...
>    "y = a+bx+cx^2+dx^3+ex^4+fx^5+gx^6+hx^7+ix^8"
> and also the fits with a log are not macro-compatible because they are
> written with 'ln', not 'log', and everything with exponentiation uses
> the caret '^'.
>
> If you would consider it helpful (and if Wayne agrees), we could add the
> equivalent macro code for the CurveFitter's function types, as a
> separate (public static final String) array. For the error function,
> this would then be
>    "y = a+b*Math.erf((x-c)/d)"
>
> [Such macro equations would be also handy if my dream of having the Plot
> class accepting macro equations for plotting functions ever becomes
> true; then the CurveFitter could pass the fit parameters and equation to
> the Plot, so we could see the extrapolated fit function and also have a
> smooth curve when zooming in, no 'corners' due to the finite spacing of
> the calculated points of the fit]
>
> Note, however, that a fit with that macro code will not necessarily
> yield the same result as what you get from the built-in function, e.g.
> "Power" and "Power (linear regression)" both have the same function
>    "y = a*x^b"
> but they yield different results because "Power (linear regression)"
> does the actual fit for
>    log y = log a + b * log x
>
>
> Concerning bug reports:
>
> In my view, we should have a culture where bug reports are encouraged.
> ImageJ would not be such a great piece of software without users
> reporting bugs and Wayne fixing them within a few hours in most cases!
>
> Concerning suggestions for improvements, like having the macro error
> message in the Minimizer's status String, it depends a bit on the ratio
> between cost and benefit, and whether someone is willing to do it.  I
> fear that this one is not so easy to do...
>
> By the way, my suspicion that the ArrayIndexOutOfBoundsException in the
> CurveFitter had been caused by the incorrect
> setOffsetMultiplySlopeParams arguments was wrong; it was due to the
> macro Exception (and Wayne was very fast in fixing it)!
>
>
> Best,
>
> Michael
> ___________________________________________________________________________
>
> On 03/04/2020 9:36 pm, Fred Damen wrote:
>> Greetings Michael,
>>
>> The reason for my request was that doFit with CurveFitter.ERF works as
>> expected, but doCustomFit with "y =
>> a+b*erf((x-c)/d)"(CurveFitter.fList[ERF]) yields a popup error message
>> stating that the <erf> is unrecognized, and, then both
>> cf.getResultString() and cf.f(x) throw a
>> java.lang.ArrayIndexOutOfBoundsException: -1 exception. It would be nice
>> if the popup message was (instead if possible) included in the results
>> string, and NaN was returned, respectively. I also evaluate the the
>> string
>> equations directly the same way Curvefitter does under the hood, (the
>> impetus for the question), and I get the same popup. Does
>> Interperter.setIgnoreErrors(true) just prevent this popup, i.e., can I
>> get
>> the same effective nonpopup results using wasError() and
>> getErrorMessage().
>>
>> Generally I don't report bugs that were discovered due to my fumbles,
>> but
>> since I appreciate your work and I was sending the email anyways...
>>
>> Thanks,
>>
>> Fred
>>
>> On Fri, April 3, 2020 2:49 am, Michael Schmid wrote:
>>> Hi Fred,
>>>
>>> concerning the erf: Maybe it would be better to have that as Math.erf
>>> in
>>> the macro language, just in case someone already has a function named
>>> "erf" in a plugin, but that's a question to Wayne.
>>> It would be easy to implement (Functions.java, somewhere around line
>>> 378)
>>>
>>> else if (name.equals("erf"))
>>> return IJMath.erf(arg);
>>>
>>> Note that the rather simple erf implementation in ImageJ does not have
>>> full machine accuracy, absolute and relative errors are below 1e-12,
>>> however (I am not aware of a public-domain implementation of the erf
>>> with better accuracy; if you know one, let me know  please!)
>>>
>>> ---
>>>   > Bonus question:  Why 21 in  macro.run(21); ???
>>> I guess you refer to the macroStartProgramCounter in CurveFitter?
>>> I think it's because there are 20 tokens in the prefix of the macro
>>> interpreter code (comas, brackets, etc. are counted as tokens)
>>> "var x, a, b, c, d, e, f; function dummy() {}"
>>>    1   2  4  6  7  9 11 13  15       16       20
>>>
>>> ---
>>>   > y=a*(1-1/(1+exp(-(x-b)/c)))+d
>>>   > curveFitter.setOffsetMultiplySlopeParams(3,3,-1);
>>>
>>> For this equation, the offset is 'd', so #3, but the multiply factor is
>>> 'a', so #0, not 3.
>>> It should be
>>> curveFitter.setOffsetMultiplySlopeParams(3, 0, -1);
>>>
>>> I hope that it does not cast an exception with that.
>>>
>>> Michael
>>> ____________________________________________________________
>>>
>>> On 03/04/2020 6:30 am, Fred Damen wrote:
>>>> Greetings,
>>>>
>>>> I have a request...
>>>>
>>>> The Curvefitter can fit to an enumerated erf function, albeit, when
>>>> the
>>>> given string equation is fit, or evaluated using the Interpreter, the
>>>> erf
>>>> function is unknown.  Could it be that the Interpreter does understand
>>>> the
>>>> erf???.
>>>>
>>>> Bonus question:  Why 21 in  macro.run(21); ???
>>>>
>>>> Bonus bug report, i.e., discovered due to fumble on my part.
>>>> Given the string equations:
>>>> y=a*(1-1/(1+exp(-(x-b)/c)))+d
>>>> and
>>>> cf.setOffsetMultiplySlopeParams(3,3,-1);
>>>> gives:
>>>> java.lang.ArrayinexOutOfBoundsExceptions: -1
>>>> from either setOffsetMultiplySlopeParams or doCustomFit
>>>>
>>>> Thanks in Advance,
>>>>
>>>> Fred
>>>>
>>>> --
>>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>>>
>>>
>>> --
>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>>
>>
>> --
>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Curvefitter / Interpreter request.

Fred Damen
Greetings,

Here is the compilable list of equations that I promised.  Most evaluate
as strings the same as the enumerated equations.  I did not critique the
ability of the string equations to fit the same as the enumerated
equations.  I do not know what a RODBARD2 is and it is not a standard 'y =
' string equations and it references y before it defines it...  POWER
refuses to fit when x==0, which seems odd since it is generally assumed
that 0^anything is 0.  Also the string equation evaluation only defines
variables up to 'f' whereas POLY8 uses up to 'i'.

Thanks in Advance,

Fred


    /** Equations of the built-in fit functions */
    public static final String[] fList = {
    "y = a+b*x",                                           // STRAIGHT_LINE
    "y = a+b*x+c*pow(x,2)",                                     // POLY2
    "y = a+b*x+c*pow(x,2)+d*pow(x,3)",                               // POLY3
    "y = a+b*x+c*pow(x,2)+d*pow(x,3)+e*pow(x,4)",                        
// POLY4
    "y = a*exp(b*x)",                                      // EXPONENTIAL
    "y = a*pow(x,b)",                                           // POWER
    "y = a*log(b*x)",                                       // LOG
    "y = d+(a-d)/(1+pow(x/c,b))",                             // RODBARD
    "y = b*pow(x-a,c)*exp(-(x-a)/d)",                         //
GAMMA_VARIATE
    "y = a+b*log(x-c)",                                     // LOG2
    "x = d+(a-d)/(1+pow(y/c,b)) [y = c*pow((x-a)/(d-x),1/b)]", // RODBARD2
    "y = a*exp(-b*x) + c",                                 // EXP_WITH_OFFSET
    "y = a+(b-a)*exp(-(x-c)*(x-c)/(2*d*d))",             // GAUSSIAN
    "y = a*(1-exp(-b*x)) + c",                             // EXP_RECOVERY
    "y = c*pow((x-a)/(d-x),1/b)",                           // INV_RODBARD
    "y = a*exp(b*x)",                                      // EXP_REGRESSION
    "y = a*pow(x,b)",                                           //
POWER_REGRESSION
    "y = a+b*x+c*pow(x,2)+d*pow(x,3)+e*pow(x,4)+f*pow(x,5)",              
    // POLY5
    "y = a+b*x+c*pow(x,2)+d*pow(x,3)+e*pow(x,4)+f*pow(x,5)+g*pow(x,6)",  
         // POLY6
    "y =
a+b*x+c*pow(x,2)+d*pow(x,3)+e*pow(x,4)+f*pow(x,5)+g*pow(x,6)+h*pow(x,7)",
      // POLY7
    "y =
a+b*x+c*pow(x,2)+d*pow(x,3)+e*pow(x,4)+f*pow(x,5)+g*pow(x,6)+h*pow(x,7)+i*pow(x,8)",
// POLY8
    "y = a*exp(-(x-b)*(x-b)/(2*c*c))",                    //GAUSSIAN_NOOFFSET
    "y = a*(1-exp(-b*x))",                                
//EXP_RECOVERY_NOOFFSET
    "y = a*pow(1-exp(-b*x),c)",                               //CHAPMAN
    "y = a+b*Math.erf((x-c)/d)"                                 //ERF;
note that the c parameter is sqrt2 times the Gaussian
    };


On Sat, April 4, 2020 3:32 pm, Fred Damen wrote:

> Greetings Michael,
>
> First thanks to you and Wayne.
>
> Your suggestion of executable macro equations would be a great help.
> Unless someone beats me to it I will provide (probably Monday) a list of
> string macro equations that compile and produce the same evaluated
> results, i.e., not necessarily fitted results.
>
> I stare at plots of data a lot and wonder what the equation and/or
> parameters that describe that data, so I wrote a plugin that fits and/or
> lets you specify the parameters and plots the results; stole the idea/code
> from your PlotWindow::Data>Add Fit...  Its nice to be able to fit first
> and then modify the parameters...  I will try and release the plugin soon.
>
> Given that it is hard to predict user oops...  Is it possible to shut off
> those popup error message and detect and display it through programmatic
> means; is this what Interpreter wasError(), getErrorString(),
> setIgnoreErrors() is for???  Does cf.getStatus() return a value that means
> don't try to call the f(.) or getParams(.), etc. Getting only one popup is
> ok, but, calling a routine over and over again that requires user GUI
> interactions is annoying.
>
> Again Thanks,
>
> Fred
>
>
> On Sat, April 4, 2020 11:59 am, Michael Schmid wrote:
>> Hi Fred,
>>
>> just for clarification, most of the CurveFitter's function Strings are
>> not usable as macro code; they are meant for humans reading them.
>> E.g., all the polynomials (including the linear fit) are written like
>> this:
>>    "y = a+bx"       (linear fit; not "y = a+b*x")
>>    "y = a+bx+cx^2"  (2nd-order polynomial)
>>    ...
>>    "y = a+bx+cx^2+dx^3+ex^4+fx^5+gx^6+hx^7+ix^8"
>> and also the fits with a log are not macro-compatible because they are
>> written with 'ln', not 'log', and everything with exponentiation uses
>> the caret '^'.
>>
>> If you would consider it helpful (and if Wayne agrees), we could add the
>> equivalent macro code for the CurveFitter's function types, as a
>> separate (public static final String) array. For the error function,
>> this would then be
>>    "y = a+b*Math.erf((x-c)/d)"
>>
>> [Such macro equations would be also handy if my dream of having the Plot
>> class accepting macro equations for plotting functions ever becomes
>> true; then the CurveFitter could pass the fit parameters and equation to
>> the Plot, so we could see the extrapolated fit function and also have a
>> smooth curve when zooming in, no 'corners' due to the finite spacing of
>> the calculated points of the fit]
>>
>> Note, however, that a fit with that macro code will not necessarily
>> yield the same result as what you get from the built-in function, e.g.
>> "Power" and "Power (linear regression)" both have the same function
>>    "y = a*x^b"
>> but they yield different results because "Power (linear regression)"
>> does the actual fit for
>>    log y = log a + b * log x
>>
>>
>> Concerning bug reports:
>>
>> In my view, we should have a culture where bug reports are encouraged.
>> ImageJ would not be such a great piece of software without users
>> reporting bugs and Wayne fixing them within a few hours in most cases!
>>
>> Concerning suggestions for improvements, like having the macro error
>> message in the Minimizer's status String, it depends a bit on the ratio
>> between cost and benefit, and whether someone is willing to do it.  I
>> fear that this one is not so easy to do...
>>
>> By the way, my suspicion that the ArrayIndexOutOfBoundsException in the
>> CurveFitter had been caused by the incorrect
>> setOffsetMultiplySlopeParams arguments was wrong; it was due to the
>> macro Exception (and Wayne was very fast in fixing it)!
>>
>>
>> Best,
>>
>> Michael
>> ___________________________________________________________________________
>>
>> On 03/04/2020 9:36 pm, Fred Damen wrote:
>>> Greetings Michael,
>>>
>>> The reason for my request was that doFit with CurveFitter.ERF works as
>>> expected, but doCustomFit with "y =
>>> a+b*erf((x-c)/d)"(CurveFitter.fList[ERF]) yields a popup error message
>>> stating that the <erf> is unrecognized, and, then both
>>> cf.getResultString() and cf.f(x) throw a
>>> java.lang.ArrayIndexOutOfBoundsException: -1 exception. It would be
>>> nice
>>> if the popup message was (instead if possible) included in the results
>>> string, and NaN was returned, respectively. I also evaluate the the
>>> string
>>> equations directly the same way Curvefitter does under the hood, (the
>>> impetus for the question), and I get the same popup. Does
>>> Interperter.setIgnoreErrors(true) just prevent this popup, i.e., can I
>>> get
>>> the same effective nonpopup results using wasError() and
>>> getErrorMessage().
>>>
>>> Generally I don't report bugs that were discovered due to my fumbles,
>>> but
>>> since I appreciate your work and I was sending the email anyways...
>>>
>>> Thanks,
>>>
>>> Fred
>>>
>>> On Fri, April 3, 2020 2:49 am, Michael Schmid wrote:
>>>> Hi Fred,
>>>>
>>>> concerning the erf: Maybe it would be better to have that as Math.erf
>>>> in
>>>> the macro language, just in case someone already has a function named
>>>> "erf" in a plugin, but that's a question to Wayne.
>>>> It would be easy to implement (Functions.java, somewhere around line
>>>> 378)
>>>>
>>>> else if (name.equals("erf"))
>>>> return IJMath.erf(arg);
>>>>
>>>> Note that the rather simple erf implementation in ImageJ does not have
>>>> full machine accuracy, absolute and relative errors are below 1e-12,
>>>> however (I am not aware of a public-domain implementation of the erf
>>>> with better accuracy; if you know one, let me know  please!)
>>>>
>>>> ---
>>>>   > Bonus question:  Why 21 in  macro.run(21); ???
>>>> I guess you refer to the macroStartProgramCounter in CurveFitter?
>>>> I think it's because there are 20 tokens in the prefix of the macro
>>>> interpreter code (comas, brackets, etc. are counted as tokens)
>>>> "var x, a, b, c, d, e, f; function dummy() {}"
>>>>    1   2  4  6  7  9 11 13  15       16       20
>>>>
>>>> ---
>>>>   > y=a*(1-1/(1+exp(-(x-b)/c)))+d
>>>>   > curveFitter.setOffsetMultiplySlopeParams(3,3,-1);
>>>>
>>>> For this equation, the offset is 'd', so #3, but the multiply factor
>>>> is
>>>> 'a', so #0, not 3.
>>>> It should be
>>>> curveFitter.setOffsetMultiplySlopeParams(3, 0, -1);
>>>>
>>>> I hope that it does not cast an exception with that.
>>>>
>>>> Michael
>>>> ____________________________________________________________
>>>>
>>>> On 03/04/2020 6:30 am, Fred Damen wrote:
>>>>> Greetings,
>>>>>
>>>>> I have a request...
>>>>>
>>>>> The Curvefitter can fit to an enumerated erf function, albeit, when
>>>>> the
>>>>> given string equation is fit, or evaluated using the Interpreter, the
>>>>> erf
>>>>> function is unknown.  Could it be that the Interpreter does
>>>>> understand
>>>>> the
>>>>> erf???.
>>>>>
>>>>> Bonus question:  Why 21 in  macro.run(21); ???
>>>>>
>>>>> Bonus bug report, i.e., discovered due to fumble on my part.
>>>>> Given the string equations:
>>>>> y=a*(1-1/(1+exp(-(x-b)/c)))+d
>>>>> and
>>>>> cf.setOffsetMultiplySlopeParams(3,3,-1);
>>>>> gives:
>>>>> java.lang.ArrayinexOutOfBoundsExceptions: -1
>>>>> from either setOffsetMultiplySlopeParams or doCustomFit
>>>>>
>>>>> Thanks in Advance,
>>>>>
>>>>> Fred
>>>>>
>>>>> --
>>>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>>>>
>>>>
>>>> --
>>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>>>
>>>
>>> --
>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>>
>>
>> --
>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Curvefitter / Interpreter request.

Schmid, Michael
Hi Fred,

it's already there in ImageJ 1.52v17:

In a macro, Fit.getEquation(index, name, formula, macrocode) will give
you the macro code for the Fit type with the given index (all arguments
except 'index' are output). The 'macrocode' parameter is optional. This
is based on the previous Fit.getEquation(index, name, formula) call.

In Java, you have a public CurveFitter.fMacro array with these
equations, and a getMacroCode() function.

The polynomials don't use Math.pow but multiplication, e.g.
   "y = a+x*(b+x*(c+x*(d+x*e)))"
which is Horner's method applied to
   y = a+bx+cx^2+dx^3+ex^4

RODBARD2 is "Rodbard NIH Image", where x is fitted as a function of y:
   x = d+(a-d)/(1+(y/c)^b)

The macro code is for y as a function of x, however, to make it
compatible with the others, using the inverse function
   "y = c*Math.pow((x-a)/(d-x),1/b)"

I think that there is no point in using the macro code as a custom fit
equation, the built-in fits are much faster than doing it with the macro
code. This is not only because function evaluation is faster in Java
than in the macro interpreter but also because most of the built-in fits
eliminate one or two parameters by linear regression. The resulting fit
with fewer parameters is also much more likely to achieve the correct
result. E.g., fitting the high-order polynomials is much more likely to
fail when really fitting all parameters; even with elimination of two
fit parameters the 8th-order polynomials work reasonably well only if
the x values are roughly centered around 0. When simply using the macro
code (where no parameters are eliminated), it will be quite unlikely to
get a correct fit of an 8th-order polynomial. This is because the ImageJ
Minimizer does not use derivatives (so it can also handle discontinuous
functions, etc.), and it is very difficult to handle a large number of
correlated parameters with such minimizers.


Michael
______________________________________________________________



On 08/04/2020 6:11 am, Fred Damen wrote:

> Greetings,
>
> Here is the compilable list of equations that I promised.  Most evaluate
> as strings the same as the enumerated equations.  I did not critique the
> ability of the string equations to fit the same as the enumerated
> equations.  I do not know what a RODBARD2 is and it is not a standard 'y =
> ' string equations and it references y before it defines it...  POWER
> refuses to fit when x==0, which seems odd since it is generally assumed
> that 0^anything is 0.  Also the string equation evaluation only defines
> variables up to 'f' whereas POLY8 uses up to 'i'.
>
> Thanks in Advance,
>
> Fred
>
>
>      /** Equations of the built-in fit functions */
>      public static final String[] fList = {
>      "y = a+b*x",                                           // STRAIGHT_LINE
>      "y = a+b*x+c*pow(x,2)",                                     // POLY2
>      "y = a+b*x+c*pow(x,2)+d*pow(x,3)",                               // POLY3
>      "y = a+b*x+c*pow(x,2)+d*pow(x,3)+e*pow(x,4)",
> // POLY4
>      "y = a*exp(b*x)",                                      // EXPONENTIAL
>      "y = a*pow(x,b)",                                           // POWER
>      "y = a*log(b*x)",                                       // LOG
>      "y = d+(a-d)/(1+pow(x/c,b))",                             // RODBARD
>      "y = b*pow(x-a,c)*exp(-(x-a)/d)",                         //
> GAMMA_VARIATE
>      "y = a+b*log(x-c)",                                     // LOG2
>      "x = d+(a-d)/(1+pow(y/c,b)) [y = c*pow((x-a)/(d-x),1/b)]", // RODBARD2
>      "y = a*exp(-b*x) + c",                                 // EXP_WITH_OFFSET
>      "y = a+(b-a)*exp(-(x-c)*(x-c)/(2*d*d))",             // GAUSSIAN
>      "y = a*(1-exp(-b*x)) + c",                             // EXP_RECOVERY
>      "y = c*pow((x-a)/(d-x),1/b)",                           // INV_RODBARD
>      "y = a*exp(b*x)",                                      // EXP_REGRESSION
>      "y = a*pow(x,b)",                                           //
> POWER_REGRESSION
>      "y = a+b*x+c*pow(x,2)+d*pow(x,3)+e*pow(x,4)+f*pow(x,5)",
>      // POLY5
>      "y = a+b*x+c*pow(x,2)+d*pow(x,3)+e*pow(x,4)+f*pow(x,5)+g*pow(x,6)",
>           // POLY6
>      "y =
> a+b*x+c*pow(x,2)+d*pow(x,3)+e*pow(x,4)+f*pow(x,5)+g*pow(x,6)+h*pow(x,7)",
>        // POLY7
>      "y =
> a+b*x+c*pow(x,2)+d*pow(x,3)+e*pow(x,4)+f*pow(x,5)+g*pow(x,6)+h*pow(x,7)+i*pow(x,8)",
> // POLY8
>      "y = a*exp(-(x-b)*(x-b)/(2*c*c))",                    //GAUSSIAN_NOOFFSET
>      "y = a*(1-exp(-b*x))",
> //EXP_RECOVERY_NOOFFSET
>      "y = a*pow(1-exp(-b*x),c)",                               //CHAPMAN
>      "y = a+b*Math.erf((x-c)/d)"                                 //ERF;
> note that the c parameter is sqrt2 times the Gaussian
>      };
>
>
> On Sat, April 4, 2020 3:32 pm, Fred Damen wrote:
>> Greetings Michael,
>>
>> First thanks to you and Wayne.
>>
>> Your suggestion of executable macro equations would be a great help.
>> Unless someone beats me to it I will provide (probably Monday) a list of
>> string macro equations that compile and produce the same evaluated
>> results, i.e., not necessarily fitted results.
>>
>> I stare at plots of data a lot and wonder what the equation and/or
>> parameters that describe that data, so I wrote a plugin that fits and/or
>> lets you specify the parameters and plots the results; stole the idea/code
>> from your PlotWindow::Data>Add Fit...  Its nice to be able to fit first
>> and then modify the parameters...  I will try and release the plugin soon.
>>
>> Given that it is hard to predict user oops...  Is it possible to shut off
>> those popup error message and detect and display it through programmatic
>> means; is this what Interpreter wasError(), getErrorString(),
>> setIgnoreErrors() is for???  Does cf.getStatus() return a value that means
>> don't try to call the f(.) or getParams(.), etc. Getting only one popup is
>> ok, but, calling a routine over and over again that requires user GUI
>> interactions is annoying.
>>
>> Again Thanks,
>>
>> Fred
>>
>>
>> On Sat, April 4, 2020 11:59 am, Michael Schmid wrote:
>>> Hi Fred,
>>>
>>> just for clarification, most of the CurveFitter's function Strings are
>>> not usable as macro code; they are meant for humans reading them.
>>> E.g., all the polynomials (including the linear fit) are written like
>>> this:
>>>     "y = a+bx"       (linear fit; not "y = a+b*x")
>>>     "y = a+bx+cx^2"  (2nd-order polynomial)
>>>     ...
>>>     "y = a+bx+cx^2+dx^3+ex^4+fx^5+gx^6+hx^7+ix^8"
>>> and also the fits with a log are not macro-compatible because they are
>>> written with 'ln', not 'log', and everything with exponentiation uses
>>> the caret '^'.
>>>
>>> If you would consider it helpful (and if Wayne agrees), we could add the
>>> equivalent macro code for the CurveFitter's function types, as a
>>> separate (public static final String) array. For the error function,
>>> this would then be
>>>     "y = a+b*Math.erf((x-c)/d)"
>>>
>>> [Such macro equations would be also handy if my dream of having the Plot
>>> class accepting macro equations for plotting functions ever becomes
>>> true; then the CurveFitter could pass the fit parameters and equation to
>>> the Plot, so we could see the extrapolated fit function and also have a
>>> smooth curve when zooming in, no 'corners' due to the finite spacing of
>>> the calculated points of the fit]
>>>
>>> Note, however, that a fit with that macro code will not necessarily
>>> yield the same result as what you get from the built-in function, e.g.
>>> "Power" and "Power (linear regression)" both have the same function
>>>     "y = a*x^b"
>>> but they yield different results because "Power (linear regression)"
>>> does the actual fit for
>>>     log y = log a + b * log x
>>>
>>>
>>> Concerning bug reports:
>>>
>>> In my view, we should have a culture where bug reports are encouraged.
>>> ImageJ would not be such a great piece of software without users
>>> reporting bugs and Wayne fixing them within a few hours in most cases!
>>>
>>> Concerning suggestions for improvements, like having the macro error
>>> message in the Minimizer's status String, it depends a bit on the ratio
>>> between cost and benefit, and whether someone is willing to do it.  I
>>> fear that this one is not so easy to do...
>>>
>>> By the way, my suspicion that the ArrayIndexOutOfBoundsException in the
>>> CurveFitter had been caused by the incorrect
>>> setOffsetMultiplySlopeParams arguments was wrong; it was due to the
>>> macro Exception (and Wayne was very fast in fixing it)!
>>>
>>>
>>> Best,
>>>
>>> Michael
>>> ___________________________________________________________________________
>>>
>>> On 03/04/2020 9:36 pm, Fred Damen wrote:
>>>> Greetings Michael,
>>>>
>>>> The reason for my request was that doFit with CurveFitter.ERF works as
>>>> expected, but doCustomFit with "y =
>>>> a+b*erf((x-c)/d)"(CurveFitter.fList[ERF]) yields a popup error message
>>>> stating that the <erf> is unrecognized, and, then both
>>>> cf.getResultString() and cf.f(x) throw a
>>>> java.lang.ArrayIndexOutOfBoundsException: -1 exception. It would be
>>>> nice
>>>> if the popup message was (instead if possible) included in the results
>>>> string, and NaN was returned, respectively. I also evaluate the the
>>>> string
>>>> equations directly the same way Curvefitter does under the hood, (the
>>>> impetus for the question), and I get the same popup. Does
>>>> Interperter.setIgnoreErrors(true) just prevent this popup, i.e., can I
>>>> get
>>>> the same effective nonpopup results using wasError() and
>>>> getErrorMessage().
>>>>
>>>> Generally I don't report bugs that were discovered due to my fumbles,
>>>> but
>>>> since I appreciate your work and I was sending the email anyways...
>>>>
>>>> Thanks,
>>>>
>>>> Fred
>>>>
>>>> On Fri, April 3, 2020 2:49 am, Michael Schmid wrote:
>>>>> Hi Fred,
>>>>>
>>>>> concerning the erf: Maybe it would be better to have that as Math.erf
>>>>> in
>>>>> the macro language, just in case someone already has a function named
>>>>> "erf" in a plugin, but that's a question to Wayne.
>>>>> It would be easy to implement (Functions.java, somewhere around line
>>>>> 378)
>>>>>
>>>>> else if (name.equals("erf"))
>>>>> return IJMath.erf(arg);
>>>>>
>>>>> Note that the rather simple erf implementation in ImageJ does not have
>>>>> full machine accuracy, absolute and relative errors are below 1e-12,
>>>>> however (I am not aware of a public-domain implementation of the erf
>>>>> with better accuracy; if you know one, let me know  please!)
>>>>>
>>>>> ---
>>>>>    > Bonus question:  Why 21 in  macro.run(21); ???
>>>>> I guess you refer to the macroStartProgramCounter in CurveFitter?
>>>>> I think it's because there are 20 tokens in the prefix of the macro
>>>>> interpreter code (comas, brackets, etc. are counted as tokens)
>>>>> "var x, a, b, c, d, e, f; function dummy() {}"
>>>>>     1   2  4  6  7  9 11 13  15       16       20
>>>>>
>>>>> ---
>>>>>    > y=a*(1-1/(1+exp(-(x-b)/c)))+d
>>>>>    > curveFitter.setOffsetMultiplySlopeParams(3,3,-1);
>>>>>
>>>>> For this equation, the offset is 'd', so #3, but the multiply factor
>>>>> is
>>>>> 'a', so #0, not 3.
>>>>> It should be
>>>>> curveFitter.setOffsetMultiplySlopeParams(3, 0, -1);
>>>>>
>>>>> I hope that it does not cast an exception with that.
>>>>>
>>>>> Michael
>>>>> ____________________________________________________________
>>>>>
>>>>> On 03/04/2020 6:30 am, Fred Damen wrote:
>>>>>> Greetings,
>>>>>>
>>>>>> I have a request...
>>>>>>
>>>>>> The Curvefitter can fit to an enumerated erf function, albeit, when
>>>>>> the
>>>>>> given string equation is fit, or evaluated using the Interpreter, the
>>>>>> erf
>>>>>> function is unknown.  Could it be that the Interpreter does
>>>>>> understand
>>>>>> the
>>>>>> erf???.
>>>>>>
>>>>>> Bonus question:  Why 21 in  macro.run(21); ???
>>>>>>
>>>>>> Bonus bug report, i.e., discovered due to fumble on my part.
>>>>>> Given the string equations:
>>>>>> y=a*(1-1/(1+exp(-(x-b)/c)))+d
>>>>>> and
>>>>>> cf.setOffsetMultiplySlopeParams(3,3,-1);
>>>>>> gives:
>>>>>> java.lang.ArrayinexOutOfBoundsExceptions: -1
>>>>>> from either setOffsetMultiplySlopeParams or doCustomFit
>>>>>>
>>>>>> Thanks in Advance,
>>>>>>
>>>>>> Fred
>>>>>>
>>>>>> --
>>>>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>>>>>
>>>>>
>>>>> --
>>>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>>>>
>>>>
>>>> --
>>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>>>
>>>
>>> --
>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>>
>>
>> --
>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Curvefitter / Interpreter request.

Fred Damen
Greetings Michael,

Sorry, did not see an announcement for this update.

My desire is not to replace the enumerated equation fitting with string
equation fitting.  What I need is the ability to plot the equations with a
given set of parameters, where it is nice and/or essential to start the
parameters at a reasonable starting point.  It is helpful that after the
fit the equation can be directly reevaluated at the fitted parameters and
get the same exact same results, i.e., the starting point. From there I
can muck with the parameters and equation(s) and see how this effects the
validity of the parameters/equations to the physical properties that the
data is supposed to represent.

I collect data under assumed conditions and given my understanding of the
underlying physics and physiology, I think I know what the data should be
telling me.  Given the wishy-washy nature of the previous statement the
precision of the CurveFitter is only one of the issues...

Thanks for the feedback,

Fred


On Wed, April 8, 2020 1:17 pm, Michael Schmid wrote:

> Hi Fred,
>
> it's already there in ImageJ 1.52v17:
>
> In a macro, Fit.getEquation(index, name, formula, macrocode) will give
> you the macro code for the Fit type with the given index (all arguments
> except 'index' are output). The 'macrocode' parameter is optional. This
> is based on the previous Fit.getEquation(index, name, formula) call.
>
> In Java, you have a public CurveFitter.fMacro array with these
> equations, and a getMacroCode() function.
>
> The polynomials don't use Math.pow but multiplication, e.g.
>    "y = a+x*(b+x*(c+x*(d+x*e)))"
> which is Horner's method applied to
>    y = a+bx+cx^2+dx^3+ex^4
>
> RODBARD2 is "Rodbard NIH Image", where x is fitted as a function of y:
>    x = d+(a-d)/(1+(y/c)^b)
>
> The macro code is for y as a function of x, however, to make it
> compatible with the others, using the inverse function
>    "y = c*Math.pow((x-a)/(d-x),1/b)"
>
> I think that there is no point in using the macro code as a custom fit
> equation, the built-in fits are much faster than doing it with the macro
> code. This is not only because function evaluation is faster in Java
> than in the macro interpreter but also because most of the built-in fits
> eliminate one or two parameters by linear regression. The resulting fit
> with fewer parameters is also much more likely to achieve the correct
> result. E.g., fitting the high-order polynomials is much more likely to
> fail when really fitting all parameters; even with elimination of two
> fit parameters the 8th-order polynomials work reasonably well only if
> the x values are roughly centered around 0. When simply using the macro
> code (where no parameters are eliminated), it will be quite unlikely to
> get a correct fit of an 8th-order polynomial. This is because the ImageJ
> Minimizer does not use derivatives (so it can also handle discontinuous
> functions, etc.), and it is very difficult to handle a large number of
> correlated parameters with such minimizers.
>
>
> Michael
> ______________________________________________________________
>
>
>
> On 08/04/2020 6:11 am, Fred Damen wrote:
>> Greetings,
>>
>> Here is the compilable list of equations that I promised.  Most evaluate
>> as strings the same as the enumerated equations.  I did not critique the
>> ability of the string equations to fit the same as the enumerated
>> equations.  I do not know what a RODBARD2 is and it is not a standard 'y
>> =
>> ' string equations and it references y before it defines it...  POWER
>> refuses to fit when x==0, which seems odd since it is generally assumed
>> that 0^anything is 0.  Also the string equation evaluation only defines
>> variables up to 'f' whereas POLY8 uses up to 'i'.
>>
>> Thanks in Advance,
>>
>> Fred
>>
>>
>>      /** Equations of the built-in fit functions */
>>      public static final String[] fList = {
>>      "y = a+b*x",                                           //
>> STRAIGHT_LINE
>>      "y = a+b*x+c*pow(x,2)",                                     //
>> POLY2
>>      "y = a+b*x+c*pow(x,2)+d*pow(x,3)",                               //
>> POLY3
>>      "y = a+b*x+c*pow(x,2)+d*pow(x,3)+e*pow(x,4)",
>> // POLY4
>>      "y = a*exp(b*x)",                                      //
>> EXPONENTIAL
>>      "y = a*pow(x,b)",                                           //
>> POWER
>>      "y = a*log(b*x)",                                       // LOG
>>      "y = d+(a-d)/(1+pow(x/c,b))",                             //
>> RODBARD
>>      "y = b*pow(x-a,c)*exp(-(x-a)/d)",                         //
>> GAMMA_VARIATE
>>      "y = a+b*log(x-c)",                                     // LOG2
>>      "x = d+(a-d)/(1+pow(y/c,b)) [y = c*pow((x-a)/(d-x),1/b)]", //
>> RODBARD2
>>      "y = a*exp(-b*x) + c",                                 //
>> EXP_WITH_OFFSET
>>      "y = a+(b-a)*exp(-(x-c)*(x-c)/(2*d*d))",             // GAUSSIAN
>>      "y = a*(1-exp(-b*x)) + c",                             //
>> EXP_RECOVERY
>>      "y = c*pow((x-a)/(d-x),1/b)",                           //
>> INV_RODBARD
>>      "y = a*exp(b*x)",                                      //
>> EXP_REGRESSION
>>      "y = a*pow(x,b)",                                           //
>> POWER_REGRESSION
>>      "y = a+b*x+c*pow(x,2)+d*pow(x,3)+e*pow(x,4)+f*pow(x,5)",
>>      // POLY5
>>      "y = a+b*x+c*pow(x,2)+d*pow(x,3)+e*pow(x,4)+f*pow(x,5)+g*pow(x,6)",
>>           // POLY6
>>      "y =
>> a+b*x+c*pow(x,2)+d*pow(x,3)+e*pow(x,4)+f*pow(x,5)+g*pow(x,6)+h*pow(x,7)",
>>        // POLY7
>>      "y =
>> a+b*x+c*pow(x,2)+d*pow(x,3)+e*pow(x,4)+f*pow(x,5)+g*pow(x,6)+h*pow(x,7)+i*pow(x,8)",
>> // POLY8
>>      "y = a*exp(-(x-b)*(x-b)/(2*c*c))",
>> //GAUSSIAN_NOOFFSET
>>      "y = a*(1-exp(-b*x))",
>> //EXP_RECOVERY_NOOFFSET
>>      "y = a*pow(1-exp(-b*x),c)",                               //CHAPMAN
>>      "y = a+b*Math.erf((x-c)/d)"                                 //ERF;
>> note that the c parameter is sqrt2 times the Gaussian
>>      };
>>
>>
>> On Sat, April 4, 2020 3:32 pm, Fred Damen wrote:
>>> Greetings Michael,
>>>
>>> First thanks to you and Wayne.
>>>
>>> Your suggestion of executable macro equations would be a great help.
>>> Unless someone beats me to it I will provide (probably Monday) a list
>>> of
>>> string macro equations that compile and produce the same evaluated
>>> results, i.e., not necessarily fitted results.
>>>
>>> I stare at plots of data a lot and wonder what the equation and/or
>>> parameters that describe that data, so I wrote a plugin that fits
>>> and/or
>>> lets you specify the parameters and plots the results; stole the
>>> idea/code
>>> from your PlotWindow::Data>Add Fit...  Its nice to be able to fit first
>>> and then modify the parameters...  I will try and release the plugin
>>> soon.
>>>
>>> Given that it is hard to predict user oops...  Is it possible to shut
>>> off
>>> those popup error message and detect and display it through
>>> programmatic
>>> means; is this what Interpreter wasError(), getErrorString(),
>>> setIgnoreErrors() is for???  Does cf.getStatus() return a value that
>>> means
>>> don't try to call the f(.) or getParams(.), etc. Getting only one popup
>>> is
>>> ok, but, calling a routine over and over again that requires user GUI
>>> interactions is annoying.
>>>
>>> Again Thanks,
>>>
>>> Fred
>>>
>>>
>>> On Sat, April 4, 2020 11:59 am, Michael Schmid wrote:
>>>> Hi Fred,
>>>>
>>>> just for clarification, most of the CurveFitter's function Strings are
>>>> not usable as macro code; they are meant for humans reading them.
>>>> E.g., all the polynomials (including the linear fit) are written like
>>>> this:
>>>>     "y = a+bx"       (linear fit; not "y = a+b*x")
>>>>     "y = a+bx+cx^2"  (2nd-order polynomial)
>>>>     ...
>>>>     "y = a+bx+cx^2+dx^3+ex^4+fx^5+gx^6+hx^7+ix^8"
>>>> and also the fits with a log are not macro-compatible because they are
>>>> written with 'ln', not 'log', and everything with exponentiation uses
>>>> the caret '^'.
>>>>
>>>> If you would consider it helpful (and if Wayne agrees), we could add
>>>> the
>>>> equivalent macro code for the CurveFitter's function types, as a
>>>> separate (public static final String) array. For the error function,
>>>> this would then be
>>>>     "y = a+b*Math.erf((x-c)/d)"
>>>>
>>>> [Such macro equations would be also handy if my dream of having the
>>>> Plot
>>>> class accepting macro equations for plotting functions ever becomes
>>>> true; then the CurveFitter could pass the fit parameters and equation
>>>> to
>>>> the Plot, so we could see the extrapolated fit function and also have
>>>> a
>>>> smooth curve when zooming in, no 'corners' due to the finite spacing
>>>> of
>>>> the calculated points of the fit]
>>>>
>>>> Note, however, that a fit with that macro code will not necessarily
>>>> yield the same result as what you get from the built-in function, e.g.
>>>> "Power" and "Power (linear regression)" both have the same function
>>>>     "y = a*x^b"
>>>> but they yield different results because "Power (linear regression)"
>>>> does the actual fit for
>>>>     log y = log a + b * log x
>>>>
>>>>
>>>> Concerning bug reports:
>>>>
>>>> In my view, we should have a culture where bug reports are encouraged.
>>>> ImageJ would not be such a great piece of software without users
>>>> reporting bugs and Wayne fixing them within a few hours in most cases!
>>>>
>>>> Concerning suggestions for improvements, like having the macro error
>>>> message in the Minimizer's status String, it depends a bit on the
>>>> ratio
>>>> between cost and benefit, and whether someone is willing to do it.  I
>>>> fear that this one is not so easy to do...
>>>>
>>>> By the way, my suspicion that the ArrayIndexOutOfBoundsException in
>>>> the
>>>> CurveFitter had been caused by the incorrect
>>>> setOffsetMultiplySlopeParams arguments was wrong; it was due to the
>>>> macro Exception (and Wayne was very fast in fixing it)!
>>>>
>>>>
>>>> Best,
>>>>
>>>> Michael
>>>> ___________________________________________________________________________
>>>>
>>>> On 03/04/2020 9:36 pm, Fred Damen wrote:
>>>>> Greetings Michael,
>>>>>
>>>>> The reason for my request was that doFit with CurveFitter.ERF works
>>>>> as
>>>>> expected, but doCustomFit with "y =
>>>>> a+b*erf((x-c)/d)"(CurveFitter.fList[ERF]) yields a popup error
>>>>> message
>>>>> stating that the <erf> is unrecognized, and, then both
>>>>> cf.getResultString() and cf.f(x) throw a
>>>>> java.lang.ArrayIndexOutOfBoundsException: -1 exception. It would be
>>>>> nice
>>>>> if the popup message was (instead if possible) included in the
>>>>> results
>>>>> string, and NaN was returned, respectively. I also evaluate the the
>>>>> string
>>>>> equations directly the same way Curvefitter does under the hood, (the
>>>>> impetus for the question), and I get the same popup. Does
>>>>> Interperter.setIgnoreErrors(true) just prevent this popup, i.e., can
>>>>> I
>>>>> get
>>>>> the same effective nonpopup results using wasError() and
>>>>> getErrorMessage().
>>>>>
>>>>> Generally I don't report bugs that were discovered due to my fumbles,
>>>>> but
>>>>> since I appreciate your work and I was sending the email anyways...
>>>>>
>>>>> Thanks,
>>>>>
>>>>> Fred
>>>>>
>>>>> On Fri, April 3, 2020 2:49 am, Michael Schmid wrote:
>>>>>> Hi Fred,
>>>>>>
>>>>>> concerning the erf: Maybe it would be better to have that as
>>>>>> Math.erf
>>>>>> in
>>>>>> the macro language, just in case someone already has a function
>>>>>> named
>>>>>> "erf" in a plugin, but that's a question to Wayne.
>>>>>> It would be easy to implement (Functions.java, somewhere around line
>>>>>> 378)
>>>>>>
>>>>>> else if (name.equals("erf"))
>>>>>> return IJMath.erf(arg);
>>>>>>
>>>>>> Note that the rather simple erf implementation in ImageJ does not
>>>>>> have
>>>>>> full machine accuracy, absolute and relative errors are below 1e-12,
>>>>>> however (I am not aware of a public-domain implementation of the erf
>>>>>> with better accuracy; if you know one, let me know  please!)
>>>>>>
>>>>>> ---
>>>>>>    > Bonus question:  Why 21 in  macro.run(21); ???
>>>>>> I guess you refer to the macroStartProgramCounter in CurveFitter?
>>>>>> I think it's because there are 20 tokens in the prefix of the macro
>>>>>> interpreter code (comas, brackets, etc. are counted as tokens)
>>>>>> "var x, a, b, c, d, e, f; function dummy() {}"
>>>>>>     1   2  4  6  7  9 11 13  15       16       20
>>>>>>
>>>>>> ---
>>>>>>    > y=a*(1-1/(1+exp(-(x-b)/c)))+d
>>>>>>    > curveFitter.setOffsetMultiplySlopeParams(3,3,-1);
>>>>>>
>>>>>> For this equation, the offset is 'd', so #3, but the multiply factor
>>>>>> is
>>>>>> 'a', so #0, not 3.
>>>>>> It should be
>>>>>> curveFitter.setOffsetMultiplySlopeParams(3, 0, -1);
>>>>>>
>>>>>> I hope that it does not cast an exception with that.
>>>>>>
>>>>>> Michael
>>>>>> ____________________________________________________________
>>>>>>
>>>>>> On 03/04/2020 6:30 am, Fred Damen wrote:
>>>>>>> Greetings,
>>>>>>>
>>>>>>> I have a request...
>>>>>>>
>>>>>>> The Curvefitter can fit to an enumerated erf function, albeit, when
>>>>>>> the
>>>>>>> given string equation is fit, or evaluated using the Interpreter,
>>>>>>> the
>>>>>>> erf
>>>>>>> function is unknown.  Could it be that the Interpreter does
>>>>>>> understand
>>>>>>> the
>>>>>>> erf???.
>>>>>>>
>>>>>>> Bonus question:  Why 21 in  macro.run(21); ???
>>>>>>>
>>>>>>> Bonus bug report, i.e., discovered due to fumble on my part.
>>>>>>> Given the string equations:
>>>>>>> y=a*(1-1/(1+exp(-(x-b)/c)))+d
>>>>>>> and
>>>>>>> cf.setOffsetMultiplySlopeParams(3,3,-1);
>>>>>>> gives:
>>>>>>> java.lang.ArrayinexOutOfBoundsExceptions: -1
>>>>>>> from either setOffsetMultiplySlopeParams or doCustomFit
>>>>>>>
>>>>>>> Thanks in Advance,
>>>>>>>
>>>>>>> Fred
>>>>>>>
>>>>>>> --
>>>>>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>>>>>>
>>>>>>
>>>>>> --
>>>>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>>>>>
>>>>>
>>>>> --
>>>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>>>>
>>>>
>>>> --
>>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>>>
>>>
>>> --
>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>>
>>
>> --
>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html