-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsample_covshift2D.m
88 lines (77 loc) · 3.99 KB
/
sample_covshift2D.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
function [X_yn, X_yp, Z_yn, Z_yp] = sample_covshift2D(pT_X, varargin)
% Sample from class-conditional distributions, with equivalent posteriors,
% for both a source and a target domain. Function assumes Y = [-1, +1].
%
% Input:
% pT_X Target marginal data distribution
%
% Optional input:
% p_y Class-priors, default is balanced (each 1./2)
% pS_X Source data distribution, default is normal distribution
% N(x | [0,0], [1,0;0,1])
% p_yX Posterior distribution, default is a multivariate
% cumulative normal distribution:
% Phi( -3[x_1, x_2] | [0,0], [1,0;0,1]) for y=+1
% 1 - Phi( -3[x_1, x_2] | [0,0], [1,0;0,1]) for y=-1
% ub Upper bound for proposal distribution; a good way to
% find a value is to take the target distributions
% integral. For instance, for normal distributions, this
% is sqrt(det(2*pi*Sigma))
% N Source sample size
% M Target sample size
% Sx1l Sampling range limits for first feature of pS(x|y)
% Sx2l Sampling range limits for second feature of pS(x|y)
% Tx1l Sampling range limits for first feature of pT(x|y)
% Tx2l Sampling range limits for second feature of pT(x|y)
%
% Output:
% X_yn: Samples from negative class-conditional, pS(x|y=-1)
% X_yp: Samples from positive class-conditional, pS(x|y=+1)
% Z_yn: Samples from negative class-conditional, pT(x|y=-1)
% Z_yp: Samples from positive class-conditional, pT(x|y=+1)
%
% Example call:
% pT_X = @(x1, x2) mvnpdf([x1, x2], [0, 0], 2*eye(2))
% [Xn, Xp, Zn, Zp] = sample_covshift2D(pT_X, 'ub', sqrt(det(2*pi*2*eye(2))))
%
% Copyright: Wouter M. Kouw
% Last update: 27-05-2018
addpath(genpath('util/'))
% Parse hyperparameters
argp = inputParser;
addOptional(argp, 'p_y', @(y) 1./2);
addOptional(argp, 'pS_X', @(x1,x2) mvnpdf([x1, x2], [0, 0], eye(2)));
addOptional(argp, 'p_yX', @(y, x1, x2) (y<0) + y*mvncdf(-[x1 x2]*3, [0 0]));
addOptional(argp, 'N', 100);
addOptional(argp, 'M', 200);
addOptional(argp, 'ub', sqrt(2*pi));
addOptional(argp, 'Sx1l', [-10 10]);
addOptional(argp, 'Sx2l', [-10 10]);
addOptional(argp, 'Tx1l', [-10 10]);
addOptional(argp, 'Tx2l', [-10 10]);
parse(argp, varargin{:});
% TODO: assert pT_X is a function handle of two inputs, 1 output
% TODO: assert pS_X is a function handle of two inputs, 1 output
% TODO: assert p_y is a function handle of 1 input, 1 output
% TODO: assert p_yX is a function handle of three inputs, 1 output
% TODO: check if upper bound is large enough for given pT_X
% Compute number of samples to draw from each class-conditional distribution
Nn = round(argp.Results.N .* argp.Results.p_y(-1));
Np = round(argp.Results.N .* argp.Results.p_y(+1));
Mn = round(argp.Results.M .* argp.Results.p_y(-1));
Mp = round(argp.Results.M .* argp.Results.p_y(+1));
%% Distribution functions
% Source class-conditional likelihoods
pS_Xyn = @(x1,x2) (argp.Results.p_yX(-1,x1,x2) .* argp.Results.pS_X(x1,x2)) ./ argp.Results.p_y(-1);
pS_Xyp = @(x1,x2) (argp.Results.p_yX(+1,x1,x2) .* argp.Results.pS_X(x1,x2)) ./ argp.Results.p_y(+1);
% Target class-conditional distributions
pT_Xyn = @(x1,x2) (argp.Results.p_yX(-1,x1,x2) .* pT_X(x1,x2)) ./ argp.Results.p_y(-1);
pT_Xyp = @(x1,x2) (argp.Results.p_yX(+1,x1,x2) .* pT_X(x1,x2)) ./ argp.Results.p_y(+1);
%% Rejection sampling
% Sample from source class-conditional distributions
X_yn = sampleDist2D(pS_Xyn, argp.Results.ub, Nn, argp.Results.Sx1l, argp.Results.Sx2l);
X_yp = sampleDist2D(pS_Xyp, argp.Results.ub, Np, argp.Results.Sx1l, argp.Results.Sx2l);
% Sample from target class-conditional distributions
Z_yn = sampleDist2D(pT_Xyn, argp.Results.ub, Mn, argp.Results.Tx1l, argp.Results.Tx2l);
Z_yp = sampleDist2D(pT_Xyp, argp.Results.ub, Mp, argp.Results.Tx1l, argp.Results.Tx2l);
end