class design question (inner classes)

coxalan coxalan at web.de
Tue Sep 11 06:39:26 PDT 2007


Hello,

I come from mathematics and I want to create some classes for _fast_ computations in certain algebraic structures (groups, fields, rings, ...).

My hope is that specialization at compile time will give me an advantage over universal computer algebra systems.

I want to have:
1) Objects for the algebraic base structures
2) Some type (class, struct, whatever) for the elements of this structure

For example:
1) a class SymmetricGroup and 2) a class Permutation.

Each instance of type 2) "belongs" to exactly one object of class 1).
But this link should not be stored for each instance of 2). Instead, It should be given statically by the type.

Furthermore, for convenience I really want to have overloaded operators for the objects of 2).


Up to now I tried these two examples:

*** 1 ***
import std.stdio;

class SymmetricGroup {
    const uint degree;

    this(int degreeIn) {
        degree = degreeIn;
    }

    struct Permutation {
        uint data[];
    }

    Permutation createPermutation(uint[] dataIn) {
        Permutation result;
        result.data = dataIn;
        return result;
    }

    Permutation mul(Permutation a, Permutation b) {
        Permutation result;
        result.data.length = degree;
        foreach(int i, uint val; b.data) {
            result.data[i] = a.data[val];
        }
        return result;
    }
}

void main() {
    SymmetricGroup s = new SymmetricGroup(3);
    s.Permutation a = s.createPermutation([0,2,1]);
    s.Permutation b = s.createPermutation([1,2,0]);
    s.Permutation c = s.mul(a,b);
    writefln("%d",c.data);
}
********

The problem with this is that I don't know how to overload the *-Operator such that I can write
s.Permutation c = a * b;
instead of
s.Permutation c = s.mul(a,b);

I cannot add a method "opMul" within the struct "Permutation", because to call the method "mul" I would need a pointer to the outer class "SymmetricGroup", which I don't have.

[Comment: Yes, I could write

        Permutation opMul(Permutation x) {
            Permutation result;
            result.data.length = data.length;
            foreach(int i, uint val; x.data) {
                result.data[i] = data[val];
            }
            return result;
        }

in this particular example, but in general I need information stored in the outer class 1).]


*** 2 ***
import std.stdio;

class SymmetricGroup {
    const uint degree;

    this(int degreeIn) {
        degree = degreeIn;
    }

    class Permutation {
        uint data[];

        this() {
            data.length = degree;
        }

        this(uint[] dataIn) {
            data = dataIn;
        }

        Permutation opMul(Permutation x) {
            return mul(this, x);
        }
    }

    Permutation mul(Permutation a, Permutation b) {
        Permutation result = new Permutation();
        foreach(int i, uint val; b.data) {
            result.data[i] = a.data[val];
        }
        return result;
    }
}

void main() {
    SymmetricGroup s = new SymmetricGroup(3);
    s.Permutation a = s.new Permutation([0,2,1]);
    s.Permutation b = s.new Permutation([1,2,0]);
    s.Permutation c = a * b;
    writefln("%d",c.data);
}
********

This is definitely more elegant than the first example. But here, every object of type "s.Permutation" stores a reference to the object "s", which I want to avoid.

If it was possible to instantiate the object "s" at compile time
(something like
static const SymmetricGroup s = new SymmetricGroup(3);
),
the above mentioned references would not be needed. But unfortunately, It is not possible to instantiate objects at compile time (what's actually the reason for this?).

[A final comment:
I know that I could go without the class SymmetricGroup, and have only objects of type Permutation. But I really want these outer classes, to do constructions like direct products of groups, etc.]


I believe that within the D template toolkit, there must be a solution for my problem, which I simply don't see.
I will appreciate any hint or suggestion.



More information about the Digitalmars-d mailing list