1

簡単にするために、次のようなアルゴリズムを計算する数値解析プログラムがあります。

y = ax^3 + bx^2 + cx + d;

実行時に a,b,c,d の値を計算し、次の同等のものを a として渡したいと思いますFunc<double, double>。X の値を設定し、Y を取得できる場所。

y = 12x^3 + 13x^2 + 14x + 15; 

12,13,14,15 は実行時に計算される数値です。

これは、次のように double 配列を渡すことで実行できることを認識していますがFunc<double[], double> 、定数 (多数になる可能性があります) を渡さないようにしています。

これらの数値を実行時に func に設定する方法はありますか?

(できれば、Func<> 自体の a、b、c、d の計算を行わないでください。a、b、c、d の計算は作業の 80% です)

例えば:

a = ...

b = ...

c = ...

Func<x, double> {
     ((const)a) * x^3 +   ((const)b) * x^2 +   ((const)c) * x + 15;
}`

ABCD の評価ごとに、10 個の x を評価します。

4

5 に答える 5

11

あなたが何を求めているのかよくわからないのですが、このようなことを試してみてはいかがでしょうか?

Func<double, double> CreateCalculationFunc()
{
    double a = heavy calculation;
    double b = heavy calculation;
    double c = heavy calculation;
    double d = heavy calculation;

    Func<double, double> calculation = (x) =>
    {
        // You can use the constants in here without passing them as parameters
        return x * (a * b / c - d);
    };

    return calculation;
}

この場合、 を呼び出すだけで、大量の計算を 1 回実行し、変数の計算を実行するためCreateCalculationFunc()に再利用可能な を返すことができます。Func<double,double>

もちろん、これは事前に計算された定数と複数の変数の量に拡張可能です。

于 2009-12-24T08:23:02.230 に答える
2

これは、関数型言語で「カリー化」または「部分適用」と呼ばれるものが必要なように思えます。

与えられたFunc<a, b, c, d, x, result>値を 1 つずつ適用し、パラメーター セットを減らします。

Func<a, b, c, d, x, result>(valueOfA)

署名付きの関数になります

Func<b, c, d, x, result>

引き継ぐことができます。

C# でのカリー化/部分適用に関連するリンク:

または - F# を試してみてください ;)

編集: 上記の参照サイトから作成された短いコード サンプル:

定型コード:

    public static Func<B, R> Partial<A, B, R>(this Func<A, B, R> f, A a) {
        return b => f(a, b);
    }

    public static Func<B, C, R> Partial<A, B, C, R>(this Func<A, B, C, R> f, A a) {
        return (b, c) => f(a, b, c);
    }

    public static Func<B, C, D, R> Partial<A, B, C, D, R>(this Func<A, B, C, D, R> f, A a) {
        return (b, c, d) => f(a, b, c, d);
    }

あなたのコード:

Func<double, double, double, double, double> yourCalculation = (a, b, c, x) => a*Math.Pow(x, 3) + b*Math.Pow(x, 2) + c*x;

var aDefined = yourCalculation.Partial(12);
var bDefined = aDefined.Partial(13);
var cDefined = bDefined.Partial(14);

cDefined は、事前に適用された値を「認識」し、好きなように渡すことができる新しい Func になりました。4 つを超えるパラメーター (つまり、Func<...> に適合しないもの) を持つデリゲートの既製のソリューションを見つけることができませんでしたが、それも可能であるはずです。

この方法では、1 回だけ事前計算を行い、現在行っている方法と同じですが、関数をすべての消費者の最後の部分に絞り込むことができます。

于 2009-12-24T08:39:21.190 に答える
2

Func<double,double>「定数」のプロパティを持つ計算 ( ) メソッドを含むクラスを作成できませんか。次に、プロパティを設定し、デリゲートCalculateとしてメソッドへの参照を使用します。Func<double,double>

public class Calculator
{
    public double A { get; set; };
    public double B { get; set; };
    public double C { get; set; };
    public double D { get; set; };

    public double Calculate(double x)
    {
        return A*x*x*x + B*x*x + C*x + D;
    }
}
于 2009-12-24T08:13:53.580 に答える
0

いくつかの異なる Func<> オーバーロードがあり、5 つのジェネリック パラメーターを持つものを使用できます。最初のパラメーターはKeyValuePairです。

Func<KeyValuePair<double,double>,double,double,double,double>

したがって、a と b を kvp として渡し、c,d と x を他のパラメーターとして渡します。

于 2009-12-24T08:14:02.410 に答える
0

後から考えると、実際にこれを行うことができました。

Class {
    a = ...
    b = ...

    Func Algorithm = (x) => {
        return x*a + x*b;
    }

    return Algorithm;
}

しかし、 Func<> と Action<> を使用するのは初めてだったので、少し混乱しました! ご協力いただきありがとうございます。

于 2009-12-27T21:13:24.580 に答える