@@ -364,18 +364,24 @@ void evaluate::merge_components(iterator it1, iterator it2)
364364 // we can be assured that the free indices match; they just may not be
365365 // in the same order).
366366
367+ #ifdef DEBUG
368+ std::cerr << " merge_components on " << Ex (it1) << " and " << Ex (it2) << std::endl;
369+ #endif
370+
367371 assert (*it1->name ==" \\ components" );
368372 assert (*it2->name ==" \\ components" );
369373 sibling_iterator sib1=tr.end (it1);
370374 --sib1;
371375 sibling_iterator sib2=tr.end (it2);
372376 --sib2;
377+ assert (*sib1->name ==" \\ comma" );
378+ assert (*sib2->name ==" \\ comma" );
373379
374- // We cannot directly compare the lhs of this equals node with the lhs
375- // of the equals node of the other components node, because the index
376- // order on the two components nodes may be different. We first
377- // have to ensure that the orders are the same (but only, of course)
378- // if we have anything to permutate in the first place.
380+ // We cannot directly compare the lhs of the equals nodes of it1
381+ // with the lhs of the equals node of it2 , because the index order
382+ // on the two components nodes may be different. We first have to
383+ // ensure that the orders are the same (but only, of course) if we
384+ // have anything to permutate in the first place.
379385
380386 if (*tr.begin (it1)->name !=" \\ comma" ) {
381387 // Look at all indices on the two components nodes. Find
@@ -384,14 +390,20 @@ void evaluate::merge_components(iterator it1, iterator it2)
384390 Perm perm;
385391 perm.find (tr.begin (it2), sib2, tr.begin (it1), sib1);
386392
387- // perm.apply(tr.begin(it2), sib2);
388- // std::cerr << "after permutation " << Ex(tr) << std::endl;
389-
393+ // For each \equals node in the it2 comma node, permute
394+ // the values so they agree with the index order on it1.
390395 cadabra::do_list (tr, sib2, [&](Ex::iterator nd) {
391- auto lhs2 = tr.begin (nd);
392- perm.apply (tr.begin (lhs2), tr.end (lhs2));
396+ // nd is an \equals node.
397+ assert (*nd->name ==" \\ equals" );
398+ auto comma = tr.begin (nd);
399+ assert (*comma->name ==" \\ comma" );
400+ perm.apply (tr.begin (comma), tr.end (comma));
393401 return true ;
394402 });
403+
404+ #ifdef DEBUG
405+ std::cerr << " permutations done" << std::endl;
406+ #endif
395407 }
396408
397409 // Now all index orders match and we can simply compare index value sets.
@@ -527,8 +539,10 @@ Ex::iterator evaluate::handle_derivative(iterator it)
527539 size_t ni=number_of_direct_indices (it);
528540
529541 cadabra::do_list (tr, ivalues, [&](Ex::iterator iv) {
530- // std::cerr << "====" << std::endl;
531- // std::cerr << Ex(iv) << std::endl;
542+ #ifdef DEBUG
543+ std::cerr << " ====" << std::endl;
544+ std::cerr << Ex (iv) << std::endl;
545+ #endif
532546 // For each internal dummy set, keep track of the
533547 // position in the permutation array where we generate
534548 // its value.
@@ -539,9 +553,11 @@ Ex::iterator evaluate::handle_derivative(iterator it)
539553 auto deps=dependencies (rhs);
540554
541555 // If the argument does not depend on anything, all derivatives
542- // would produce zero.
543- if (deps.size ()==0 )
556+ // would produce zero. Remove this \equals node from the tree.
557+ if (deps.size ()==0 ) {
558+ tr.erase (iv);
544559 return true ;
560+ }
545561
546562 // All indices on \partial can take any of the values of the
547563 // dependencies, EXCEPT when the index is a dummy index. In
@@ -556,7 +572,9 @@ Ex::iterator evaluate::handle_derivative(iterator it)
556572
557573 combin::combinations<Ex> cb;
558574 for (auto & obj: deps) {
559- // std::cerr << "dep " << obj << std::endl;
575+ #ifdef DEBUG
576+ std::cerr << " dep " << obj << std::endl;
577+ #endif
560578 cb.original .push_back (obj);
561579 }
562580 cb.multiple_pick =true ;
@@ -596,18 +614,24 @@ Ex::iterator evaluate::handle_derivative(iterator it)
596614 // derivative, create an entry in the \components node.
597615
598616 for (unsigned int i=0 ; i<cb.size () || cb.size ()==0 ; ++i) {
599- // std::cerr << "Index combination " << i << std::endl;
617+ #ifdef DEBUG
618+ std::cerr << " Index combination " << i << std::endl;
619+ #endif
600620 Ex eqcopy (iv);
601621 auto lhs=eqcopy.begin (eqcopy.begin ());
602622 assert (*lhs->name ==" \\ comma" );
603623
604624 if (cb.size ()>0 ) {
625+ #ifdef DEBUG
626+ std::cerr << " Copying values of derivative indices" << std::endl;
627+ #endif
605628 // Setup the index values; simply copy from the cb array, but only
606629 // if the indices are not internal dummy.
607630 for (size_t j=0 ; j<cb[i].size (); ++j) {
608631 auto fd = ind_dummy.find (Ex (tr.child (it, j)));
609- if (fd==ind_dummy.end ())
632+ if (fd==ind_dummy.end ()) {
610633 eqcopy.append_child (iterator (lhs), cb[i][j].begin () );
634+ }
611635 }
612636 }
613637 auto rhs=lhs;
@@ -672,14 +696,16 @@ Ex::iterator evaluate::handle_derivative(iterator it)
672696
673697 if (cb.size ()==0 ) break ;
674698 }
699+
700+ // Erase the original \equals entry (we generated a full replacement above).
675701 tr.erase (iv);
676702 return true ;
677703 });
678704
679705 one (it->multiplier );
680706 // std::cerr << "now " << Ex(it) << std::endl;
681707
682-
708+
683709 // Now move the free (but not the internal dummy!) partial indices
684710 // to the components node, and then unwrap the partial node.
685711
@@ -707,11 +733,15 @@ Ex::iterator evaluate::handle_derivative(iterator it)
707733 ++se;
708734 }
709735
710- // std::cerr << "after index move " << Ex(it) << std::endl;
736+ #ifdef DEBUG
737+ std::cerr << " after index move " << Ex (it) << std::endl;
738+ #endif
711739
712740 merge_component_children (it);
713741
714- // std::cerr << "after merge " << Ex(it) << std::endl;
742+ #ifdef DEBUG
743+ std::cerr << " after merge " << Ex (it) << std::endl;
744+ #endif
715745
716746 simplify_components (it);
717747 // std::cerr << "then " << Ex(it) << std::endl;
0 commit comments