docs: public static void solveBlock( final int blockLength ,
                                     final boolean upper , final DSubmatrixD1 T ,
                                     final DSubmatrixD1 B ,
                                     final boolean transT ,final boolean transB )
      {
          int Trows = T.row1-T.row0;
          if( Trows > blockLength )
              throw new IllegalArgumentException("T can be at most the size of a block");
          // number of rows in a block.  The submatrix can be smaller than a block
          final int blockT_rows = Math.min(blockLength,T.original.numRows-T.row0);
          final int blockT_cols = Math.min(blockLength,T.original.numCols-T.col0);
  
          int offsetT = T.row0*T.original.numCols+blockT_rows*T.col0;
  
          final double dataT[] = T.original.data;
          final double dataB[] = B.original.data;
  
          if( transB ) {
              if( upper ) {
                  if ( transT ) {
                      throw new IllegalArgumentException("Operation not yet supported");
                  } else {
                      throw new IllegalArgumentException("Operation not yet supported");
                  }
              } else {
                  if ( transT ) {
                      throw new IllegalArgumentException("Operation not yet supported");
                  } else {
                      for( int i = B.row0; i < B.row1; i += blockLength ) {
                          int N = Math.min(B.row1 , i + blockLength ) - i;
  
                          int offsetB = i*B.original.numCols + N*B.col0;
  
                          InnerTriangularSolver_DDRB.solveLTransB(dataT,dataB,blockT_rows,N,blockT_rows,offsetT,offsetB);
                      }
                  }
              }
          } else {
              if( Trows != B.row1-B.row0 )
                  throw new IllegalArgumentException("T and B must have the same number of rows.");
  
              if( upper ) {
                  if ( transT ) {
                      for( int i = B.col0; i < B.col1; i += blockLength ) {
                          int offsetB = B.row0*B.original.numCols + Trows*i;
  
                          int N = Math.min(B.col1 , i + blockLength ) - i;
                          InnerTriangularSolver_DDRB.solveTransU(dataT,dataB,Trows,N,Trows,offsetT,offsetB);
                      }
                  } else {
                      for( int i = B.col0; i < B.col1; i += blockLength ) {
                          int offsetB = B.row0*B.original.numCols + Trows*i;
  
                          int N = Math.min(B.col1 , i + blockLength ) - i;
                          InnerTriangularSolver_DDRB.solveU(dataT,dataB,Trows,N,Trows,offsetT,offsetB);
                      }
                  }
              } else {
                  if ( transT ) {
                      for( int i = B.col0; i < B.col1; i += blockLength ) {
                          int offsetB = B.row0*B.original.numCols + Trows*i;
  
                          int N = Math.min(B.col1 , i + blockLength ) - i;
                          InnerTriangularSolver_DDRB.solveTransL(dataT,dataB,Trows,N,blockT_cols,offsetT,offsetB);
                      }
                  } else {
                      for( int i = B.col0; i < B.col1; i += blockLength ) {
                          int offsetB = B.row0*B.original.numCols + Trows*i;
  
                          int N = Math.min(B.col1 , i + blockLength ) - i;
                          InnerTriangularSolver_DDRB.solveL(dataT,dataB,Trows,N,blockT_cols,offsetT,offsetB);
                      }
                  }
              }
          }
      }