oseledets / TT-Toolbox

The git repository for the TT-Toolbox
Other
193 stars 73 forks source link

Vectorize greedy2_cross #66

Open Boyuan-Shi-0607 opened 8 months ago

Boyuan-Shi-0607 commented 8 months ago

I use your vectorize handle

function val = vectorized(ind, fun)
%Trivial vectorized computation of the elements of a tensor
%   [VAL]=MY_VEC_FUN(IND,FUN) Given a function handle FUN, compute all
%   elements of a tensor given in the index array IND. IND is a M x d
%   array, where M is the number of indices to be computed.
M = size(ind, 1);
val = zeros(1, M);
for i = 1:M
    ind_loc = ind(i,:);
    val(i) = fun(ind_loc);
end
return
end

from your dmrg_cross.m with a test function:

fun = @(ind) ind(1);

But it does not work. Error message in the command window:

Arrays have incompatible sizes for this operation.

Error in greedy2_cross (line 399)
            cre = crt-cry;

Error in test_greedy2_cross (line 149)
[y,Jyl,Jyr,ilocl,ilocr,evalcnt] = greedy2_cross(n, vectorized_code, tol, nswp=40, vec=true);

Related documentation

where the function handle vectorized_code is

vectorized_code = @(ind) vectorized(ind, fun);

And then I call your greedy2_cross with vec=true:

tol = 10^(-6);
% mode size 
n = [1,2,3,4,5];

[y,Jyl,Jyr,ilocl,ilocr,evalcnt] = greedy2_cross(n, vectorized_code, tol, nswp=40, vec=true);

May I kindly ask if you could fix the bug? Since fun is simply enough without any of my interface. I guess it’s might be an intrinsic issue.

dolgov commented 8 months ago

Hello, greedy2_cross can be instructed to handle an unvectorised function by passing the parameter 'vec', false. For example,

fun = @(ind)ind(1);
tt = greedy2_cross([2;2;2], fun, 1e-6, 'vec', false)
=greedy_cross= swp=1, max_dx=0.000e+00, max_rank=1, cum#evals=16
tt is a 3-dimensional TT-tensor, ranks and mode sizes: 
r(1)=1   n(1)=2 
r(2)=1   n(2)=2 
r(3)=1   n(3)=2 
r(4)=1

As per the documentation in the header of greedy2_cross, vectorised functions must take a M x d matrix of indices, where d is the dimension, and M is the number of samples in the current cross step, and return a M x 1 matrix of corresponding function values. That is, each row of the input matrix is an index at which the function should be evaluated.

Boyuan-Shi-0607 commented 8 months ago

Thanks for your reply. I think the vectorized(ind, fun) defined above exactly does this, with ind being the size of M x d. By passing fun to vectorized(), it should work as prescribed. Why does it not work?

dolgov commented 8 months ago

Well, it looks to me that this is not an issue with greedy2_cross. It has a well-defined interface for both vectorised and unvectorised functions, which works with your actual test function (fun). It doesn't seem necessary to implement another vectorisation. If you want to understand why exactly your function doesn't work, you can debug it as usual, given the input and output specifications. For example, make sure it always takes an M x d matrix and returns a M x 1 matrix.