Recursive Algebraic
Mr.Bingo
Bingo at Namo.com
Sat Jun 30 10:43:10 UTC 2018
I'm trying to create a vector of vectors(more general than
vectors or matrices).
The idea is that a Vector can contain another Vector or another
type. Vector can be specified to be fixed in length or dynamic
for efficiency. Vector!(T, N) creates a vector of leaf type T and
length N. If N = size_t.max then the vector internally uses a
dynamic array.
Vector is essentially a tree. Norm, dot, and many operators on
Vector are computed recursively. The norm of a vector of vectors
is the norm of the vector of the norm of vectors. This definition
is valid when Vector is a simple Vector but also works for
vectors of vectors. Other operators can be similarly defined.
I believe the problem is that Algebraic only accepts This of the
fixed N. So as of now one can only have vectors of vectors with
size 1 or fixed N.
I also get an error
overload for type 'VariantN!(4u, int, This*)*' hasn't been
specified".
It would be nice if the compiler would construct the missing
handler and give the signature so I could know what I'm doing
wrong, I'm using (This* i) => ; but it does not recognize that.
import std.typecons, std.range, std.array, std.algorithm,
std.variant, std.stdio, std.traits;
struct Vector(T, size_t N = size_t.max) // N could be small value
if it is stored inside the vector as it could be stored as part
of the flags
{
Flags flags; // Contains direction flag(row or column),
normalized, etc
import std.range, std.typecons, std.meta, std.algorithm,
std.conv, std.math;
static if (N == size_t.max) // For size_t.max sets N to be
infinite/dynamic;
{
mixin("Algebraic!(T, This*)[] data;");
@property size_t Length() { return data.length; }
}
else
{
mixin("Algebraic!(T, This*)[N] data;");
static @property size_t Length() { return N; }
}
alias data this;
@property double Norm(size_t n = 2)
{
return iota(0, n).map!((a)
{
return data[a].visit!(
(T i) { return 1; },
(This* i) { return 2000; }
);
}).sum();
}
auto opDispatch(string s, Args...)(Args v)
{
enum index = to!int(s[1..$]);
static if (N == size_t.max) while(index >= data.length) data ~=
T.init;
static if (Args.length == 0)
return data[index];
else static if (Args.length == 1)
{
data[index] = &v[0];
}
}
}
void main()
{
import std.math, std.variant;
Vector!(int, 5) v;
v.x1 = v;
writeln(v.x1);
v.x2 = 4;
v.x3 = 5;
writeln(v.x3);
writeln(v.Norm);
getchar();
}
More information about the Digitalmars-d-learn
mailing list