getfem-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Getfem-commits] r5056 - /trunk/getfem/src/getfem_generic_assembly.cc


From: logari81
Subject: [Getfem-commits] r5056 - /trunk/getfem/src/getfem_generic_assembly.cc
Date: Mon, 27 Jul 2015 10:24:06 -0000

Author: logari81
Date: Mon Jul 27 12:24:05 2015
New Revision: 5056

URL: http://svn.gna.org/viewcvs/getfem?rev=5056&view=rev
Log:
new explicit tensor format (nested) in the generic assembly language

Modified:
    trunk/getfem/src/getfem_generic_assembly.cc

Modified: trunk/getfem/src/getfem_generic_assembly.cc
URL: 
http://svn.gna.org/viewcvs/getfem/trunk/getfem/src/getfem_generic_assembly.cc?rev=5056&r1=5055&r2=5056&view=diff
==============================================================================
--- trunk/getfem/src/getfem_generic_assembly.cc (original)
+++ trunk/getfem/src/getfem_generic_assembly.cc Mon Jul 27 12:24:05 2015
@@ -572,6 +572,26 @@
         root->parent = 0;
       }
       current_node->nbc1 = current_node->nbc2 = current_node->nbc3 = 0;
+    }
+
+    void zip_matrix(const pga_tree_node source_node) {
+      GMM_ASSERT1(current_node->node_type == GA_NODE_C_MATRIX &&
+                  source_node->node_type == GA_NODE_C_MATRIX,
+                  "Internal error");
+      size_type target_size = current_node->children.size();
+      size_type source_size = source_node->children.size();
+      size_type last_dim_size = target_size/source_size;
+      GMM_ASSERT1(target_size == source_size*last_dim_size,
+                  "Internal error");
+      std::vector<pga_tree_node> new_children;
+      for (size_type i = 0; i < source_size; ++i) {
+        for (size_type j = 0; j < last_dim_size; ++j)
+          new_children.push_back(current_node->children[i*last_dim_size+j]);
+        new_children.push_back(source_node->children[i]);
+      }
+      source_node->children.resize(0); // so that the destructor of source_node
+                                       // will not destruct the children
+      current_node->children = new_children;
     }
 
     void add_op(GA_TOKEN_TYPE op_type, size_type pos) {
@@ -1458,47 +1478,125 @@
           {
             ga_tree sub_tree;
             GA_TOKEN_TYPE r_type;
-            size_type nbc1 = 0, nbc2 = 0, nbc3 = 0, n1 = 0, n2 = 0, n3 = 0;
-            bool foundsemi = false, founddcomma = false, founddsemi = false;
+            size_type nbc1(0), nbc2(0), nbc3(0), n1(0), n2(0), n3(0);
+            size_type tensor_order(1);
+            bool foundcomma(false), foundsemi(false), nested_format(false);
+
             tree.add_matrix(token_pos);
             do {
               r_type = ga_read_term(expr, pos, sub_tree);
-              ++n1; ++n2; ++n3;
-              if (!foundsemi) ++nbc1;
-              if (!founddcomma) ++nbc2;
-              if (!founddsemi) ++nbc3;
-
-              switch(r_type) {
-              case GA_COMMA: break;
-              case GA_SEMICOLON: foundsemi = true; n1 = 0; break;
-              case GA_DCOMMA: founddcomma = true; n2 = 0; n1 = 0; break;
-              case GA_DSEMICOLON:
-                founddsemi = true; n3 = 0; n2 = 0; n1 = 0; break;
-              case GA_RBRACKET:
-                if (n1 != nbc1 || n2 != nbc2 || n3 != nbc3 ||
-                    (founddcomma && !founddsemi) ||
-                    (!founddcomma && founddsemi))
+
+              if (sub_tree.root->node_type == GA_NODE_C_MATRIX) {
+
+                // nested format
+
+                if (r_type != GA_COMMA && r_type != GA_RBRACKET)  // in the 
nested format only "," and "]" are expected
                   ga_throw_error(expr, pos-1, "Bad explicit "
-                                  "vector/matrix/tensor format. ");
-                tree.current_node->nbc1 = nbc1;
-                if (founddcomma) {
-                  tree.current_node->nbc2 = nbc2/nbc1;
-                  tree.current_node->nbc3 = nbc3/nbc2;
+                                 "vector/matrix/tensor format.")
+                else if (sub_tree.root->nbc3 != 1)                // the 
sub-tensor to be merged cannot be of fourth order
+                  ga_throw_error(expr, pos-1, "Definition of explicit "
+                                 "tensors is limitted to the fourth order. "
+                                 "Limit exceeded.")
+                else if (foundsemi ||                             // Cannot 
mix with the non-nested format.
+                         (sub_tree.root->children.size() > 1 &&   // The 
sub-tensor cannot be a column vector [a;b],
+                          sub_tree.root->nbc1 == 1))              // the 
nested format only accepts row vectors [a,b]
+                  ga_throw_error(expr, pos-1, "Bad explicit "     // and 
converts them to column vectors internally
+                                 "vector/matrix/tensor format.")  // (see 
below)
+
+                if (sub_tree.root->children.size() == sub_tree.root->nbc1)
+                  sub_tree.root->nbc1 = 1; // convert a row vector [a,b] to a 
column vector [a;b]
+
+                nested_format = true;
+
+                size_type sub_tensor_order = 3;
+                if (sub_tree.root->nbc1 == 1)
+                  sub_tensor_order = 1;
+                else if (sub_tree.root->nbc2 == 1)
+                  sub_tensor_order = 2;
+
+                if (tensor_order == 1) {
+                  if (nbc1 != 0 || nbc2 != 0 || nbc3 != 0)
+                    ga_throw_error(expr, pos-1, "Bad explicit "
+                                   "vector/matrix/tensor format.");
+                  nbc1 = 1;
+                  nbc2 = sub_tree.root->nbc1;
+                  nbc3 = sub_tree.root->nbc2;
+                  tensor_order = sub_tensor_order + 1;
                 } else {
-                  tree.current_node->nbc2 = tree.current_node->nbc3 = 1;
+                  if ((tensor_order != sub_tensor_order + 1) ||
+                      (tensor_order > 2 && nbc2 != sub_tree.root->nbc1) ||
+                      (tensor_order > 3 && nbc3 != sub_tree.root->nbc2))
+                    ga_throw_error(expr, pos-1, "Bad explicit "
+                                   "vector/matrix/tensor format.");
+                  nbc1 += 1;
                 }
-                break;
-              default:
-                ga_throw_error(expr, pos-1, "The explicit "
-                                "vector/matrix/tensor components should be "
-                                "separated by ',', ';', ',,' and ';;' and "
-                                "be ended by ']'.");
-                break;
+
+                tree.zip_matrix(sub_tree.root);
+                sub_tree.clear();
+                if (r_type == GA_RBRACKET) {
+                  tree.current_node->nbc1 = nbc1;
+                  tree.current_node->nbc2 = nbc2;
+                  tree.current_node->nbc3 = nbc3;
+                }
+
+              } else {
+
+                // non-nested format
+
+                tree.add_sub_tree(sub_tree);
+
+                ++n1; ++n2; ++n3;
+                if (tensor_order < 2) ++nbc1;
+                if (tensor_order < 3) ++nbc2;
+                if (tensor_order < 4) ++nbc3;
+
+                if (r_type == GA_COMMA) {
+                  if (!foundcomma && tensor_order > 1)
+                    ga_throw_error(expr, pos-1, "Bad explicit "
+                                   "vector/matrix/tensor format.");
+                  foundcomma = true;
+                } else if (r_type == GA_SEMICOLON) {
+                  if (n1 != nbc1)
+                    ga_throw_error(expr, pos-1, "Bad explicit "
+                                   "vector/matrix/tensor format.");
+                  n1 = 0;
+                  tensor_order = std::max(tensor_order, size_type(2));
+                } else if (r_type == GA_DCOMMA) {
+                  if (n1 != nbc1 || n2 != nbc2)
+                    ga_throw_error(expr, pos-1, "Bad explicit "
+                                   "vector/matrix/tensor format.");
+                  foundsemi = true;
+                  n2 = n1 = 0;
+                  tensor_order = std::max(tensor_order, size_type(3));
+                } else if (r_type == GA_DSEMICOLON) {
+                  if (n1 != nbc1 || n2 != nbc2 || n3 != nbc3 ||
+                      tensor_order < 3)
+                    ga_throw_error(expr, pos-1, "Bad explicit "
+                                   "vector/matrix/tensor format.");
+                  n3 = n2 = n1 = 0;
+                  tensor_order = std::max(tensor_order, size_type(4));
+                } else if (r_type == GA_RBRACKET) {
+                  if (n1 != nbc1 || n2 != nbc2 || n3 != nbc3 ||
+                      tensor_order == 3)
+                    ga_throw_error(expr, pos-1, "Bad explicit "
+                                   "vector/matrix/tensor format.");
+                  tree.current_node->nbc1 = nbc1;
+                  if (tensor_order == 4) {
+                    tree.current_node->nbc2 = nbc2/nbc1;
+                    tree.current_node->nbc3 = nbc3/nbc2;
+                  } else {
+                    tree.current_node->nbc2 = tree.current_node->nbc3 = 1;
+                  }
+                } else {
+                  ga_throw_error(expr, pos-1, "The explicit "
+                                 "vector/matrix/tensor components should be "
+                                 "separated by ',', ';', ',,' and ';;' and "
+                                 "be ended by ']'.");
+                }
               }
 
-              tree.add_sub_tree(sub_tree);
-
             } while (r_type != GA_RBRACKET);
+
             state = 2;
           }
           break;
@@ -6279,30 +6377,33 @@
         if (nbc1 == 1 && nbc2 == 1 && nbc3 == 1 && nbl == 1) {
           pnode->t.adjust_sizes(mi);
           if (all_cte) pnode->t[0] = child0->t[0];
-        } else if (nbc1 == 1 && nbc2 == 1 && nbc3 == 1) {
+        } else {
           mi.push_back(nbl);
+          if (nbc3 != 1) mi.push_back(nbc3);
+          if (nbc2 != 1) mi.push_back(nbc2);
+          if (nbc1 != 1) mi.push_back(nbc1);
           pnode->t.adjust_sizes(mi);
-          if (all_cte)
-            for (size_type i = 0; i < nbl; ++i)
-              pnode->t[i] = pnode->children[i]->t[0];
-        } else if (nbc2 == 1 && nbc3 == 1) {
-          mi.push_back(nbl); mi.push_back(nbc1);
-          pnode->t.adjust_sizes(mi);
-          if (all_cte) // TODO: verify order
-            for (size_type i = 0; i < nbl; ++i)
-              for (size_type j = 0; j < nbc1; ++j)
-                pnode->t(i,j) = pnode->children[i*nbc1+j]->t[0];
-        } else {
-          mi.push_back(nbl); mi.push_back(nbc3);
-          mi.push_back(nbc2); mi.push_back(nbc1);
-          pnode->t.adjust_sizes(mi);
-          size_type n = 0;
-          if (all_cte) // TODO: verify order
-            for (size_type i = 0; i < nbl; ++i)
-              for (size_type j = 0; j < nbc3; ++j)
-                for (size_type k = 0; k < nbc2; ++k)
-                  for (size_type l = 0; l < nbc1; ++l)
-                    pnode->t(i,j,k,l) = pnode->children[n++]->t[0];
+          if (all_cte) {
+            size_type n = 0;
+            if (nbc1 == 1 && nbc2 == 1 && nbc3 == 1)
+              for (size_type i = 0; i < nbl; ++i)
+                pnode->t[i] = pnode->children[i]->t[0];
+            else if (nbc2 == 1 && nbc3 == 1) // TODO: verify order
+              for (size_type i = 0; i < nbl; ++i)
+                for (size_type j = 0; j < nbc1; ++j)
+                  pnode->t(i,j) = pnode->children[n++]->t[0];
+            else if (nbc3 == 1) // TODO: verify order
+              for (size_type i = 0; i < nbl; ++i)
+                for (size_type j = 0; j < nbc2; ++j)
+                  for (size_type k = 0; k < nbc1; ++k)
+                    pnode->t(i,j,k) = pnode->children[n++]->t[0];
+            else // TODO: verify order
+              for (size_type i = 0; i < nbl; ++i)
+                for (size_type j = 0; j < nbc3; ++j)
+                  for (size_type k = 0; k < nbc2; ++k)
+                    for (size_type l = 0; l < nbc1; ++l)
+                      pnode->t(i,j,k,l) = pnode->children[n++]->t[0];
+          }
         }
         if (all_cte) tree.clear_children(pnode);
       }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]