@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 GaussianKernel<T> k : kernels.keySet()) {
      final double w = kernels.get(k);

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

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

            @Override
            public void doLines(double[][] matrix, int from, int to) {

              for (int index = from; index < to; index++) {
                for (int i = 0; i < m[index].length; i++) {
                  matrix[index][i] *= m[index][i];
                }
              }
            };
          };

      matrix = tmo.getMatrix(matrix);
    }

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

    return sum;
  }