1 /*$Id: m_cpoly.h,v 1.2 2009-12-10 14:34:44 felix Exp $ -*- C++ -*-
2 * Copyright (C) 2001 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 *------------------------------------------------------------------
22 * structs for fixed order polynomials, in 2 different forms
23 * FPOLY is by function -- f0 = eval of function
28 * f(t) = f0 + f1*(t-x) + f2*(t-x)^2 + ...
29 * CPOLY is by series -- c0 = coeff of x^0 term (constant)
30 * c1 = coeff of x^1 term (1st derivative)
31 * c2 = coeff of x^2 term
33 * f(x) = c0 + f1*x + f2*x^2 + ...
34 * f(t) = c0 + f1*t + f2*t^2 + ...
36 //testing=script,sparse 2006.07.13
41 /*--------------------------------------------------------------------------*/
42 // fixme. move (where?)
43 inline double operator*(const DPAIR
& t
, const DPAIR
& a
)
45 double ret
= t
.first
* a
.first
;
46 ret
+= t
.second
* a
.second
;
49 /*--------------------------------------------------------------------------*/
52 /*--------------------------------------------------------------------------*/
53 struct FPOLY1
{ /* first order polynomial */
54 hp_float_t x
; /* the argument */
55 hp_float_t f0
; /* the function (c0 + x*f1) */
56 hp_float_t f1
; /* the first derivative */
57 explicit FPOLY1() : x(0), f0(0), f1(0) {}
58 FPOLY1(const FPOLY1
& p
) : x(p
.x
), f0(p
.f0
), f1(p
.f1
) {}
59 explicit FPOLY1(hp_float_t X
,hp_float_t F0
,hp_float_t F1
) : x(X
), f0(F0
), f1(F1
) {}
60 explicit FPOLY1(const CPOLY1
& p
);
61 explicit FPOLY1(const DPAIR
& l
, const DPAIR
& r
);
64 bool operator==(const FPOLY1
& p
)const
65 {return (f1
==p
.f1
&& f0
==p
.f0
&& x
==p
.x
);}
66 FPOLY1
& operator*=(hp_float_t s
) {f0
*=s
; f1
*=s
; return *this;}
67 FPOLY1
& operator*=(const FPOLY1
& s
);
68 FPOLY1
& operator+=(hp_float_t f
) {untested(); f0
+=f
; return *this;}
69 FPOLY1
& operator+=(const FPOLY1
& s
)
70 {untested(); assert(x
==s
.x
); f0
+=s
.f0
; f1
+=s
.f1
; return *this;}
71 FPOLY1
operator-()const {untested(); return FPOLY1(x
, -f0
, -f1
);}
72 hp_float_t
c1()const {assert(f1
== f1
); return f1
;}
74 {assert(f0
==f0
); assert(f1
==f1
); assert(x
==x
); assert(f0
!=LINEAR
); return (f0
- x
* f1
);}
75 double f(double xx
)const {return (f0
+ (xx
-x
)*f1
);}
76 double operator()(double xx
)const {return f(xx
);}
78 /*--------------------------------------------------------------------------*/
79 struct CPOLY1
{ /* first order polynomial */
80 hp_float_t x
; /* the argument */
81 hp_float_t c0
; /* f(x) - x*f'(x), or f0 - x*f1 */
82 hp_float_t c1
; /* the first derivative */
83 explicit CPOLY1() : x(0), c0(0), c1(0) {}
84 CPOLY1(const CPOLY1
& p
) : x(p
.x
), c0(p
.c0
), c1(p
.c1
) {}
85 explicit CPOLY1(hp_float_t X
,hp_float_t C0
,hp_float_t C1
) : x(X
), c0(C0
), c1(C1
) {}
86 explicit CPOLY1(const FPOLY1
& p
);
89 bool operator==(const CPOLY1
& p
)const
90 {return (c1
==p
.c1
&& c0
==p
.c0
&& x
==p
.x
);}
91 CPOLY1
& operator*=(hp_float_t s
) {c0
*=s
; c1
*=s
; return *this;}
92 CPOLY1
& operator+=(const CPOLY1
& s
) {c0
+=s
.c0
; c1
+=s
.c1
; return *this;}
93 CPOLY1
& operator-=(const CPOLY1
& s
) {c0
-=s
.c0
; c1
-=s
.c1
; return *this;}
94 hp_float_t
f1()const {return c1
;}
95 hp_float_t
f0()const {return (c0
+ x
* c1
);}
96 hp_float_t
f(double xx
)const {return (c0
+ xx
* c1
);}
97 DPAIR
intersect(const CPOLY1
&) const;
99 double zero(const FPOLY1
&)const;
101 /*--------------------------------------------------------------------------*/
102 inline FPOLY1::FPOLY1(const CPOLY1
& p
)
108 assert(*this == *this);
110 /*--------------------------------------------------------------------------*/
111 inline FPOLY1::FPOLY1(const DPAIR
& l
, const DPAIR
& r
):
114 f1((r
.second
- l
.second
) / (r
.first
- l
.first
))
117 /*--------------------------------------------------------------------------*/
118 inline CPOLY1::CPOLY1(const FPOLY1
& p
)
127 assert(*this == *this);
129 /*--------------------------------------------------------------------------*/
130 inline FPOLY1
& FPOLY1::operator*=(const FPOLY1
& s
)
138 /*--------------------------------------------------------------------------*/
139 inline FPOLY1
operator*(FPOLY1 a
, const FPOLY1
& b
)
145 /*--------------------------------------------------------------------------*/
146 inline FPOLY1
operator+(FPOLY1 a
, const FPOLY1
& b
)
152 /*--------------------------------------------------------------------------*/
153 inline FPOLY1
operator+(FPOLY1 a
, hp_float_t b
)
159 /*--------------------------------------------------------------------------*/
160 inline FPOLY1
operator-(hp_float_t a
, const FPOLY1
& b
)
165 /*--------------------------------------------------------------------------*/
166 // compute a zero. return inf if there is none.
167 inline double CPOLY1::zero() const
175 /*--------------------------------------------------------------------------*/
177 inline T
& operator<<(T
& o
, const CPOLY1
& x
)
179 return o
<< x
.c0
<< ((x
.c1
<0)?"":"+") << x
.c1
<< "*x at x=" << x
.x
;
181 /*--------------------------------------------------------------------------*/
183 inline T
& operator<<(T
& o
, const FPOLY1
& x
)
185 return o
<< "F " << x
.x
<< " " << x
.f0
<< " " << x
.f1
;
187 /*--------------------------------------------------------------------------*/
188 // compute a zero wrt linear function. return inf if there is none.
189 inline double CPOLY1::zero(const FPOLY1
& ff
) const
195 double t
= (p1
- ff
.f1
*(c0
-p2
)) / (1.+ff
.f1
*c1
);
197 trace5("zero", *this, ff
, t
, p1
, p2
);
200 /*--------------------------------------------------------------------------*/
201 inline DPAIR
CPOLY1::intersect(const CPOLY1
& that
) const
205 double z
= tmp
.zero();
206 trace4("found zero", *this, that
, z
, tmp
);
208 return DPAIR(z
,f(z
));
210 /*--------------------------------------------------------------------------*/
212 // vim:ts=8:sw=2:noet: