• d/dx in forth

    From Ahmed@21:1/5 to All on Fri May 24 09:57:47 2024
    Hello,

    In the thread: https://www.novabbs.com/devel/article-flat.php?group=comp.lang.forth&id=16944&first=1&last=25#start

    Paul Robin posted:

    For example, sin (sine) is a function, whose input is a real and
    whose
    output is another real. And "derivative" (d/dx) is a function whose
    input is a function, and whose output is another function. So you
    get
    that d/dx (sin) = cos, or some numerical approximation of same. In
    Python or Haskell, this is easy, e.g.:


    h = 0.0001
    d_over_dx f = g where { g x = (f(x+h) - f(x)) / h }
    dsin = d_over_dx sin
    print (dsin 0.5) -- prints 0.8775585891507287
    print (cos 0.5) -- prints 0.8775825618903728


    Pretty close approximation. In Forth it is a bit messier because you
    want a signature like


    : d/dx ( xt -- xt ) .... ;


    and you may have to do some advanced or non-portable things to create
    new xt's on the fly like that. But there are various ways you can
    get
    equivalent functionality using OOP or whatever.


    minforth replied:

    Clumsy but portable:

    0.0001e FVALUE h

    DEFER ofunc ' FSIN IS ofunc
    DEFER dfunc

    : D/DX {: xt f: x -- y :}
    x h f+ xt execute x xt execute f- h f/ ;

    :NONAME ( x -- y ) ['] ofunc D/DX ; IS dfunc


    0.5e dfunc f.
    0.5e fcos f.

    My question is:
    Why not do it directly like this:

    : d/dx ( xt -- )
    create ,
    does> @ dup ( f: x -- y) fdup 1e-4 f+ execute fswap 1e-4 f-
    execute f- 0.5e4 f* ;

    and the dervative of any function can be obtained directly like this:

    ' func() d/dx der_func()

    for example: (in gforth)
    ' fsin d/dx der_fsin ok
    0.5e fcos f. 0.877582561890373 ok
    0.5e der_fsin f. 0.877582560427637 ok

    another example:
    : f() ( f: x -- y) fdup fdup f* f+ ; \ f(x) = x^2+x
    : df() ( f: x -- y) 2e f* 1e f+ ; \ df(x) = 2*x + 1 for comparison
    ' f() d/dx der_f()

    5e der_f() f. 10.9999999999744 ok
    5e df() f. 11. ok

    Best Regards.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to Ahmed on Fri May 24 11:56:40 2024
    melahi_ahmed@yahoo.fr (Ahmed) writes:
    Hello,

    In the thread: >https://www.novabbs.com/devel/article-flat.php?group=comp.lang.forth&id=16944&first=1&last=25#start

    Paul Robin posted:

    For example, sin (sine) is a function, whose input is a real and
    whose
    output is another real. And "derivative" (d/dx) is a function whose
    input is a function, and whose output is another function. So you
    get
    that d/dx (sin) = cos, or some numerical approximation of same. In
    Python or Haskell, this is easy, e.g.:


    h = 0.0001
    d_over_dx f = g where { g x = (f(x+h) - f(x)) / h }
    dsin = d_over_dx sin
    print (dsin 0.5) -- prints 0.8775585891507287
    print (cos 0.5) -- prints 0.8775825618903728


    Pretty close approximation. In Forth it is a bit messier because you
    want a signature like


    : d/dx ( xt -- xt ) .... ;

    Most probably he meant ( xt1 -- xt2 )

    and you may have to do some advanced or non-portable things to create
    new xt's on the fly like that.

    Why not do it directly like this:

    : d/dx ( xt -- )
    create ,
    does> @ dup ( f: x -- y) fdup 1e-4 f+ execute fswap 1e-4 f-
    execute f- 0.5e4 f* ;

    and the dervative of any function can be obtained directly like this:

    ' func() d/dx der_func()

    or, for his example:

    ' fsin d/dx fdsin

    And given that he gives a name to the result anyway, it's obviously
    fine that your solution requires a name and produces a named word
    rather than an unnamed word. Your solution uses a slightly different (unbiased) formula, though.

    for example: (in gforth)
    ' fsin d/dx der_fsin ok
    0.5e fcos f. 0.877582561890373 ok
    0.5e der_fsin f. 0.877582560427637 ok

    The smaller difference from the fcos result demonstrates the advantage
    of the unbiased formula.

    A solution that actually complies with the ( xt1 -- xt2 ) requirement
    and is in standard Forth is as follows (using the biased formula in
    the Python or Haskell program above):

    0.0001e fvalue h

    : d/dx1 ( r1 xt -- r2 )
    fdup h f+ dup execute fswap execute f- h f/ ;

    : d/dx ( xt1 -- xt2 )
    >r :noname ( r1 -- r2 ) r> postpone literal postpone d/dx1 postpone ; ;

    0.5e ' fsin d/dx execute f. \ prints 0.877558589150729

    Maybe he considers the use of DOES> or POSTPONE to be "advanced
    things". The disadvantage of the ( xt1 -- xt2 ) variant is that it
    may seduce the user to produce multiple instances of the same function (possibly one instance for every iteration of some loop), with every
    instance costing memory that is unlikely to be reclaimed before the
    end of the session. With a version that produces a named word that is
    far less likely.

    The advantage of the unnamed variant is that we can do things like

    defer fddsin
    ' fsin d/dx d/dx is fddsin

    without naming the intermediate function. Looking at the result, this
    seems to work ok:

    0.5e fddsin f. \ prints -0.479513295736922
    0.5e fsin fnegate f. \ prints -0.479425538604203

    - anton
    --
    M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
    comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
    New standard: https://forth-standard.org/
    EuroForth 2023: https://euro.theforth.net/2023

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ahmed@21:1/5 to All on Fri May 24 12:58:29 2024
    Got it.
    Thanks for the clarifications.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Krishna Myneni@21:1/5 to Ahmed on Fri May 24 21:13:15 2024
    On 5/24/24 04:57, Ahmed wrote:
    ;;;
     that d/dx (sin) = cos, or some numerical approximation of same.  In
     Python or Haskell, this is easy, e.g.:


       h = 0.0001
       d_over_dx f = g where { g x = (f(x+h) - f(x)) / h }
    ...

    Side note: you may already be aware that the accuracy of the derivative improves significantly if you average the forward and backward slopes,

    df/dx \approx [(f(x+h) - f(x)) + (f(x) - f(x-h))] / 2h

    = [f(x+h) - f(x-h)] / 2h

    The error goes as O(h^2) rather than as O(h).

    This is the method I implement for computing a numerical derivative in
    my XYPLOT-32 program:

    https://github.com/mynenik/XYPLOT-32/blob/master/modules/fsl/extras/derivative.4th

    --
    Krishna

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ahmed@21:1/5 to I just on Sat May 25 07:34:19 2024
    Hello,
    Thanks for the link.

    The forward derivative was posted by Paul Robin.
    I just asked why not do it simply and directly like this:

    : d/dx ( xt -- ) create , does> @ dup ( f: x -- y) fdup 1e-4 f+ execute
    fswap 1e-4 f- execute f- 0.5e4 f* ;

    where h = 1e-4 for example.

    It is the same as that you proposed.

    I have a question concerning your derivative implementation (the link
    you've given):
    in the word derivative, we find:

    dx1 F@ F0= dx2 F@ F0= or
    IF 1 unloop EXIT THEN

    why you use or in the condition? why not and?

    I think you implemented:
    the derivative at (x1, f(x1)) as

    d/dx f(x1) = (( (f(x2)-f(x1))/(x2-x1))+(( (f(x1)-f(x0))/(x1-x0)))/2,
    where (x0,f(x0)), (x1, f(x1)) and (x2, f(x2)) are successive points.

    and that is diffrent from
    d/dx f(x1) = (f(x2)-f(x0))/(x2-x0) when (x1-x0) != (x2-x1)
    the latter can be written d/dx f(x1) = (f(x1+h) - f(x1-h))/(2h) wher h =
    x1-x0 = x2-x1
    the formula you've given in your reply.

    Thanks.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Krishna Myneni@21:1/5 to Ahmed on Sat May 25 09:05:07 2024
    On 5/25/24 02:34, Ahmed wrote:
    ...
    I have a question concerning your derivative implementation (the link
    you've given):
    in the word derivative, we find:

        dx1 F@ F0=  dx2 F@ F0=  or
        IF 1 unloop EXIT  THEN

    why you use or in the condition? why not and?
    I think you implemented:
    the derivative at (x1, f(x1)) as


    The routine stops the calculation whenever it encounters adjacent points
    which have dx = 0. Thus either dx1 being zero OR dx2 being zero results
    in an error condition -- the derivative calculation is considered invalid.

    --
    Krishna

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ahmed@21:1/5 to All on Sat May 25 14:55:50 2024
    Hi,
    Thanks for the explanation.
    So it is like a jump where the derivative is not defined (not in the
    sens of distributions where it is given by Dirac delta distribution (or generalized function)).

    Thank you again.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ahmed@21:1/5 to All on Sat May 25 15:14:47 2024
    Hi again,

    But in that case, one still can calculate the derivative
    d/dx (f(x1)) = (f(x2)-f(x0))/(x2-x0)
    where (x0,f(x0)), (x1, f(x1)) and (x2, f(x2)) are three consecutive
    points with:
    - x1 = x0 and f(x1) != f(x0) and x2 != x1.
    or
    - x2 = x1 and f(x2) != f(x1) and x1 != x0.

    The problem is when x2 = x1 = x0, and that's why I asked why not "and"
    in place of "or".

    Thanks again.

    Best Regards.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Krishna Myneni@21:1/5 to Ahmed on Sat May 25 15:11:18 2024
    On 5/25/24 10:14, Ahmed wrote:
    Hi again,

    But in that case, one still can calculate the derivative d/dx (f(x1)) = (f(x2)-f(x0))/(x2-x0) where (x0,f(x0)), (x1, f(x1)) and (x2, f(x2)) are
    three consecutive
    points with:
    - x1 = x0 and f(x1) != f(x0) and x2 != x1.
    or - x2 = x1 and f(x2) != f(x1) and x1 != x0.

    The problem is when x2 = x1 = x0, and that's why I asked why not "and"
    in place of "or".


    You can still calculate a local derivative if one of the intervals, dx1
    or dx2 is not zero; however, my preference in this case is that an error
    be flagged for the user, since the data is itself problematic. The user
    needs to consider why the data represents a multi-valued function.

    --
    Krishna

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ahmed@21:1/5 to All on Sat May 25 20:32:26 2024
    Ah, I see.
    Thanks for the reply.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Krishna Myneni@21:1/5 to Ahmed on Sun May 26 06:41:52 2024
    On 5/25/24 15:32, Ahmed wrote:
    Ah, I see.
    Thanks for the reply.

    My derivative routine is basic. For experimental data, it assumes you
    have done whatever preprocessing on the raw data to provide a reasonably
    smooth approximation of an analytic function to it.

    In measurements, one is rarely dealing with data which, in raw form, is
    an analytic function. It's possible that the data contains repeated measurements of Y at the same control parameter X, and Y is a random
    variable drawn from some distribution. Then, one could write a
    derivative routine which computes the statistics of Y at each X, and
    then compute an alternative derivative e.g., a derivative based on the
    mean y-values.

    I have not implemented such a method for XYPLOT, although one can write
    an external Forth module to add that functionality to the program.

    Then, of course, there is also the case where X itself may have a
    distribution ...

    --
    Krishna

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@21:1/5 to All on Sun May 26 13:50:16 2024
    Even signals disturbed by noise and smoothed by splines
    often show considerable deviations in their first derivative.
    This can even make them unusable. Simple bandpass filters,
    e.g. classic Butterworth, are often better. Finding the right
    frequency bands is usually a question of empirical experience.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From albert@spenarnc.xs4all.nl@21:1/5 to krishna.myneni@ccreweb.org on Mon May 27 09:05:35 2024
    In article <v2v762$3d4ji$1@dont-email.me>,
    Krishna Myneni <krishna.myneni@ccreweb.org> wrote:
    On 5/25/24 15:32, Ahmed wrote:
    Ah, I see.
    Thanks for the reply.

    My derivative routine is basic. For experimental data, it assumes you
    have done whatever preprocessing on the raw data to provide a reasonably >smooth approximation of an analytic function to it.

    In measurements, one is rarely dealing with data which, in raw form, is
    an analytic function.

    An analytic function is defined in an infinitly many immeasurable
    points where only Descartes and Cantor pretend to know the properties off. Seriously?
    At most an analytic function is a pretend thing, not a property of real
    data, not even "rarely".

    --
    Krishna


    Groetjes Albert
    --
    Don't praise the day before the evening. One swallow doesn't make spring.
    You must not say "hey" before you have crossed the bridge. Don't sell the
    hide of the bear until you shot it. Better one bird in the hand than ten in
    the air. First gain is a cat purring. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Krishna Myneni@21:1/5 to albert@spenarnc.xs4all.nl on Mon May 27 13:40:05 2024
    On 5/27/24 02:05, albert@spenarnc.xs4all.nl wrote:
    In article <v2v762$3d4ji$1@dont-email.me>,
    Krishna Myneni <krishna.myneni@ccreweb.org> wrote:
    On 5/25/24 15:32, Ahmed wrote:
    Ah, I see.
    Thanks for the reply.

    My derivative routine is basic. For experimental data, it assumes you
    have done whatever preprocessing on the raw data to provide a reasonably
    smooth approximation of an analytic function to it.

    In measurements, one is rarely dealing with data which, in raw form, is
    an analytic function.

    An analytic function is defined in an infinitly many immeasurable
    points where only Descartes and Cantor pretend to know the properties off. Seriously?
    At most an analytic function is a pretend thing, not a property of real
    data, not even "rarely".


    Good grief. We shouldn't even be talking about numerical differentiation
    then.

    --
    Krishna

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From albert@spenarnc.xs4all.nl@21:1/5 to krishna.myneni@ccreweb.org on Mon May 27 21:12:22 2024
    In article <v32k25$5kmh$2@dont-email.me>,
    Krishna Myneni <krishna.myneni@ccreweb.org> wrote:
    On 5/27/24 02:05, albert@spenarnc.xs4all.nl wrote:
    In article <v2v762$3d4ji$1@dont-email.me>,
    Krishna Myneni <krishna.myneni@ccreweb.org> wrote:
    On 5/25/24 15:32, Ahmed wrote:
    Ah, I see.
    Thanks for the reply.

    My derivative routine is basic. For experimental data, it assumes you
    have done whatever preprocessing on the raw data to provide a reasonably >>> smooth approximation of an analytic function to it.

    In measurements, one is rarely dealing with data which, in raw form, is
    an analytic function.

    An analytic function is defined in an infinitly many immeasurable
    points where only Descartes and Cantor pretend to know the properties off. >> Seriously?
    At most an analytic function is a pretend thing, not a property of real
    data, not even "rarely".


    Good grief. We shouldn't even be talking about numerical differentiation >then.

    In practical manners it is okay to talk about numerical differentiation.
    For instance implementing a pid regulator.
    The derivative calculated numerically serves a great purpose. The thought
    that a jurky motion of a piston is or isn't an analytical function, and
    can extended to minus infinity in the complex plane is foreign to me.


    --
    Krishna

    Groetjes Albert
    --
    Don't praise the day before the evening. One swallow doesn't make spring.
    You must not say "hey" before you have crossed the bridge. Don't sell the
    hide of the bear until you shot it. Better one bird in the hand than ten in
    the air. First gain is a cat purring. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From ahmed@21:1/5 to All on Tue May 28 08:37:01 2024
    Hi,
    I think Mr K. M. meant "analytic formula fitting the acquired (measured)
    data".
    And analytic functions are a class of functions over the complexe plane
    (C) with some properties that give them certain characteristics
    (derivation for example).
    See the link
    https://en.wikipedia.org/wiki/Analytic_function

    For automatic control we use numeric derivation for modeling,
    identification and control of systems based on sampled time data
    (transfer functions in z plane, z-transform).
    The approximations used are for example:
    Euler forward
    Euler backward
    Tustin
    And the digital PID controller is just an example of discrete systems
    with a derivation action
    (d/dt(in time domaine)<--->s (Laplace transform)<--->(1-z^(-1))/Ts (in z domaine, Backwrad Euler)
    (d/dt(in time domaine)<--->s (Laplace transform)<--->(z-1)/Ts (in z
    domaine, Forward Euler)
    (d/dt(in time domaine)<--->s (Laplace transform)<--->(2/Ts)*(z-1)/(z+1)
    (in z domaine, Tustin)

    Ts is the sampling period.

    I used a PID controller with arduino-based real-time simulation and that
    worked as required and a comparison with a simulation under
    matlab/simulink confirmed the results.

    Best regards.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From albert@spenarnc.xs4all.nl@21:1/5 to ahmed on Tue May 28 12:20:31 2024
    In article <1be75ceb4dfcfb241237191acda06020@www.novabbs.com>,
    ahmed <melahi_ahmed@yahoo.fr> wrote:
    Hi,
    I think Mr K. M. meant "analytic formula fitting the acquired (measured) >data".
    And analytic functions are a class of functions over the complexe plane
    (C) with some properties that give them certain characteristics
    (derivation for example).
    See the link
    https://en.wikipedia.org/wiki/Analytic_function

    An analytic function has the properties that if you know a
    tiny environment -- mathematically speaking --
    you can calculate all derivatives and use these in a series
    formula to calculate the function anywere.
    So If you know the orbit of the earth for the next 10 mS
    you could calculate the position to all eternity
    (forgetting about 3 body problems and chaos theory.)
    This is all nice and dandy for the Rieman Zeta function but not
    for this situation.

    (I have a degree a theoretical physics. I'm not worth a
    dime in physics, but this mathematics subject I was quite
    good at.)

    Best regards.
    --
    Don't praise the day before the evening. One swallow doesn't make spring.
    You must not say "hey" before you have crossed the bridge. Don't sell the
    hide of the bear until you shot it. Better one bird in the hand than ten in
    the air. First gain is a cat purring. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to Anton Ertl on Tue May 28 08:34:59 2024
    anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
    melahi_ahmed@yahoo.fr (Ahmed) writes:
    Hello,

    In the thread: >>https://www.novabbs.com/devel/article-flat.php?group=comp.lang.forth&id=16944&first=1&last=25#start

    Paul Robin posted:

    For example, sin (sine) is a function, whose input is a real and
    whose
    output is another real. And "derivative" (d/dx) is a function whose
    input is a function, and whose output is another function. So you
    get
    that d/dx (sin) = cos, or some numerical approximation of same. In
    Python or Haskell, this is easy, e.g.:


    h = 0.0001
    d_over_dx f = g where { g x = (f(x+h) - f(x)) / h }
    dsin = d_over_dx sin
    print (dsin 0.5) -- prints 0.8775585891507287
    print (cos 0.5) -- prints 0.8775825618903728

    Ahmed Melahi's solution (using a better formula):

    : d/dx ( xt -- )
    create ,
    does> @ dup ( f: x -- y) fdup 1e-4 f+ execute fswap 1e-4 f-
    execute f- 0.5e4 f* ;

    Usage example:

    ' fsin d/dx fdsin

    My solution (using Paul Rubin's formula):

    0.0001e fvalue h

    : d/dx1 ( r1 xt -- r2 )
    fdup h f+ dup execute fswap execute f- h f/ ;

    : d/dx ( xt1 -- xt2 )
    r :noname ( r1 -- r2 ) r> postpone literal postpone d/dx1 postpone ; ;

    0.5e ' fsin d/dx execute f. \ prints 0.877558589150729

    Another variant is to compile xt1 into xt2; here a standard version
    (with Paul Rubin's formula):

    0.0001e fvalue h

    : d/dx ( xt1 -- xt2 )
    >r :noname ( r1 -- r2 )
    postpone fdup postpone h postpone f+ r@ compile,
    postpone fswap r> compile, postpone f- postpone h postpone f/
    postpone ; ;

    0.5e ' fsin d/dx execute f. \ prints "0.877558589150729"

    If I do

    0.5e ' fsin d/dx disasm/f

    on VFX64, I get:

    ( 0050A358 D9C0 ) FLD ST
    ( 0050A35A DB2DF0FEFFFF ) FLD TBYTE FFFFFEF0 [RIP] @0050A250 ( 0050A360 DEC1 ) FADDP ST(1), ST
    ( 0050A362 E8F9CBFFFF ) CALL 00506F60 FSIN
    ( 0050A367 D9C9 ) FXCH ST(1)
    ( 0050A369 E8F2CBFFFF ) CALL 00506F60 FSIN
    ( 0050A36E DEE9 ) FSUBP ST(1), ST
    ( 0050A370 DB2DDAFEFFFF ) FLD TBYTE FFFFFEDA [RIP] @0050A250 ( 0050A376 DEF9 ) FDIVP ST(1), ST
    ( 0050A378 C3 ) RET/NEXT
    ( 33 bytes, 10 instructions )

    Now on to the less portable stuff. The many POSTPONE's in the code
    above hamper readability. So let's use ]] ... [[ to get rid of them:

    : d/dx ( xt1 -- xt2 )
    >r :noname ( r1 -- r2 ) ]]
    fdup h f+ [[ r@ compile, ]] fswap [[ r> compile, ]] f- h f/ ;
    [[ ;

    This example may also make it clear why the brackets are oriented the
    way they are. Compiles on Gforth and VFX64 (and to the same code as
    above on VFX64).

    Gforth offers an additional nicety. The following code generates the
    same code as the previous D/DX.

    : d/dx {: xt: xt1 -- xt2 :}
    :noname ( r1 -- r2 ) ]] fdup h f+ xt1 fswap xt1 f- h f/ ; [[ ;

    The XT: results in XT1 being a defer-flavoured local, so mentioning
    the name executes the xt, and POSTPONEing it (e.g., within ]]..[[)
    COMPILE,s it.

    Another variant is to use Gforth's flat closures:

    : d/dx ( xt1 -- xt2 )
    [{: xt: xt1 :}d fdup h f+ xt1 fswap xt1 f- h f/ ;] ;

    The functionality is the same as my previous D/DX implementations, and
    the source code looks similar to the previous one, but the
    implementation is quite different:

    ' fsin d/dx

    uses 3 cells in the dictionary (and none in the native code) with the flat-closure version, while the three definitions before that (which
    use POSTPONE in some form or other) take 16 cells of dictionary and
    148 bytes of native code. Generating a closure is also much faster.
    However, the POSTPONE-based variants will run faster.

    Stack purists will dislike the local in the closure. Gforth also
    provides a pure-stack variant, and using it here will look as follows:

    : d/dx ( xt1 -- xt2 )
    [n:d fdup h f+ dup execute fswap execute f- h f/ ;] ;

    This variant makes the difference to the POSTPONE-based approaches
    more obvious by calling EXECUTE explicitly.

    Ahmed Melahis CREATE...DOES> variant can be seen as the classical
    Forth syntax for the pure-stack flat-closure approach; he uses a
    different formula and inlines H, which obscures this a bit, but using
    the same formula and H, a CREATE-DOES variant looks as follows:

    : d/dx-named ( xt1 "name" -- xt2 )
    create ,
    does> ( r1 -- r2 )
    @ fdup h f+ dup execute fswap execute f- h f/ ;

    where the code from FDUP to F/ is the same as in the pure-stack
    closure version above. If you use D/DX-NAMED with Gforth's NONAME,
    calling

    ' fsin noname d/dx-named

    consumes three cells, like the flat-closure variants.

    Some may conclude that this shows that flat closures are unnecessary
    (and some may extend this to other newer features like defer-flavoured
    locals and ]]...[[). However, note that flat closures can not just be allocated in the dictionary, but also on the locals stack or on the
    heap, unlike CREATE..DOES>.

    Of course, if we judge expressive power by Turing completeness, one
    can reject all new features (or leave away many existing ones),
    because they do not change Turing completeness, but there is a reason
    why we implement more than just a minimal Turing-complete language, so
    we obviously use other criteria for judging the desirability of
    features.

    - anton
    --
    M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
    comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
    New standard: https://forth-standard.org/
    EuroForth 2023: https://euro.theforth.net/2023

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Krishna Myneni@21:1/5 to minforth on Tue May 28 07:25:31 2024
    On 5/26/24 08:50, minforth wrote:
    Even signals disturbed by noise and smoothed by splines
    often show considerable deviations in their first derivative.
    This can even make them unusable. Simple bandpass filters,
    e.g. classic Butterworth, are often better. Finding the right
    frequency bands is usually a question of empirical experience.

    I'm wary of using filters in connection with computing derivatives.
    Filters will exhibit latency and therefore alter some properties of a
    signal. One such case might be a repetitive signal consisting of a short-duration pulse followed by a long-duration pulse. If we want to
    obtain a measure of the peak to peak time interval between the short and
    long pulse within a cycle, the distortion of the waveform by the filter
    has to be considered.

    Alternatively, if a trigger pulse is available to mark the start of the
    cycle, the repetitive signal can be averaged until the noise is low
    enough to use a derivative to obtaining the zero crossings. Curve
    fitting is generally a better technique though, when a model function
    exists.

    --
    Krishna

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@21:1/5 to Krishna Myneni on Tue May 28 12:53:13 2024
    Krishna Myneni wrote:

    On 5/26/24 08:50, minforth wrote:
    Even signals disturbed by noise and smoothed by splines
    often show considerable deviations in their first derivative.
    This can even make them unusable. Simple bandpass filters,
    e.g. classic Butterworth, are often better. Finding the right
    frequency bands is usually a question of empirical experience.

    I'm wary of using filters in connection with computing derivatives.
    Filters will exhibit latency and therefore alter some properties of a
    signal.

    That's why Butterworths are a good compromise. They exhibit only
    slight phase distortion. Doing eg FFT with raw signals using ends
    in garbage.

    One such case might be a repetitive signal consisting of a
    short-duration pulse followed by a long-duration pulse. If we want to
    obtain a measure of the peak to peak time interval between the short
    and
    long pulse within a cycle, the distortion of the waveform by the filter

    has to be considered.

    That's a typical application for matched filters.

    Alternatively, if a trigger pulse is available to mark the start of the

    cycle, the repetitive signal can be averaged until the noise is low
    enough to use a derivative to obtaining the zero crossings. Curve
    fitting is generally a better technique though, when a model function
    exists.

    My quasi daily "aha"s were hidden 50 Hz (60 Hz in the US) hums within
    signals. Curve fitting happily counts them in, whereas a simple notch
    filter can take care of that.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ahmed@21:1/5 to albert@spenarnc.xs4all.nl on Tue May 28 13:52:39 2024
    albert@spenarnc.xs4all.nl wrote:

    In article <1be75ceb4dfcfb241237191acda06020@www.novabbs.com>,
    ahmed <melahi_ahmed@yahoo.fr> wrote:
    Hi,
    I think Mr K. M. meant "analytic formula fitting the acquired (measured) >>data".
    And analytic functions are a class of functions over the complexe plane
    (C) with some properties that give them certain characteristics
    (derivation for example).
    See the link
    https://en.wikipedia.org/wiki/Analytic_function

    An analytic function has the properties that if you know a
    tiny environment -- mathematically speaking --
    you can calculate all derivatives and use these in a series
    formula to calculate the function anywere.
    So If you know the orbit of the earth for the next 10 mS
    you could calculate the position to all eternity
    (forgetting about 3 body problems and chaos theory.)
    This is all nice and dandy for the Rieman Zeta function but not
    for this situation.

    (I have a degree a theoretical physics. I'm not worth a
    dime in physics, but this mathematics subject I was quite
    good at.)

    Agreed.

    Best Regards

    Best regards.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)