Reputation: 8578
Consider the code below:
public class Analyzer {
protected Func f,fd;
public delegate double Func( double x );
public Analyzer( Func f, Func fd ) {
this.f = f;
this.fd = fd;
}
public Analyzer( Func f ) {
this.f = f;
fd = dx;
}
public Analyzer( ) { }
protected double dx( double x ) {
double h = x / 50.0;
return ((f(x + h) - f(x - h)) / (2 * h));
}
public double evaluate(double x) {
return f( x );
}
public double evaluateDerived( double x ) {
return fd( x );
}
public double solve(double x0) {
double eps = 1, x1 = f(x0), x2 = fd(x0);
do x0 = x0 - ( f( x0 ) / fd( x0 ) );
while ( f( x0 ) > eps );
return x0;
}
}
public class PolyAnalyzer : Analyzer {
private double[] coefs;
public PolyAnalyzer( params double[] coef ) {
coefs = coef;
f = poly;
fd = dx;
}
private double poly( double x ) {
double sum = 0;
for ( int i = 0 ; i < coefs.Length ; i++ ) {
sum += coefs[i] * Math.Pow(x,coefs.Length-1-i);
}
return sum;
}
}
I was trying to think of a way to send poly to the constructor Analyser(Func f), is there a way to do that here? tried something like :
public PolyAnalyzer( params double[] coef ) : base(new Func(poly)){
coefs = coef;
}
but it doesnt compile... compilation error:: An object reference is required for the nonstatic field, method, or property 'member'
Id appriciate a well explained answer, and not just how its done... :)
Upvotes: 0
Views: 1424
Reputation: 25563
In my opinion you're trying to combine object-oriented inheritance and functional programming, and it's not working well in this case.
I would write
public abstract class Analyzer {
protected abstract double Fd(double x);
// ...
}
and override it in the descendant class (if you want to stick with an OO hierarchy). This is classic Strategy Pattern implementation.
To address your comment, if you want Analyzer to be instantiable, use:
public class Analyzer {
protected virtual double Fd(double x)
{
// provide default implementation
}
// ...
}
If you want to stick to functional programming, I would use composition instead of inheritance:
// Does not descend from Analyzer. Could implement IAnalyzer.
public class PolyAnalyzer {
private readonly Analyzer analyzer;
private double[] coefs;
public PolyAnalyzer( params double[] coef ) {
coefs = coef;
analyzer = new Analyzer(poly);
}
public double evaluate(double x) {
return analyzer.evaluate(x);
}
// Implement evaluateDerived and solve through delegation
private double poly( double x ) {
double sum = 0;
for ( int i = 0 ; i < coefs.Length ; i++ ) {
sum += coefs[i] * Math.Pow(x,coefs.Length-1-i);
}
return sum;
}
}
Alternately, if you took @Reed Copsey's advice and switched to Func<double, double>
, you could use closures in a factory method:
public static class PolyAnalyzerFactory {
public static Analyzer Create( params double[] coef ) {
var coefs = coef.ToArray(); // protect against mutations to original array
return new Analyzer(
x =>
{
double sum = 0;
for ( int i = 0 ; i < coefs.Length ; i++ ) {
sum += coefs[i] * Math.Pow(x,coefs.Length-1-i);
}
return sum;
});
}
}
Upvotes: 0
Reputation: 8511
The error you're getting:
An object reference is required for the non-static field, method, or property...
is due to the fact that poly is a member the object that you are creating, it is dependant upon the variables within the PolyAnalyzer
class.
Normally you could resolve this by adding an object reference
like it calls for (i.e. new Func(this.poly)
) however the current instance of the class (this
) isn't available within the context yet. (Your instance is not yet fully realized).
You can, like you have already done in your PolyAnalyzer
constructor, set the values yourself, which would be my suggestion.
Upvotes: 1