Salome HOME
DataArrayInt.FindPermutationFromFirstToSecond
authorageay <ageay>
Thu, 25 Jul 2013 15:19:10 +0000 (15:19 +0000)
committerageay <ageay>
Thu, 25 Jul 2013 15:19:10 +0000 (15:19 +0000)
src/MEDCoupling/MEDCouplingMemArray.cxx
src/MEDCoupling/MEDCouplingMemArray.hxx
src/MEDCoupling_Swig/MEDCouplingBasicsTest.py
src/MEDCoupling_Swig/MEDCouplingCommon.i
src/MEDCoupling_Swig/MEDCouplingMemArray.i

index 82082779f8d2fd73099b86c3cffa1930cfd4624a..eb91aa22ce5e1567af0ef80998d72ce7b9dd1da9 100644 (file)
@@ -6853,6 +6853,44 @@ DataArrayInt *DataArrayInt::checkAndPreparePermutation() const throw(INTERP_KERN
   return ret;
 }
 
+/*!
+ * This method tries to find the permutation to apply to the first input \a ids1 to obtain the same array (without considering strings informations) the second
+ * input array \a ids2.
+ * \a ids1 and \a ids2 are expected to be both a list of ids (both with number of components equal to one) not sorted and with values that can be negative.
+ * This method will throw an exception is no such permutation array can be obtained. It is typically the case if there is some ids in \a ids1 not in \a ids2 or
+ * inversely.
+ * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
+ *
+ * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
+ *          array using decrRef() as it is no more needed.
+ * \throw If either ids1 or ids2 is null not allocated or not with one components.
+ * 
+ */
+DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2) throw(INTERP_KERNEL::Exception)
+{
+  if(!ids1 || !ids2)
+    throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
+  if(!ids1->isAllocated() || !ids2->isAllocated())
+    throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
+  if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
+  if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
+    {
+      std::ostringstream oss; oss << "DataArrayInt::FindPermutationFromFirstToSecond : first array has " << ids1->getNumberOfTuples() << " tuples and the second one " << ids2->getNumberOfTuples() << " tuples ! No chance to find a permutation between the 2 arrays !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(ids1->deepCpy());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(ids2->deepCpy());
+  p1->sort(true); p2->sort(true);
+  if(!p1->isEqualWithoutConsideringStr(*p2))
+    throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation betwenn the 2 arrays !");
+  p1=ids1->checkAndPreparePermutation();
+  p2=ids2->checkAndPreparePermutation();
+  p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
+  p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
+  return p2.retn();
+}
+
 /*!
  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
  * onto a set of values of size \a targetNb (\a B). The surjective function is 
index 9ef0b37de1562cdbad438a3735ddd768ec11c901..44b83de9ad996fe98c543ce53a994f2fe1a90f16 100644 (file)
@@ -484,6 +484,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT DataArrayInt *selectByTupleId2(int bg, int end, int step) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArray *selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT static DataArrayInt *FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT static DataArrayInt *BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception);
index 7bd55b9a2f1f270d93b5c93737c529d6efeceb7a..21137adab6aa5a56867756e9328acd395ff99876 100644 (file)
@@ -13471,6 +13471,19 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         self.assertTrue(a.buildUnstructured().isEqual(c2.buildUnstructured().buildPartAndReduceNodes(d20)[0],1e-12))
         pass
 
+    def testSwig2FindPermutationFromFirstToSecond1(self):
+        ids1=DataArrayInt([3,1,103,4,6,10,-7,205])
+        ids2=DataArrayInt([-7,1,205,10,6,3,103,4])
+        ids3=DataArrayInt.FindPermutationFromFirstToSecond(ids1,ids2)
+        self.assertTrue(ids3.isEqual(DataArrayInt([5,1,6,7,4,3,0,2])))
+        ids2ToTest=ids1.renumber(ids3)
+        self.assertTrue(ids2ToTest.isEqual(ids2))
+        self.assertRaises(InterpKernelException,DataArrayInt.FindPermutationFromFirstToSecond,DataArrayInt([3,1,103]),DataArrayInt([1,103]))
+        self.assertRaises(InterpKernelException,DataArrayInt.FindPermutationFromFirstToSecond,DataArrayInt([3,1,103]),DataArrayInt([1,103,2]))
+        self.assertRaises(InterpKernelException,DataArrayInt.FindPermutationFromFirstToSecond,DataArrayInt([3,1,103]),DataArrayInt([1,103,1]))
+        self.assertTrue(DataArrayInt.FindPermutationFromFirstToSecond(DataArrayInt([]),DataArrayInt([])).empty())
+        pass
+    
     def setUp(self):
         pass
     pass
index 144defc4a9dcee1d4d11f2ae024a4195eb34e6ff..49c9c16956e8dd0453bf531f0d07b74a3377396f 100644 (file)
@@ -275,6 +275,7 @@ using namespace INTERP_KERNEL;
 %newobject ParaMEDMEM::DataArrayInt::buildPermutationArr;
 %newobject ParaMEDMEM::DataArrayInt::buildPermArrPerLevel;
 %newobject ParaMEDMEM::DataArrayInt::getDifferentValues;
+%newobject ParaMEDMEM::DataArrayInt::FindPermutationFromFirstToSecond;
 %newobject ParaMEDMEM::DataArrayInt::__neg__;
 %newobject ParaMEDMEM::DataArrayInt::__add__;
 %newobject ParaMEDMEM::DataArrayInt::__radd__;
index f2837c8da45d7da0e9d62dcea6b3f749367cc543..aabcd6a1bf7f2a3ca3cddc33a0ad510f42b84318 100644 (file)
@@ -2381,6 +2381,7 @@ namespace ParaMEDMEM
     static DataArrayInt *MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups) throw(INTERP_KERNEL::Exception);
     static DataArrayInt *BuildUnion(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception);
     static DataArrayInt *BuildIntersection(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception);
+    static DataArrayInt *FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2) throw(INTERP_KERNEL::Exception);
     DataArrayInt *buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception);
     DataArrayInt *buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception);
     DataArrayInt *buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception);