diff --git a/cfg/partitioning/subpicture_4_slice_2_tiles_4_subpic.cfg b/cfg/partitioning/subpicture_4_slice_2_tiles_4_subpic.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..6f70f813f73c505a2afd9648be60172b396c948e
--- /dev/null
+++ b/cfg/partitioning/subpicture_4_slice_2_tiles_4_subpic.cfg
@@ -0,0 +1,38 @@
+# example cfg file, assuming an 832x480 input sequence with CTU size = 128x128, and split to 2 tiles, with two tile columns and one tile row.
+# example 2 tiles, 4 subpictures (and each subpicture is a slice) in a 832x480 picture:
+#----------
+#|    |   |
+#|    |   |
+#|----|---|
+#|    |   |
+#|    |   |
+#----------
+#     |
+#     v
+# vertically divided into 2 tile, each tile includes two subpictures/slices
+
+SubPicInfoPresentFlag                  	: 1             # subpicture information present flag(0: OFF, 1: ON)
+NumSubPics                              : 4             # number of subpictures in a picture
+SubPicCtuTopLeftX                     	: 0 0 4 4       # specifies horizontal position of top left CTU of i-th subpicture in unit of CtbSizeY 
+SubPicCtuTopLeftY                       : 0 2 0 2       # specifies vertical position of top left CTU of i-th subpicture in unit of CtbSizeY
+SubPicWidth                             : 4 4 3 3       # specifies the width of the i-th subpicture in units of CtbSizeY
+SubPicHeight                            : 2 2 2 2       # specifies the height of the i-th subpicture in units of CtbSizeY
+SubPicTreatedAsPicFlag                  : 1 1 1 1       # equal to 1 specifies that the i-th subpicture of each coded picture in the CLVS is treated as a picture in the decoding process excluding in-loop filtering operations
+LoopFilterAcrossSubpicEnabledFlag       : 0 0 0 0       # equal to 1 specifies that in-loop filtering operations may be performed across the boundaries of the i-th subpicture in each coded picture in the CLVS
+SubPicIdMappingExplicitlySignalledFlag  : 0             # equal to 1 specifies that the subpicture ID mapping is explicitly signalled, either in the SPS or in the PPSs
+SubPicIdMappingInSpsFlag                : 0             # specifies that subpicture ID mapping is signalled in the SPS(0: OFF, 1: ON)
+SubPicIdLen                             : 0             # the number of bits used to represent the syntax element sps_subpic_id[ i ]
+SubPicId                                : 0             # subpicture ID of the i-th subpicture
+
+
+#============ Tiles / Slices ================
+EnablePicPartitioning         : 1                       # Enable picture partitioning (0: single tile, single slice, 1: multiple tiles/slices can be used)
+
+TileColumnWidthArray          : 4                       # Tile column widths in units of CTUs. Last column width will be repeated uniformly to cover any remaining picture width
+TileRowHeightArray            : 4                       # Tile row heights in units of CTUs. Last row height will be repeated uniformly to cover any remaining picture height  
+RasterScanSlices              : 0                       # Raster-scan or rectangular slices (0: rectangular, 1: raster-scan)
+RectSliceFixedWidth           : 0                       # Fixed rectangular slice width in units of tiles (0: disable this feature and use RectSlicePositions instead)
+RectSliceFixedHeight          : 0                       # Fixed rectangular slice height in units of tiles (0: disable this feature and use RectSlicePositions instead)
+RectSlicePositions            : 0 10 14 24 4 13 18 27
+DisableLoopFilterAcrossTiles  : 1                       # Loop filtering (DBLK/SAO/ALF) applied across tile boundaries or not (0: filter across tile boundaries  1: do not filter across tile boundaries)
+DisableLoopFilterAcrossSlices : 1                       # Loop filtering (DBLK/SAO/ALF) applied across slice boundaries or not (0: filter across slice boundaries 1: do not filter across slice boundaries)
diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp
index 3731b840ec1219b0ae397892145e0cfe1cc6aa0e..ba84ed99ca111543775308008de936051d195f3b 100644
--- a/source/Lib/CommonLib/Slice.cpp
+++ b/source/Lib/CommonLib/Slice.cpp
@@ -3196,41 +3196,59 @@ void PPS::initRectSliceMap(const SPS  *sps)
     // allocate new memory for slice list
     CHECK(m_numSlicesInPic > MAX_SLICES, "Number of slices in picture exceeds valid range");
     m_sliceMap.resize( m_numSlicesInPic );
-    
+
+    // Q2001 v15 equation 29
+    std::vector<uint32_t> subpicWidthInTiles;
+    std::vector<uint32_t> subpicHeightInTiles;
+    std::vector<uint32_t> subpicHeightLessThanOneTileFlag;
+    subpicWidthInTiles.resize(sps->getNumSubPics());
+    subpicHeightInTiles.resize(sps->getNumSubPics());
+    subpicHeightLessThanOneTileFlag.resize(sps->getNumSubPics());
+    for (uint32_t i = 0; i <sps->getNumSubPics(); i++)
+    {
+      uint32_t leftX = sps->getSubPicCtuTopLeftX(i);
+      uint32_t rightX = leftX + sps->getSubPicWidth(i) - 1;
+      subpicWidthInTiles[i] = m_ctuToTileCol[rightX] + 1 - m_ctuToTileCol[leftX];
+      
+      uint32_t topY = sps->getSubPicCtuTopLeftY(i);
+      uint32_t bottomY = topY + sps->getSubPicHeight(i) - 1;
+      subpicHeightInTiles[i] = m_ctuToTileRow[bottomY] + 1 - m_ctuToTileRow[topY];
+
+      if (subpicHeightInTiles[i] == 1 && sps->getSubPicHeight(i) < m_tileRowHeight[m_ctuToTileRow[topY]] )
+      {
+        subpicHeightLessThanOneTileFlag[i] = 1;
+      }
+      else
+      {
+        subpicHeightLessThanOneTileFlag[i] = 0;
+      }
+    }
+
     for( int i = 0; i < m_numSlicesInPic; i++ )
     {
+      CHECK(m_numSlicesInPic != sps->getNumSubPics(), "in single slice per subpic mode, number of slice and subpic shall be equal");
       m_sliceMap[ i ].initSliceMap();
-    }
-    for (int row = 0; row < m_numTileRows; row++)
-    {
-      for (int col = 0; col < m_numTileCols; col++)
+      if (subpicHeightLessThanOneTileFlag[i])
       {
-        const int tileTopLeftCtu = getTileColumnBd(col) + getTileRowBd(row) * getPicWidthInCtu();
-        const int sliceIdx = getCtuToSubPicIdx(tileTopLeftCtu);
-        const int tileSizeInCtus = (getTileColumnBd(col + 1) - getTileColumnBd(col)) * (getTileRowBd(row + 1) - getTileRowBd(row));
-        const int subPicSizeInCtus = sps->getSubPicHeight(sliceIdx) * sps->getSubPicWidth(sliceIdx);
-        if (subPicSizeInCtus >= tileSizeInCtus)
-        {
-          m_sliceMap[sliceIdx].addCtusToSlice(getTileColumnBd(col), getTileColumnBd(col + 1),
-            getTileRowBd(row), getTileRowBd(row + 1), m_picWidthInCtu);
-        }
-        else
-        {
-          int sliceIdxInTile = sliceIdx;
-          do
+        m_sliceMap[i].addCtusToSlice(sps->getSubPicCtuTopLeftX(i), sps->getSubPicCtuTopLeftX(i) + sps->getSubPicWidth(i), 
+                                     sps->getSubPicCtuTopLeftY(i), sps->getSubPicCtuTopLeftY(i) + sps->getSubPicHeight(i), m_picWidthInCtu);
+      }
+      else
+      {
+        tileX = m_ctuToTileCol[sps->getSubPicCtuTopLeftX(i)];
+        tileY = m_ctuToTileRow[sps->getSubPicCtuTopLeftY(i)];
+        for (uint32_t j = 0; j< subpicHeightInTiles[i]; j++)
+        { 
+          for (uint32_t k = 0; k < subpicWidthInTiles[i]; k++)
           {
-            // subpicture vertical boundary must be a tile boundary, so tile column parameter doesn't change
-            m_sliceMap[sliceIdxInTile].addCtusToSlice(getTileColumnBd(col), getTileColumnBd(col + 1),
-              sps->getSubPicCtuTopLeftY(sliceIdxInTile), sps->getSubPicCtuTopLeftY(sliceIdxInTile) +  sps->getSubPicHeight(sliceIdxInTile), m_picWidthInCtu);
-            sliceIdxInTile++;
-            if (sliceIdxInTile == sps->getNumSubPics())
-            {
-              break;
-            }
-          } while (sps->getSubPicCtuTopLeftY(sliceIdxInTile) < getTileRowBd(row + 1));
+            m_sliceMap[i].addCtusToSlice(getTileColumnBd(tileX + k), getTileColumnBd(tileX + k + 1), getTileRowBd(tileY + j), getTileRowBd(tileY + j + 1), m_picWidthInCtu);
+          }
         }
       }
-    }    
+    }
+    subpicWidthInTiles.clear();
+    subpicHeightInTiles.clear();
+    subpicHeightLessThanOneTileFlag.clear();
   }
   else
   {