/// <summary> /// Constructs summation kernel from an initial kernel function /// </summary> /// <param name="kernel"></param> public MixtureKernel(IKernelFunctionWithParams kernel) : this() { kernels.Add(kernel); weights.Add(1.0); buildMaps(); }
public static PositiveDefiniteMatrix GramMatrix(IKernelFunctionWithParams kf, Vector[] xData, int[] hypersToOptimise, ref PositiveDefiniteMatrix[] gradK) { int nData = xData.Length; // Allocate and fill the Kernel matrix. PositiveDefiniteMatrix K = new PositiveDefiniteMatrix(nData, nData); //gradK = Enumerable.Range(0, kf.ThetaCount).Select(_ => new PositiveDefiniteMatrix(nData, nData)).ToArray(); for (int i = 0; i < nData; i++) { for (int j = 0; j < nData; j++) { Vector temp = gradK == null ? null : Vector.Zero(kf.ThetaCount); // Evaluate the kernel. All hyperparameters, including noise // variance are handled in the kernel. K[i, j] = kf.EvaluateX1X2(xData[i], xData[j], ref temp); if (gradK != null) { for (int t = 0; t < hypersToOptimise.Length; t++) { gradK[t][i, j] = temp[hypersToOptimise[t]]; } } } } return(K); }
private static void TestReadWrite(IKernelFunctionWithParams kf) { string typeName = kf.GetType().Name; string fn = typeName + ".txt"; // Write out the kernel StreamWriter sw = new StreamWriter(fn); kf.Write(sw); sw.Close(); // Now read it back again StreamReader sr = new StreamReader(fn); KernelFactory kfact = KernelFactory.Instance; IKernelFunctionWithParams kf1 = kfact.CreateKernelFunction(typeName); kf1.Read(sr); sr.Close(); // Now test that they're the same Assert.Equal(kf.ThetaCount, kf1.ThetaCount); for (int i = 0; i < kf.ThetaCount; i++) { Assert.Equal(kf[i], kf1[i], 1e-6); } }
/// <summary> /// Evaluates the kernel for a single vector (which is used for both slots) /// </summary> /// <param name="x">Vector</param> /// <param name="xDeriv">Derivative of the kernel value with respect to x</param> /// <param name="logThetaDeriv">Derivative of the kernel value with respect to the log hyper-parameters</param> /// <returns></returns> public override double EvaluateX(Vector x, ref Vector xDeriv, ref Vector logThetaDeriv) { int totalCount = this.ThetaCount; double result = 0.0; Vector lthd; Vector lx1d; // Check that log theta deriv is correct size if (((object)logThetaDeriv) != null) { if (logThetaDeriv.Count != totalCount) { logThetaDeriv = Vector.Zero(totalCount); } } // Check that the x deriv is the correct size // Check that log theta deriv is correct size if (((object)xDeriv) != null) { if (xDeriv.Count != x.Count) { xDeriv = Vector.Zero(x.Count); } lx1d = Vector.Zero(x.Count); } else { lx1d = null; } int derivX = 0; for (int kx = 0; kx < kernels.Count; kx++) { IKernelFunctionWithParams k = kernels[kx]; int thcnt = thetaCount[kx]; if (((object)logThetaDeriv) != null) { lthd = Vector.Zero(thcnt); } else { lthd = null; } result += k.EvaluateX(x, ref lx1d, ref lthd); if (((object)lthd) != null) { for (int ix = 0; ix < thcnt; ix++) { logThetaDeriv[derivX++] = lthd[ix]; } } if (((object)lx1d) != null) { xDeriv.SetToSum(xDeriv, lx1d); } } return(result); }
/// <summary> /// Registers a kernel function. The factory is primed with stock /// kernel functions. This function allows clients to add in custom /// kernel functions /// </summary> /// <param name="ikf">Type instance</param> public void RegisterKernelFunction(IKernelFunctionWithParams ikf) { Type kfType = ikf.GetType(); string typeName = kfType.Name; if (creators.ContainsKey(typeName)) creators[typeName] = kfType; else creators.Add(typeName, kfType); }
public static string[] KernelHyperNames(IKernelFunctionWithParams kf) { int K = kf.ThetaCount; var result = new string[K]; for (int i = 0; i < K; i++) { result[i] = kf.IndexToName(i); } return(result); }
public static double[] KernelToArray(IKernelFunctionWithParams kf) { int K = kf.ThetaCount; var result = new double[K]; for (int i = 0; i < K; i++) { result[i] = kf[i]; } return(result); }
/// <summary> /// Registers a kernel function. The factory is primed with stock /// kernel functions. This function allows clients to add in custom /// kernel functions /// </summary> /// <param name="ikf">Type instance</param> public void RegisterKernelFunction(IKernelFunctionWithParams ikf) { Type kfType = ikf.GetType(); string typeName = kfType.Name; if (creators.ContainsKey(typeName)) { creators[typeName] = kfType; } else { creators.Add(typeName, kfType); } }
/// <summary> /// Reads the function parameters in from a stream /// </summary> /// <param name="sr">Stream reader</param> public override void Read(StreamReader sr) { string typeName = this.GetType().Name; string start = "<" + typeName + ">"; string end = "</" + typeName + ">"; KernelFactory kfact = KernelFactory.Instance; initialise(); string str; str = sr.ReadLine(); if (str != start) { throw new IOException("Unexpected section start"); } // Version str = sr.ReadLine(); int vers = int.Parse(str); // kernel count str = sr.ReadLine(); int kcnt = int.Parse(str); // Cosntruct the kernels for (int i = 0; i < kcnt; i++) { str = sr.ReadLine(); IKernelFunctionWithParams kf = kfact.CreateKernelFunction(str); kf.Read(sr); kernels.Add(kf); } // Build the maps buildMaps(); // Read in the end marker str = sr.ReadLine(); if (str != end) { throw new IOException("Unexpected section end"); } }
/// <summary> /// Helper method for building maps between container and containees /// </summary> protected void buildMaps() { clearMaps(); int thetaSum = 0; thetaCount = new int[kernels.Count]; for (int kx = 0; kx < kernels.Count; kx++) { IKernelFunctionWithParams k = kernels[kx]; thetaCount[kx] = k.ThetaCount; thetaSum += k.ThetaCount; } indexOfKernel = new int[thetaSum]; indexInKernel = new int[thetaSum]; thetaNames = new string[thetaSum]; thetaName2Index = new Dictionary <string, int>(); int idxOf = 0; int idx = 0; foreach (IKernelFunctionWithParams k in kernels) { for (int idxIn = 0; idxIn < k.ThetaCount; idxIn++, idx++) { indexOfKernel[idx] = idxOf; indexInKernel[idx] = idxIn; string name = k.IndexToName(idxIn); thetaNames[idx] = name; // For index look-up, hoose a unique name in case there are clashes between two kernels while (thetaName2Index.ContainsKey(name)) { name += "_" + idxOf.ToString(CultureInfo.InvariantCulture); } thetaName2Index.Add(name, idx); } idxOf++; } }
/// <summary> /// Local function that can be used to compare analytic with numeric derivatives /// </summary> /// <param name="kf">Kernel function</param> private void TestDerivatives(IKernelFunctionWithParams kf, Vector vec1, Vector vec2) { int thcnt = kf.ThetaCount; Vector analyticLogThetaDeriv = Vector.Zero(thcnt); Vector numericLogThetaDeriv = Vector.Zero(thcnt); Vector analytic_x1Deriv = Vector.Zero(vec1.Count); Vector numeric_x1Deriv = Vector.Zero(vec1.Count); Vector xNull = null; kf.EvaluateX1X2(vec1, vec2, ref analytic_x1Deriv, ref analyticLogThetaDeriv); // Calculate a numeric derivative for each parameter and compare with analytic for (int i = 0; i < thcnt; i++) { double d = kf[i]; kf[i] = d + DITHER; double dplus = kf.EvaluateX1X2(vec1, vec2, ref xNull, ref xNull); kf[i] = d - DITHER; double dminus = kf.EvaluateX1X2(vec1, vec2, ref xNull, ref xNull); numericLogThetaDeriv[i] = DITHER_MULT * (dplus - dminus); Assert.True(System.Math.Abs(numericLogThetaDeriv[i] - analyticLogThetaDeriv[i]) < TOLERANCE); // Restore value kf[i] = d; } // Calculate a numeric derivative for each of the two vectors, and compare with analytic for (int i = 0; i < vec1.Count; i++) { double d = vec1[i]; vec1[i] = d + DITHER; double dplus = kf.EvaluateX1X2(vec1, vec2, ref xNull, ref xNull); vec1[i] = d - DITHER; double dminus = kf.EvaluateX1X2(vec1, vec2, ref xNull, ref xNull); numeric_x1Deriv[i] = DITHER_MULT * (dplus - dminus); Assert.True(System.Math.Abs(numeric_x1Deriv[i] - analytic_x1Deriv[i]) < TOLERANCE); // Restore value vec1[i] = d; } }
/// <summary> /// Constructs summation kernel from an initial kernel function /// </summary> /// <param name="kernel"></param> public SummationKernel(IKernelFunctionWithParams kernel) : this() { kernels.Add(kernel); buildMaps(); }
/// <summary> /// Adds two kernel functions /// </summary> /// <param name="kernelA"></param> /// <param name="kernelB"></param> /// <returns></returns> public void Add(double weight, IKernelFunctionWithParams kernel) { kernels.Add(kernel); weights.Add(weight); buildMaps(); }