public function setMatrix()
    {
        if (func_num_args() > 0) {
            $args = func_get_args();
            $match = implode(',', array_map('gettype', $args));
 
            switch ($match) {
        case 'integer,integer,object':
          $M = is_a($args[2], 'Matrix') ? $args[2] : trigger_error(ArgumentTypeException, ERROR);
          $i0 = (($args[0] + $M->m) <= $this->m) ? $args[0] : trigger_error(ArgumentBoundsException, ERROR);
          $j0 = (($args[1] + $M->n) <= $this->n) ? $args[1] : trigger_error(ArgumentBoundsException, ERROR);
 
          for ($i = $i0; $i < $i0 + $M->m; $i++) {
              for ($j = $j0; $j < $j0 + $M->n; $j++) {
                  $this->A[$i][$j] = $M->get($i - $i0, $j - $j0);
              }
          }
 
          break;
 
        case 'integer,integer,array':
          $M = new Matrix($args[2]);
          $i0 = (($args[0] + $M->m) <= $this->m) ? $args[0] : trigger_error(ArgumentBoundsException, ERROR);
          $j0 = (($args[1] + $M->n) <= $this->n) ? $args[1] : trigger_error(ArgumentBoundsException, ERROR);
 
          for ($i = $i0; $i < $i0 + $M->m; $i++) {
              for ($j = $j0; $j < $j0 + $M->n; $j++) {
                  $this->A[$i][$j] = $M->get($i - $i0, $j - $j0);
              }
          }
 
          break;
 
        default:
          trigger_error(PolymorphicArgumentException, ERROR);
          break;
      }
        } else {
            trigger_error(PolymorphicArgumentException, ERROR);
        }
    }