2

我正在尝试考虑如何使用面向对象的方法正确解决这个问题。语言并不重要——我其实很想写代码,但我更关心的是一般原则。

我想实现一个字段:操作 +、-、* 和 / 操作的“数字”集合。此外,我希望能够实现更高的操作,例如 ^ 和循环查找,其中 (1) 不需要为给定字段定义,但如果需要,可以覆盖 (2),例如出于效率原因。

这就是问题所在。不好申报

FieldElement power (FieldElement base, FieldElement exponent)

因为我想要类型安全:不可能将有限域的成员添加到整数中。

也许我真正在寻找的是元对象或超级接口,或者将不同类联系在一起的东西(一个用于整数,一个用于 7-adics,一个用于有限域 F_4,等等)。或者也许有更好的东西。

NB 代码在答案中受到欢迎(甚至鼓励),如果它有启发性的话,但声明可能就足够了:大概这里的每个人都可以为至少几个领域写出明显的方法。


我将提到其他对我很重要但(显然)与主要 OO 问题无关的条件:我不希望字段元素携带它们的类型信息,而且我希望它们是轻量级的(因为我可能需要处理大型字段元素数组)。这些需求可能无法实现——尽管坦率地说,我更可能在这里放弃面向对象而不是效率。但是无论如何,我都会很感激答案,因为我有兴趣了解这些问题,即使除了手头的特定问题。

4

2 回答 2

2

这称为二元法问题。快速谷歌搜索将显示一些(大量)信息。特别是,Luca Cardelli 等人的文章“On binary methods”对这个主题进行了彻底的处理。

您可能想学习一些 Haskell,以了解实用的编程语言如何处理此问题。

编辑洛卢卡→卢卡。该死的小手机屏幕和更小的键盘;)

于 2012-05-17T02:17:00.727 回答
1

之前尝试过用C#来表达这些概念,但是遇到了语言障碍:语言不够丰富,或者不够具体。例如,如果我这样定义一个字段的元素:

public abstract class FieldElement 
{
    public abstract FieldElement Add(FieldElement another);
    public abstract FieldElement SumInvert();
    public abstract FieldElement MultiplicationInvert();
    public abstract FieldElement MultiplyBy(FieldElement another);
    public abstract FieldElement One; //Multiplication neutral element
    public abstract FieldElement Zero; //Addition neutral element

    public FieldElement Subtract(FieldElement another)
    {
        return this.Add(another.SumInvert());
    }

    public FieldElement Divide(FieldElement another)
    {
        return this.MultiplyBy(another.MultiplicationInvert());
    }
    public virtual FieldElement Power(uint b)
    {
        if (b == 0)
            return this.One;
        else
        {
            FieldElement result = this;
            for (int i = 0; i < b - 1; i++)
                result = result.MultiplyBy(result);
            return result;
        }
    }
}

然后我像这样定义实数:

public class RealNumber : FieldElement
{
    public double Value { get; set; }

    public RealNumber(double value)
    {
        this.Value = value;
    }
    public override FieldElement Power(uint b)
    {
        return new RealNumber(Math.Pow(Value, b));
    }
    public override FieldElement Add(FieldElement another)
    {
        if (another.GetType() != typeof(RealNumber)) //Ugly typecast to enforce type-safety
            throw new ArgumentException("RealNumber expected in Add method");

        return new RealNumber(Value + (another as RealNumber).Value);
    }
}

然后我可以定义对字段元素的一般操作(通过使用泛型):

public class FieldOperations<T> where T: FieldElement 
{
    public T Add(T a, T b)        
    {
        return a.Add(b) as T;
    }
    public T Multiply(T a, T b)
    {
        return a.MultiplyBy(b) as T;
    }
    public T Subtract(T a, T b)
    {
        return a.Subtract(b) as T;
    }
    public T Divide(T a, T b)
    {
        return a.Divide(b) as T;
    }
    public T Power(T a, uint b)
    {
        return a.Power(b) as T;
    }   
}

我将在代码中这样使用它:

public class TestFieldOperations
{
    public static void TestAddRealNumbers()
    {
        FieldOperations<RealNumber> operations = new FieldOperations<RealNumber>();
        RealNumber a = new RealNumber(0.5);
        RealNumber b = new RealNumber(0.7);
        RealNumber c = operations.Add(a, b);
        RealNumber d = operations.Power(c, 3);
    }
}

同样,我可以在向量上使用 FieldOperations,在 InvMatrix 上使用 FieldOperations...

能够以类型安全和面向对象的方式抽象字段操作的概念可能非常强大:能够在同一抽象级别处理数字、向量和(可逆)矩阵算术。

于 2012-05-17T02:43:06.507 回答