2 * Copyright (C) 2008 Albert Davis
3 * Author: Albert Davis <aldavis@gnu.org>
5 * This file is part of "Gnucap", the Gnu Circuit Analysis Package
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 *------------------------------------------------------------------
23 #include "u_parameter.h"
25 #include "u_function.h"
26 /*--------------------------------------------------------------------------*/
28 /*--------------------------------------------------------------------------*/
29 class MIN
: public WAVE_FUNCTION
{
30 PARAMETER
<double> before
;
31 PARAMETER
<double> after
;
45 virtual FUNCTION_BASE
* clone()const { return new MIN(*this);}
46 string
label()const{return "min";}
47 void expand(CS
& Cmd
, const CARD_LIST
* Scope
)
54 unsigned here
= Cmd
.cursor();
56 _w
= find_wave(probe_name
);
66 || Get(Cmd
, "probe", &probe_name
)
67 || Get(Cmd
, "before", &before
)
68 || Get(Cmd
, "after", &after
)
69 || Get(Cmd
, "end", &before
)
70 || Get(Cmd
, "begin", &after
)
71 || Set(Cmd
, "deriv{ative}", &derivative
, true)
72 || Set(Cmd
, "arg", &arg
, true)
73 || Set(Cmd
, "last", &last
, true)
74 || Set(Cmd
, "first", &last
, false)
76 }while (Cmd
.more() && !Cmd
.stuck(&here
));
79 _w
= find_wave(probe_name
);
82 before
.e_val(BIGBIG
, Scope
);
83 after
.e_val(-BIGBIG
, Scope
);
86 double wave_eval()const
88 trace1("MIN::wave_eval", probe_name
);
91 double time
= (last
) ? -BIGBIG
: BIGBIG
;
93 WAVE::const_iterator begin
= lower_bound(_w
->begin(), _w
->end(), DPAIR(after
, -BIGBIG
));
94 WAVE::const_iterator end
= upper_bound(_w
->begin(), _w
->end(), DPAIR(before
, BIGBIG
));
95 if (begin
== end
) return(NAN
);
98 double t1
= begin
->first
;
100 for (WAVE::const_iterator i
= begin
; i
< end
; ++i
) {
102 if(derivative
){ // very simple difference quotient.
103 double dt
= i
->first
- t1
;
109 val
= (i
->second
- prev
)/(dt
);
115 double at
= i
->first
;
116 trace3("MIN::wave_eval", probe_name
, at
, val
);
117 if (val
< m
|| (last
&& (val
== m
))) {
123 return ((arg
) ? (time
) : (m
));
125 throw Exception_No_Match(probe_name
);
129 DISPATCHER
<FUNCTION_BASE
>::INSTALL
d2(&measure_dispatcher
, "min", &p2
);
130 /*--------------------------------------------------------------------------*/
132 /*--------------------------------------------------------------------------*/
133 /*--------------------------------------------------------------------------*/
134 // vim:ts=8:sw=2:noet: