@Override
  public double[][] getKernelMatrix(List<TrainingSample<T>> list) {
    final List<TrainingSample<T>> l = list;
    // init matrix with ones
    double matrix[][] = new double[l.size()][l.size()];
    for (double[] lines : matrix) Arrays.fill(lines, 1.);

    for (final Kernel<T> k : kernels.keySet()) {
      final double w = kernels.get(k);

      // check w
      if (w == 0) continue;

      final double[][] m = k.getKernelMatrix(l);
      // specific factory
      ThreadedMatrixOperator tmo =
          new ThreadedMatrixOperator() {

            @Override
            public void doLine(int index, double[] line) {

              for (int i = line.length - 1; i >= 0; i--) {
                line[i] *= Math.pow(m[index][i], w);
              }
            };
          };

      tmo.getMatrix(matrix);
    }
    return matrix;
  }
  @Override
  public double valueOf(T t1, T t2) {
    double sum = 1.;
    for (Kernel<T> k : kernels.keySet()) {
      double w = kernels.get(k);
      if (w != 0) sum *= Math.pow(k.valueOf(t1, t2), kernels.get(k));
    }

    return sum;
  }