diff --git a/tests/test_ASTNodeListAffectationExpressionBuilder.cpp b/tests/test_ASTNodeListAffectationExpressionBuilder.cpp
index ad2684560290f6b1e7f499ca9f319d11bd529d97..62b584eaa1f9e0bac8b05ae8f8d1072cf4e46bae 100644
--- a/tests/test_ASTNodeListAffectationExpressionBuilder.cpp
+++ b/tests/test_ASTNodeListAffectationExpressionBuilder.cpp
@@ -199,6 +199,56 @@ let (x1,x2,x3,x) : R^1*R^2*R^3*R,
       CHECK_AST(data, result);
     }
 
+    SECTION("without conversion R^1x1*R^2x2*R^3x3*R")
+    {
+      std::string_view data = R"(
+let a:R^1x1, a = 0;
+let b:R^2x2, b = (1, 2, 3, 4);
+let c:R^3x3, c = (9, 8, 7, 6, 5, 4, 3, 2, 1);
+let (x1,x2,x3,x) : R^1x1*R^2x2*R^3x3*R,
+    (x1,x2,x3,x) = (a, b, c, 2);
+)";
+
+      std::string_view result = R"(
+(root:ASTNodeListProcessor)
+ +-(language::eq_op:AffectationProcessor<language::eq_op, TinyMatrix<1ul, double>, long>)
+ |   +-(language::name:a:NameProcessor)
+ |   `-(language::integer:0:ValueProcessor)
+ +-(language::eq_op:AffectationToTinyMatrixFromListProcessor<language::eq_op, TinyMatrix<2ul, double> >)
+ |   +-(language::name:b:NameProcessor)
+ |   `-(language::expression_list:ASTNodeExpressionListProcessor)
+ |       +-(language::integer:1:ValueProcessor)
+ |       +-(language::integer:2:ValueProcessor)
+ |       +-(language::integer:3:ValueProcessor)
+ |       `-(language::integer:4:ValueProcessor)
+ +-(language::eq_op:AffectationToTinyMatrixFromListProcessor<language::eq_op, TinyMatrix<3ul, double> >)
+ |   +-(language::name:c:NameProcessor)
+ |   `-(language::expression_list:ASTNodeExpressionListProcessor)
+ |       +-(language::integer:9:ValueProcessor)
+ |       +-(language::integer:8:ValueProcessor)
+ |       +-(language::integer:7:ValueProcessor)
+ |       +-(language::integer:6:ValueProcessor)
+ |       +-(language::integer:5:ValueProcessor)
+ |       +-(language::integer:4:ValueProcessor)
+ |       +-(language::integer:3:ValueProcessor)
+ |       +-(language::integer:2:ValueProcessor)
+ |       `-(language::integer:1:ValueProcessor)
+ `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
+     +-(language::name_list:FakeProcessor)
+     |   +-(language::name:x1:NameProcessor)
+     |   +-(language::name:x2:NameProcessor)
+     |   +-(language::name:x3:NameProcessor)
+     |   `-(language::name:x:NameProcessor)
+     `-(language::expression_list:ASTNodeExpressionListProcessor)
+         +-(language::name:a:NameProcessor)
+         +-(language::name:b:NameProcessor)
+         +-(language::name:c:NameProcessor)
+         `-(language::integer:2:ValueProcessor)
+)";
+
+      CHECK_AST(data, result);
+    }
+
     SECTION("Zero initialization")
     {
       std::string_view data = R"(
@@ -223,6 +273,30 @@ let  (x1,x2,x3,x) : R^1*R^2*R^3*R, (x1,x2,x3,x) = (0, 0, 0, 0);
       CHECK_AST(data, result);
     }
 
+    SECTION("Zero initialization")
+    {
+      std::string_view data = R"(
+let  (x1,x2,x3,x) : R^1x1*R^2x2*R^3x3*R, (x1,x2,x3,x) = (0, 0, 0, 0);
+)";
+
+      std::string_view result = R"(
+(root:ASTNodeListProcessor)
+ `-(language::eq_op:ListAffectationProcessor<language::eq_op>)
+     +-(language::name_list:FakeProcessor)
+     |   +-(language::name:x1:NameProcessor)
+     |   +-(language::name:x2:NameProcessor)
+     |   +-(language::name:x3:NameProcessor)
+     |   `-(language::name:x:NameProcessor)
+     `-(language::expression_list:ASTNodeExpressionListProcessor)
+         +-(language::integer:0:ValueProcessor)
+         +-(language::integer:0:ValueProcessor)
+         +-(language::integer:0:ValueProcessor)
+         `-(language::integer:0:ValueProcessor)
+)";
+
+      CHECK_AST(data, result);
+    }
+
     SECTION("from function")
     {
       std::string_view data = R"(
diff --git a/tests/test_FunctionArgumentConverter.cpp b/tests/test_FunctionArgumentConverter.cpp
index dfa637bf735c66e02dab8c4345ccbf74e7a1e069..b0a191fc5c2474a65c34c8c5e5b822b5046cb8a2 100644
--- a/tests/test_FunctionArgumentConverter.cpp
+++ b/tests/test_FunctionArgumentConverter.cpp
@@ -75,6 +75,32 @@ TEST_CASE("FunctionArgumentConverter", "[language]")
                                                                             " unexpected aggregate value type");
   }
 
+  SECTION("FunctionTinyMatrixArgumentConverter")
+  {
+    const TinyMatrix<3> x3{1.7, 2.9, -3, 4, 5.2, 6.1, -7, 8.3, 9.05};
+    FunctionTinyMatrixArgumentConverter<TinyMatrix<3>, TinyMatrix<3>> converter0{0};
+    converter0.convert(execution_policy, TinyMatrix{x3});
+
+    const double x1 = 6.3;
+    FunctionTinyMatrixArgumentConverter<TinyMatrix<1>, double> converter1{1};
+    converter1.convert(execution_policy, double{x1});
+
+    AggregateDataVariant values{std::vector<DataVariant>{6.3, 3.2, 4ul, 2.3, -3.1, 6.7, 3.6, 2ul, 1.1}};
+    FunctionTinyMatrixArgumentConverter<TinyMatrix<3>, TinyMatrix<3>> converter2{2};
+    converter2.convert(execution_policy, values);
+
+    REQUIRE(std::get<TinyMatrix<3>>(execution_policy.currentContext()[0]) == x3);
+    REQUIRE(std::get<TinyMatrix<1>>(execution_policy.currentContext()[1]) == TinyMatrix<1>{x1});
+    REQUIRE(std::get<TinyMatrix<3>>(execution_policy.currentContext()[2]) ==
+            TinyMatrix<3>{6.3, 3.2, 4ul, 2.3, -3.1, 6.7, 3.6, 2ul, 1.1});
+
+    AggregateDataVariant bad_values{std::vector<DataVariant>{6.3, 3.2, std::string{"bar"}, true}};
+
+    REQUIRE_THROWS_WITH(converter2.convert(execution_policy, bad_values), std::string{"unexpected error: "} +
+                                                                            demangle<std::string>() +
+                                                                            " unexpected aggregate value type");
+  }
+
   SECTION("FunctionTupleArgumentConverter")
   {
     const TinyVector<3> x3{1.7, 2.9, -3};
diff --git a/tests/test_FunctionProcessor.cpp b/tests/test_FunctionProcessor.cpp
index 59386bbae65a807841ead561899e0a61719a82d3..64fe6776ee427db8b2e3641ee952cff2477279ca 100644
--- a/tests/test_FunctionProcessor.cpp
+++ b/tests/test_FunctionProcessor.cpp
@@ -406,6 +406,79 @@ let fx:R^3, fx = f(3);
     }
   }
 
+  SECTION("R^dxd functions (single value)")
+  {
+    SECTION("  R^1x1 -> R^1x1")
+    {
+      std::string_view data = R"(
+let f : R^1x1 -> R^1x1, x -> 2*x;
+let x:R^1x1, x = 3;
+
+let fx:R^1x1, fx = f(x);
+)";
+      CHECK_FUNCTION_EVALUATION_RESULT(data, "fx", (2 * TinyMatrix<1>{3}));
+    }
+
+    SECTION("  R^2x2 -> R^2x2")
+    {
+      std::string_view data = R"(
+let f : R^2x2 -> R^2x2, x -> 2*x;
+let x:R^2x2, x = (3, 7, 6, -2);
+
+let fx:R^2x2, fx = f(x);
+)";
+      CHECK_FUNCTION_EVALUATION_RESULT(data, "fx", (2 * TinyMatrix<2>{3, 7, 6, -2}));
+    }
+
+    SECTION("  R^3x3 -> R^3x3")
+    {
+      std::string_view data = R"(
+let f : R^3x3 -> R^3x3, x -> 2*x;
+let x:R^3x3, x = (2, 4, 7, 1, 3, 5, -6, 2, -3);
+
+let fx:R^3x3, fx = f(x);
+)";
+      CHECK_FUNCTION_EVALUATION_RESULT(data, "fx", (2 * TinyMatrix<3>{2, 4, 7, 1, 3, 5, -6, 2, -3}));
+    }
+
+    SECTION("  R -> R^1x1")
+    {
+      std::string_view data = R"(
+let f : R -> R^1x1, x -> 2*x;
+let x:R, x = 3;
+
+let fx:R^1x1, fx = f(x);
+)";
+      CHECK_FUNCTION_EVALUATION_RESULT(data, "fx", (2 * TinyMatrix<1>{3}));
+    }
+
+    SECTION("  R*R -> R^2x2")
+    {
+      std::string_view data = R"(
+let f : R*R -> R^2x2, (x,y) -> (2*x, 3*y, 5*(x-y), 2*x-y);
+let fx:R^2x2, fx = f(2, 3);
+)";
+
+      const double x = 2;
+      const double y = 3;
+      CHECK_FUNCTION_EVALUATION_RESULT(data, "fx", (TinyMatrix<2>{2 * x, 3 * y, 5 * (x - y), 2 * x - y}));
+    }
+
+    SECTION("  R -> R^3x3")
+    {
+      std::string_view data = R"(
+let f : R -> R^3x3, x -> (x, 2*x, x*x, 3*x, 2+x, x-1, x+0.5, 2*x-1, 1/x);
+
+let fx:R^3x3, fx = f(3);
+)";
+
+      const double x = 3;
+      CHECK_FUNCTION_EVALUATION_RESULT(data, "fx",
+                                       (TinyMatrix<3>{x, 2 * x, x * x, 3 * x, 2 + x, x - 1, x + 0.5, 2 * x - 1,
+                                                      1 / x}));
+    }
+  }
+
   SECTION("multi-expression functions (using R^d)")
   {
     SECTION("  R -> R*R^1*R^2*R^3")
@@ -479,6 +552,89 @@ let (x, x1, x2, x3):R*R^1*R^2*R^3, (x, x1, x2, x3) = f(y2, 0);
     }
   }
 
+  SECTION("multi-expression functions (using R^dxd)")
+  {
+    SECTION("  R -> R*R^1x1*R^2x2*R^3x3")
+    {
+      std::string_view data = R"(
+let f : R -> R*R^1x1*R^2x2*R^3x3, x -> (x+1, 2*x, (x-2, x+2, 3, 2), (1, 0.5*x, x*x, x+1, 1/x, 2, x*x, 2*x-1, 3*x));
+
+let  (x, x11, x22, x33):R*R^1x1*R^2x2*R^3x3, (x, x11, x22, x33) = f(3);
+)";
+
+      const double x = 3;
+      CHECK_FUNCTION_EVALUATION_RESULT(data, "x", (double{x + 1}));
+      CHECK_FUNCTION_EVALUATION_RESULT(data, "x11", (TinyMatrix<1>{2 * x}));
+      CHECK_FUNCTION_EVALUATION_RESULT(data, "x22", (TinyMatrix<2>{x - 2, x + 2, 3, 2}));
+      CHECK_FUNCTION_EVALUATION_RESULT(data, "x33",
+                                       (TinyMatrix<3>{1, 0.5 * x, x * x, x + 1, 1 / x, 2, x * x, 2 * x - 1, 3 * x}));
+    }
+
+    SECTION("  R^2x2*R^3x3 -> R*R^1x1*R^2x2*R^3x3")
+    {
+      std::string_view data = R"(
+let f : R^2x2*R^3x3 -> R*R^1x1*R^2x2*R^3x3,
+       (x22, x33) -> (x22[0,0]+x33[2,0], x33[1,2], (x33[0,1], x22[1,1], x22[0,0], x33[2,2]), x22[0,0]*x33);
+
+let y22:R^2x2, y22 = (2.3, 4.1, 6, -3);
+let y33:R^3x3, y33 = (1.2, 1.3, 2.1, 3.2, -1.5, 2.3, -0.2, 3.1, -2.6);
+let(x, x11, x22, x33) : R*R^1x1*R^2x2*R^3x3, (x, x11, x22, x33) = f(y22, y33);
+)";
+
+      const TinyMatrix<2> x22{2.3, 4.1, 6, -3};
+      const TinyMatrix<3> x33{1.2, 1.3, 2.1, 3.2, -1.5, 2.3, -0.2, 3.1, -2.6};
+      CHECK_FUNCTION_EVALUATION_RESULT(data, "x", (double{x22(0, 0) + x33(2, 0)}));
+      CHECK_FUNCTION_EVALUATION_RESULT(data, "x11", (TinyMatrix<1>{x33(1, 2)}));
+      CHECK_FUNCTION_EVALUATION_RESULT(data, "x22", (TinyMatrix<2>{x33(0, 1), x22(1, 1), x22(0, 0), x33(2, 2)}));
+      CHECK_FUNCTION_EVALUATION_RESULT(data, "x33", (TinyMatrix<3>{x22(0, 0) * x33}));
+    }
+
+    SECTION("  R^2x2*R^3x3 -> R*R^1x1*R^2x2*R^3x3 [with 0 as argument]")
+    {
+      std::string_view data = R"(
+let f : R^2x2*R^3x3 -> R*R^1x1*R^2x2*R^3x3,
+       (x22, x33) -> (x22[0,0]+x33[2,1], x33[1,2], (x33[0,1], x22[1,0], x22[0,1], x33[2,2]),
+                      (x22[1,0], x33[0,2]+x22[1,1], x33[2,2],
+                       x33[2,0], x33[2,0]+x22[0,0], x33[1,1],
+                       x33[2,1], x33[1,2]+x22[1,1], x33[0,0]));
+
+let y22:R^2x2, y22 = (2.3, 4.1, 3.1, 1.7);
+let y33:R^3x3, y33 = (2.7, 3.1, 2.1,
+                      0.3, 1.2, 1.6,
+                      1.7, 2.2, 1.4);
+let (x, x11, x22, x33) : R*R^1x1*R^2x2*R^3x3, (x, x11, x22, x33) = f(y22, y33);
+)";
+
+      TinyMatrix<2> x22{2.3, 4.1, 3.1, 1.7};
+      TinyMatrix<3> x33{2.7, 3.1, 2.1, 0.3, 1.2, 1.6, 1.7, 2.2, 1.4};
+      CHECK_FUNCTION_EVALUATION_RESULT(data, "x", (double{x22(0, 0) + x33(2, 1)}));
+      CHECK_FUNCTION_EVALUATION_RESULT(data, "x11", (TinyMatrix<1>{x33(1, 2)}));
+      CHECK_FUNCTION_EVALUATION_RESULT(data, "x22", (TinyMatrix<2>{x33(0, 1), x22(1, 0), x22(0, 1), x33(2, 2)}));
+      CHECK_FUNCTION_EVALUATION_RESULT(data, "x33",
+                                       (TinyMatrix<3>{x22(1, 0), x33(0, 2) + x22(1, 1), x33(2, 2), x33(2, 0),
+                                                      x33(2, 0) + x22(0, 0), x33(1, 1), x33(2, 1),
+                                                      x33(1, 2) + x22(1, 1), x33(0, 0)}));
+    }
+
+    SECTION("  R^2x2*R^3x3 -> R*R^1x1*R^2x2*R^3x3 [with 0 in result]")
+    {
+      std::string_view data = R"(
+let f : R^2x2*R^3x3 -> R*R^1x1*R^2x2*R^3x3,
+       (x22, x33) -> (x22[0,0]+x33[2,0], x33[1,1], 0, 0);
+
+let y22:R^2x2, y22 = (2.3, 4.1, 3.1, 1.7);
+let (x, x11, x22, x33):R*R^1x1*R^2x2*R^3x3, (x, x11, x22, x33) = f(y22, 0);
+)";
+
+      TinyMatrix<2> x22{2.3, 4.1, 3.1, 1.7};
+      TinyMatrix<3> x33{zero};
+      CHECK_FUNCTION_EVALUATION_RESULT(data, "x", (double{x22(0, 0) + x33(2, 0)}));
+      CHECK_FUNCTION_EVALUATION_RESULT(data, "x11", (TinyMatrix<1>{x33(1, 1)}));
+      CHECK_FUNCTION_EVALUATION_RESULT(data, "x22", (TinyMatrix<2>{zero}));
+      CHECK_FUNCTION_EVALUATION_RESULT(data, "x33", (TinyMatrix<3>{zero}));
+    }
+  }
+
   SECTION("function composition")
   {
     SECTION("N -> N -> R")
@@ -518,7 +674,6 @@ let x:R, x = pow(f(2));
     SECTION("R -> R^2 -> R")
     {
       std::string_view data = R"(
-import math;
 let f : R -> R^2, x -> (x+1, x*2);
 let g : R^2 -> R, x -> x[0] + x[1];
 
@@ -532,7 +687,6 @@ let x:R, x = g(f(3));
     SECTION("R -> R^2*R^3 -> R")
     {
       std::string_view data = R"(
-import math;
 let f : R -> R^2*R^3, x -> ((x+1, x*2), (6*x, 7-x, x/2.3));
 let g : R^2*R^3 -> R, (x, y) -> x[0]*x[1] + y[0]*y[1]-y[2];
 
@@ -542,5 +696,37 @@ let x:R, x = g(f(3));
       double x0 = 3;
       CHECK_FUNCTION_EVALUATION_RESULT(data, "x", double{(x0 + 1) * x0 * 2 + 6 * x0 * (7 - x0) - x0 / 2.3});
     }
+
+    SECTION("R -> R^2x2 -> R")
+    {
+      std::string_view data = R"(
+let f : R -> R^2x2, x -> (x+1, x*2, x-1, x);
+let g : R^2x2 -> R, A -> A[0,0] + 2*A[1,1] + 3*A[0,1]+ A[1, 0];
+
+let x:R, x = g(f(3));
+)";
+
+      const double x = 3;
+      const TinyMatrix<2> A{x + 1, x * 2, x - 1, x};
+      CHECK_FUNCTION_EVALUATION_RESULT(data, "x", double{A(0, 0) + 2 * A(1, 1) + 3 * A(0, 1) + A(1, 0)});
+    }
+
+    SECTION("R -> R^2x2*R^3x3 -> R")
+    {
+      std::string_view data = R"(
+let f : R -> R^2x2*R^3x3, x -> ((x+1, x*2, x-1, x), (6*x, 7-x, x/2.3, -x, 2*x, x/2.5, x*x, 2*x, x));
+let g : R^2x2*R^3x3 -> R, (A22, A33) -> A22[0,0]*A22[1,1] + (A33[0,0]*A33[1,0]-A33[2,2])*A22[0,1]-A33[2,0]*A33[0,2]-A22[1,1];
+
+let x:R, x = g(f(3));
+)";
+
+      const double x = 3;
+      const TinyMatrix<2> A22{x + 1, x * 2, x - 1, x};
+      const TinyMatrix<3> A33{6 * x, 7 - x, x / 2.3, -x, 2 * x, x / 2.5, x * x, 2 * x, x};
+
+      CHECK_FUNCTION_EVALUATION_RESULT(data, "x",
+                                       double{A22(0, 0) * A22(1, 1) + (A33(0, 0) * A33(1, 0) - A33(2, 2)) * A22(0, 1) -
+                                              A33(2, 0) * A33(0, 2) - A22(1, 1)});
+    }
   }
 }
diff --git a/tests/test_ListAffectationProcessor.cpp b/tests/test_ListAffectationProcessor.cpp
index 2b24f5e3ed3b1fe5e23938bc4855b269ce3dc2a5..0dc1b8d77c0e6dc23cb2681c30e8006d9e939f86 100644
--- a/tests/test_ListAffectationProcessor.cpp
+++ b/tests/test_ListAffectationProcessor.cpp
@@ -75,12 +75,16 @@ TEST_CASE("ListAffectationProcessor", "[language]")
 {
   SECTION("ListAffectations")
   {
-    SECTION("R*R^2*string")
+    SECTION("R*R^2*R^2x2*string")
     {
-      CHECK_AFFECTATION_RESULT(R"(let (x,u,s): R*R^2*string, (x,u,s) = (1.2, (2,3), "foo");)", "x", double{1.2});
-      CHECK_AFFECTATION_RESULT(R"(let (x,u,s): R*R^2*string, (x,u,s) = (1.2, (2,3), "foo");)", "u",
+      CHECK_AFFECTATION_RESULT(R"(let (x,u,A,s): R*R^2*R^2x2*string, (x,u,A,s) = (1.2, (2,3), (4,3,2,1), "foo");)", "x",
+                               double{1.2});
+      CHECK_AFFECTATION_RESULT(R"(let (x,u,A,s): R*R^2*R^2x2*string, (x,u,A,s) = (1.2, (2,3), (4,3,2,1), "foo");)", "u",
                                (TinyVector<2>{2, 3}));
-      CHECK_AFFECTATION_RESULT(R"(let (x,u,s): R*R^2*string, (x,u,s) = (1.2, (2,3), "foo");)", "s", std::string{"foo"});
+      CHECK_AFFECTATION_RESULT(R"(let (x,u,A,s): R*R^2*R^2x2*string, (x,u,A,s) = (1.2, (2,3), (4,3,2,1), "foo");)", "A",
+                               (TinyMatrix<2>{4, 3, 2, 1}));
+      CHECK_AFFECTATION_RESULT(R"(let (x,u,A,s): R*R^2*R^2x2*string, (x,u,A,s) = (1.2, (2,3), (4,3,2,1), "foo");)", "s",
+                               std::string{"foo"});
     }
 
     SECTION("compound with string conversion")
@@ -114,6 +118,13 @@ TEST_CASE("ListAffectationProcessor", "[language]")
       CHECK_AFFECTATION_RESULT(R"(let (x,y,z):R^3*R^2*R^1, (x,y,z) = (0,0,0);)", "z", (TinyVector<1>{zero}));
     }
 
+    SECTION("compound R^dxd from '0'")
+    {
+      CHECK_AFFECTATION_RESULT(R"(let (x,y,z):R^3x3*R^2x2*R^1x1, (x,y,z) = (0,0,0);)", "x", (TinyMatrix<3>{zero}));
+      CHECK_AFFECTATION_RESULT(R"(let (x,y,z):R^3x3*R^2x2*R^1x1, (x,y,z) = (0,0,0);)", "y", (TinyMatrix<2>{zero}));
+      CHECK_AFFECTATION_RESULT(R"(let (x,y,z):R^3x3*R^2x2*R^1x1, (x,y,z) = (0,0,0);)", "z", (TinyMatrix<1>{zero}));
+    }
+
     SECTION("compound with subscript values")
     {
       CHECK_AFFECTATION_RESULT(R"(let x:R^3; (x[0], x[2], x[1]) = (4, 6, 5);)", "x", (TinyVector<3>{4, 5, 6}));