-
Notifications
You must be signed in to change notification settings - Fork 21
/
create_guess.m
157 lines (147 loc) · 5.14 KB
/
create_guess.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
function U = create_guess(varargin)
%CREATE_GUESS Creates initial guess for CP or Tucker fitting.
%
% U = CREATE_GUESS('Param',value,...) creates an initial guess at the
% factor matrices for a CP or Tucker decomposition. The factors can be
% generated randomly, random orthogonal, etc. If the tensor is provided,
% it can be alternatively generated via the HO-SVD.
%
% --- Parameters ---
%
% 'Factor_Generator' - Method to be used to generate the factor matrices.
% Options:
% - 'rand' (uniform on [0,1])
% - 'randn' (standard normal distribution)
% - 'orthogonal'
% - 'stochastic' (uniform on [0,1] with column sums rescaled to 1)
% - 'nvecs' (HOSVD solution)
% - 'pertubation' of the true solution
% Alternatively, pass in a function that accepts two arguments (the size
% of the matrix) and generates the desired factor. Default: 'rand'
%
% 'Size' - Size of the tensor. Required to be specified unless 'Data' or
% 'Soln' is given. Default: []
%
% 'Num_Factors' - Number of factors (can be either a single value for CP
% or a vector for Tucker). Required to be specified unless 'Soln' is
% given. Default: []
%
% 'Data' - The actual tensor to be fit. Required if 'nvecs' is the
% selected Factor Generator. The 'Size' parameter is ignored if this
% is specified. Default: []
%
% 'Soln' - The actual solution to the problem. Required if 'pertubation'
% is the selected Factor Generator. The 'Size' and 'Num_Factors'
% parameters are ignored if this is specified. Default: []
%
% 'Pertubation' - Size of the pertubation is the 'pertubation' option is
% selected under 'Factor_Generator'. The pertubation is of the form U+p*N
% where U is the original factor matrix, N is a noise matrix with entries
% selected for a standard normal distribution, and p is the pertubation
% parameter times ||U||/||N||. Default: 0.10
%
% 'Skip' - Specifies mode to skip in initial guess generation (this is
% useful for ALS). Default: 0 (no skipping)
%
% 'State' - State of the random number generator. This can be used
% to reproduce results.
%
% See also CREATE_PROBLEM.
%
%MATLAB Tensor Toolbox.
%Copyright 2015, Sandia Corporation.
% This is the MATLAB Tensor Toolbox by T. Kolda, B. Bader, and others.
% http://www.sandia.gov/~tgkolda/TensorToolbox.
% Copyright (2015) Sandia Corporation. Under the terms of Contract
% DE-AC04-94AL85000, there is a non-exclusive license for use of this
% work by or on behalf of the U.S. Government. Export of this data may
% require a license from the United States Government.
% The full license terms can be found in the file LICENSE.txt
%% Random set-up
defaultStream = RandStream.getGlobalStream;
%% Parse inputs
p = inputParser;
p.addParamValue('Factor_Generator', 'rand', @(x) isa(x,'function_handle') || ...
ismember(lower(x),{'rand','randn','orthogonal','stochastic','nvecs','pertubation'}));
p.addParamValue('Size', [], @(x) isempty(x) || all(x));
p.addParamValue('Num_Factors', [], @(x) isempty(x) || all(x));
p.addParamValue('Soln', [], @(x) isempty(x) || isa(x,'ktensor') || isa(x,'ttensor'));
p.addParamValue('Data', [], @(x) isempty(x) || isa(x,'tensor') || isa(x,'sptensor'));
p.addParamValue('Pertubation', 0.10, @(x) x >= 0 & x < 1);
p.addParamValue('Skip', 0);
p.addParamValue('State', defaultStream.State, @(x) true);
p.parse(varargin{:});
params = p.Results;
%% Initialize random number generator with specified state.
defaultStream.State = params.State;
%% Determine problem size
if ~isempty(params.Soln)
sz = size(params.Soln);
elseif ~isempty(params.Data)
sz = size(params.Data);
else
sz = params.Size;
end
if isempty(sz)
error('Size must be specified');
end
nd = length(sz);
modes = setdiff(1:nd,params.Skip);
%% Determine number of factors
if ~isempty(params.Soln)
nf = zeros(nd,1);
for n = 1:nd
nf(n) = size(params.Soln.U{n},2);
end
else
nf = params.Num_Factors;
if length(nf) == 1
nf = nf * ones(nd,1);
end
end
%% Create factor matrices
U = cell(nd,1);
if isa(params.Factor_Generator,'function_handle')
for n = modes
U{n} = params.Factor_Generator(sz(n), nf(n));
end
return;
end
switch(params.Factor_Generator)
case 'rand'
for n = modes
U{n} = rand(sz(n), nf(n));
end
case 'randn'
for n = modes
U{n} = randn(sz(n), nf(n));
end
case 'orthogonal'
for n = modes
X = matrandorth(sz(n));
U{n} = X(:,1:nf(n));
end
case 'stochastic'
for n = modes
X = rand(sz(n), nf(n));
S = sum(X,1);
U{n} = X * diag(1./S);
end
case 'nvecs'
if isempty(params.Data)
error('Data required for nvecs initialization');
end
for n = modes
U{n} = nvecs(params.Data,n,nf(n));
end
case 'pertubation'
if isempty(params.Soln)
error('Soln required for pertubation initialization');
end
for n = modes
X = params.Soln{n};
N = rand(size(X));
p = params.Pertubation * norm(X,'fro') / norm(N,'fro');
U{n} = X + p * N;
end
end