MATLAB: Fitrsvm doesn’t vectorize the custom kernel

custom kernelfitrsvm

I'm working on an iterative function approximation algorithm. As part of that algorithm I use fitrsvm to update a kernel regression each iteration. This all works great when I use MATLAB's built in kernels. However, once I venture outside of MATLAB's kernels and start using my own the runtime of fitrsvm increases by nearly 4 times. That is, the runtime increases when I call:
m = fitrsvm(X, Y, 'KernelFunction','my_kernel');
To try to understand why I placed a break point in my_kernel. By doing this it appears that fitrsvm is not taking advantage of vectorization. The arguments being passed into my_kernel by fitrsvm behave as if it is in a loop similar to what I have below:
%how my_kernel appears to be called in fitrsvm based on the arguments passed to my_kernel
%though I admit I can't actually see the code since it seems to dispatch to a C file
for i = 1:size(X,1):
for j = 1:size(X,1):
G(i,j) = feval('my_kernel',X(i,:), X(j,:))
end
end
This same inefficient behavior also occurs when I predict the responses:
response = predict(m,Z)
I've managed to get a considerable speed up by replacing predict with the following:
response = m.Bias + m.Alpha' * feval('my_kernel',m.SupportVectors,Z);
Has anybody else noticed this behavior? Any suggestions? Am I missing a parameter maybe? I'm working on 2020a.

Best Answer

I had this annoying problem too. I reached the conclusion that the best way to solve it is to use a 'precompiled' kernel and hack the kernel function as follows:
function g = precomp(u,v)
global K
g = K(u,v);
end
Where u and v correspond to the indexes of the observations. To achieve such indexing, I replaced the training data with the indexes as follows:
global K
K = myvectorizedkernelfcn(X,X);
Xidx = 1:size(X,1); % This corressponds to the number of rows
mdl = fitrsvm(Xidx',Y,'KernelFunction','precomp');
I hope this helps. Cheers.