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