private double cost(int line, int column) {
    if (costTable[line][column] == null) {
      costTable[line][column] = new DTWCell(0, -1, -1);

      costTable[line][column].cost = abs(lines.valueAt(line) - columns.valueAt(column));

      if (line > 0 && column > 0) {
        double minimum = cost(line - 1, column - 1);
        costTable[line][column].line = line - 1;
        costTable[line][column].column = column - 1;

        if (cost(line, column - 1) < minimum) {
          minimum = cost(line - 1, column - 1);
          costTable[line][column].line = line;
          costTable[line][column].column = column - 1;
        }

        if (cost(line - 1, column) < minimum) {
          minimum = cost(line - 1, column);
          costTable[line][column].line = line - 1;
          costTable[line][column].column = column;
        }

        costTable[line][column].cost += minimum;
      } else if (line > 0) {
        costTable[line][column].cost += cost(line - 1, column);
        costTable[line][column].line = line - 1;
        costTable[line][column].column = column;
      } else if (column > 0) {
        costTable[line][column].cost += cost(line, column - 1);
        costTable[line][column].line = line;
        costTable[line][column].column = column - 1;
      }
    }

    return costTable[line][column].cost;
  }