コード例 #1
0
def get_data(order, params, freq, ll, scale):
    Batchsize = params['M']
    train_windows, train_path, time = _load_rough_bergomi(params, freq, ll)

    train_logsig = signatory.logsignature(torch.tensor(train_windows),
                                          order).numpy()
    train_sig = signatory.signature(torch.tensor(train_windows), order).numpy()
    train_sig_exp = np.concatenate([np.ones([Batchsize, 1]), train_sig],
                                   axis=1)
    #     train_sig_normalized = normalize.normalize_sig(2, order, train_sig_exp)

    test_windows, test_path, time = _load_rough_bergomi(params, freq, ll)
    test_logsig = signatory.logsignature(torch.tensor(test_windows),
                                         order).numpy()
    test_sig = signatory.signature(torch.tensor(test_windows), order).numpy()
    test_sig_exp = np.concatenate([np.ones([Batchsize, 1]), test_sig], axis=1)
    if scale:
        scaler_logsig = MinMaxScaler(feature_range=(0.00001, 0.99999))
        logsig_transformed = scaler_logsig.fit_transform(train_logsig)
        data = logsig_transformed[1:]  # 1 week forecasting 1 week
        data_cond = logsig_transformed[:-1]
        data_cond = np.zeros_like(
            data_cond)  ######################################### for VAE
        scaler = scaler_logsig
    else:
        logsig_transformed = None
        scaler = None
        data = train_logsig[1:]  # 1 week forecasting 1 week
        data_cond = train_logsig[:-1]
        data_cond = np.zeros_like(
            data_cond)  ######################################### for VAE

    return train_windows, train_path, train_logsig, train_sig, train_sig_exp, test_windows, test_path,\
test_logsig, test_sig, test_sig_exp, logsig_transformed, data, data_cond, scaler
コード例 #2
0
def test_insertion_matrix_structure():
    """Tests that the insertion matrix has identical singular values, all equal to the norm of the signature of order
    depth"""
    batch_size = 1
    for input_stream in (2, 3, 10):
        for input_channels in (1, 2, 6):
            path = torch.rand((batch_size, input_stream, input_channels))
            for depth in (1, 2, 4, 6):
                signature = signatory.signature(path, depth)
                norm_sign = torch.norm(
                    signatory.extract_signature_term(signature, input_channels,
                                                     depth)[0])**2
                for insertion_position in range(1, depth + 1):
                    insertion_matrix = get_insertion_matrix(
                        signature, insertion_position, depth,
                        input_channels)[0]
                    diagonal_matrix = torch.matmul(insertion_matrix,
                                                   insertion_matrix.T)
                    assert diagonal_matrix.shape == (input_channels,
                                                     input_channels)
                    assert torch.allclose(diagonal_matrix[0, 0],
                                          norm_sign,
                                          atol=1e-05)
                    if input_channels > 1:
                        assert diagonal_matrix[0, input_channels - 1] == 0.
                        assert torch.allclose(
                            diagonal_matrix[input_channels - 1,
                                            input_channels - 1],
                            diagonal_matrix[0, 0])
コード例 #3
0
ファイル: bsde.py プロジェクト: msabvid/Deep-PPDE
    def get_stream_signatures(self, ts: torch.Tensor, x: torch.Tensor,
                              lag: int):
        """
        Given a path, get the stream of signatures
        
        Parameters
        ----------
        ts: torch.Tensor
            Time discretisation.
        x: torch.Tensor
            Tensor of size (batch_size, n_steps, d)
        """
        device = x.device
        batch_size = x.shape[0]
        path_signature = torch.zeros(batch_size,
                                     len(range(0, len(ts), lag)),
                                     self.sig_channels,
                                     device=device)
        basepoint = torch.zeros(batch_size, 1, self.d, device=device)

        for idx, id_t in enumerate(range(0, len(ts), lag)):
            if idx == 0:
                portion_path = torch.cat([basepoint, x[:, 0, :].unsqueeze(1)],
                                         1)
            else:
                portion_path = x[:, id_t - lag:id_t + 1, :]
            augmented_path = apply_augmentations(portion_path,
                                                 self.augmentations)
            path_signature[:, idx, :] = signatory.signature(
                augmented_path, self.depth)
        return path_signature
コード例 #4
0
def setup(obj):
    torch.set_num_threads(1)

    obj.path = torch.rand(obj.size, dtype=torch.float, requires_grad=True)
    shape = obj.size[-3], signatory.signature_channels(obj.size[-1], obj.depth)
    obj.grad = torch.rand(shape)
    obj.signature = signatory.signature(obj.path, obj.depth)
コード例 #5
0
ファイル: helpers.py プロジェクト: zeta1999/signatory
def get_initial(batch_size, input_channels, device, depth, initial, scalar_term):
    """Gets a value for the 'initial' argument of signatory.signature."""
    if initial in (without_grad, with_grad):
        initial_path = torch.rand(batch_size, 2, input_channels, device=device, dtype=torch.double)
        initial_signature = signatory.signature(initial_path, depth, scalar_term=scalar_term)
        if initial == with_grad:
            initial_signature.requires_grad_()
        return initial_signature
    else:
        return initial
コード例 #6
0
ファイル: bsde.py プロジェクト: msabvid/Deep-PPDE
    def prepare_data(self, ts: torch.Tensor, x0: torch.Tensor, lag: int):
        """
        Prepare the data:
            1. Solve the sde using some sde solver on a fine time discretisation
            2. calculate path signature between consecutive timesteps of a coarser time discretisation
            3. Calculate increments of brownian motion on the coarser time discretisation
        Parameters
        ----------
        ts: torch.Tensor
            Time discrstisation. Tensor of size (n_steps + 1)
        x0: torch.Tensor
            initial value of paths. Tensor of size (batch_size, d)
        lag: int
            lag used to create the coarse time discretisation in terms of the fine time discretisation.
        
        Returns
        -------
        x: torch.Tensor
            Solution of the SDE on the fine time discretisation. Tensor of shape (batch_size, n_steps+1, d)
        path_signature: torch.Tensor
            Stream of signatures. Tensor of shape (batch_size, n_steps/lag + 1, sig_channels)
        sum_increments: torch.Tensor
            Increments of the Brownian motion on the coarse time discretisation. Tensor of shape (batch_size, n_steps/lag+1, d)
        """
        x, brownian_increments = self.sdeint(ts, x0)
        device = x.device
        batch_size = x.shape[0]
        path_signature = torch.zeros(batch_size,
                                     len(range(0, len(ts), lag)),
                                     self.sig_channels,
                                     device=device)
        sum_increments = torch.zeros(batch_size,
                                     len(range(0, len(ts), lag)),
                                     self.d,
                                     device=device)
        basepoint = torch.zeros(batch_size, 1, self.d, device=device)

        for idx, id_t in enumerate(range(0, len(ts), lag)):
            if idx == 0:
                portion_path = torch.cat([basepoint, x[:, 0, :].unsqueeze(1)],
                                         1)
            else:
                portion_path = x[:, id_t - lag:id_t + 1, :]

            augmented_path = apply_augmentations(portion_path,
                                                 self.augmentations)
            path_signature[:, idx, :] = signatory.signature(
                augmented_path, self.depth)
            try:
                sum_increments[:, idx, :] = torch.sum(
                    brownian_increments[:, id_t:id_t + lag], 1)
            except:
                pass  # it is the last point and we don't have anymore increments, but that's okay, because at the last step of the bsde, we compare thes olution of the bsde against the payoff of the option
        return x, path_signature, sum_increments
コード例 #7
0
def test_inverted_path_shape():
    """Tests that the inverted path is of the right shape"""
    for batch_size in (1, 2, 5):
        for input_stream in (2, 3, 10):
            for input_channels in (1, 2, 6):
                path = torch.rand((batch_size, input_stream, input_channels))
                for depth in (2, 4, 6):
                    signature = signatory.signature(path, depth)
                    inverted_path = invert_signature(
                        signature,
                        depth,
                        input_channels,
                        initial_position=path[:, 0, :])
                    assert inverted_path.shape == (batch_size, depth + 1,
                                                   input_channels)
コード例 #8
0
def test_insertion_matrix_shape():
    """ Tests that the insertion matrix obtained is of the right shape"""
    for batch_size in (1, 2, 5):
        for input_stream in (2, 3, 10):
            for input_channels in (1, 2, 6):
                path = torch.rand((batch_size, input_stream, input_channels))
                for depth in (1, 2, 4, 6):
                    signature = signatory.signature(path, depth)
                    correct_shape = (batch_size, input_channels,
                                     input_channels**(depth + 1))
                    for insertion_position in range(1, depth + 1):
                        insertion_matrix = get_insertion_matrix(
                            signature, insertion_position, depth,
                            input_channels)
                    assert insertion_matrix.shape == correct_shape
コード例 #9
0
def get_initial(batch_size, input_channels, device, depth, initial):
    """Gets a value for the 'initial' argument of signatory.signature, and also returns the path it used to generate
    that value."""
    if initial in (without_grad, with_grad):
        initial_path = torch.rand(batch_size,
                                  2,
                                  input_channels,
                                  device=device,
                                  dtype=torch.double)
        initial_signature = signatory.signature(initial_path, depth)
        if initial == with_grad:
            initial_signature.requires_grad_()
        return initial_signature
    else:
        return initial
コード例 #10
0
def test_initial_position_zero():
    """Tests that the inverted path initial position is the right one."""
    batch_size = 10
    input_stream = 10
    input_channels = 3
    path = torch.rand((batch_size, input_stream, input_channels))
    for depth in (2, 4, 6):
        signature = signatory.signature(path, depth)
        inverted_path = invert_signature(signature, depth, input_channels)
        assert torch.equal(inverted_path[:, 0, :],
                           torch.zeros(batch_size, input_channels))
        initial_position = torch.rand((batch_size, input_channels))
        inverted_path = invert_signature(signature,
                                         depth,
                                         input_channels,
                                         initial_position=initial_position)
        assert torch.equal(inverted_path[:, 0, :], initial_position)
コード例 #11
0
    def forward(self, x, lengths):
        # `x` should be a three dimensional tensor (batch, stream, channel)
        # `lengths` should be a one dimensional tensor (batch,) giving the true length of each batch element along the
        # stream dimension

        batch, stream, channel = x.shape

        x = become_constant_trick(x, lengths)

        x = stack([augment(x) for augment in self.augments], dim=1)
        # channel_group is essentially an extra batch dimension, but unfortunately signatory.signature doesn't support
        # multiple batch dimensions. So the trick is just to combine all the batch dimensions and then peel them apart
        # again afterwards.
        x = x.view(batch * self.channel_groups, stream, x.size(-1))
        x = signatory.signature(x, self.sig_depth)
        x = x.view(batch, -1)
        x = self.neural(x)
        return x
コード例 #12
0
def sig_stream1(path, depth):  # Unified depth
    path = torch.Tensor(path[None, :, :])
    batch, length, channels = path.shape
    length = length - 1
    index2word = index_to_word(channels, depth)
    dim_sig = len(index2word) + 1
    sig_path_split = [
        signatory.signature(path[:, i:i + 2, :], depth) for i in range(length)
    ]
    add = sig_path_split[0]
    sig_path_stream = [add[:, None, :]]
    for i in range(len(sig_path_split) - 1):
        add = signatory.signature_combine(add, sig_path_split[i + 1], channels,
                                          depth)
        sig_path_stream.append(add[:, None, :])
    sig_path_stream = torch.cat(sig_path_stream, axis=1)
    sig_path_stream = torch.cat(
        [torch.zeros([batch, 1, dim_sig - 1]), sig_path_stream], axis=1)
    sig_path_stream = torch.cat(
        [torch.ones([batch, length + 1, 1]), sig_path_stream], axis=2)
    return sig_path_stream
コード例 #13
0
ファイル: signature.py プロジェクト: andrewXiaY/EzLSH
def make_signature(path="/home/azureuser/ifs/data/",
                   date_str="2019/12/30",
                   freq='5T'):
    df, symbol_list = read_from_db(path, date_str)
    df = df[df.filter(regex='^time$|price|size|no|orders|^sym$').columns]
    # Columns after dropping
    # print("Num cols after filtering ", len(df.columns))

    df_g = df.groupby([
        pd.Grouper(key='time', freq=freq), 'sym'
    ]).mean().apply(lambda x: (x - min(x)) / (max(x) - min(x))).unstack(
        fill_value=0).stack().fillna(0)

    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    data_tensor = torch.from_numpy(df_g.values).float().to(device)

    rows = data_tensor.shape[0]
    cols = data_tensor.shape[1]
    batch = rows // len(symbol_list)

    path = data_tensor.reshape([batch, len(symbol_list), cols])
    sig = signatory.signature(path, 3)
    print("Signature ", sig)
    return sig
コード例 #14
0
def sig(step, stride, level, data):
    size = data.shape[0]
    frame = data.shape[1]
    data = data.reshape(size, 39, 19, 3)
    data = np.swapaxes(data, 1, 2)
    data = data.reshape(size * 19, 39, 3)
    sig = list()
    for i in range(0, frame - step + 1, stride):
        temp_data = data[:, i:i + step, :]
        temp_data = torch.from_numpy(temp_data).float()
        temp_sig = (signatory.logsignature(temp_data, level))
        temp_data = temp_data.cpu().numpy()
        temp_sig = temp_sig.cpu().numpy()
        temp_data = np.swapaxes(temp_data, 0, 1)
        temp_data = temp_data[0]
        att = np.concatenate((temp_data, temp_sig), axis=1)
        sig.append(att)

    if frame % stride > 1:
        temp_data1 = data[:, frame - step + 1:frame, :]
        temp_data1 = torch.from_numpy(temp_data1).float()
        temp_sig1 = (signatory.signature(temp_data1, level))
        temp_data1 = temp_data1.cpu().numpy()
        temp_sig1 = temp_sig1.cpu().numpy()
        temp_data1 = np.swapaxes(temp_data1, 0, 1)
        temp_data1 = temp_data1[0]
        att1 = np.concatenate((temp_data1, temp_sig1), axis=1)
        sig.append(att1)

    sig = np.swapaxes(sig, 0, 1)
    t1 = sig.shape[1]
    s1 = sig.shape[2]
    sig = sig.reshape(size, 19, t1, s1)
    sig = np.swapaxes(sig, 1, 3)
    sig = np.expand_dims(sig, axis=-1)
    return s1, sig
コード例 #15
0
def augment_path_and_compute_signatures(
        x: torch.Tensor, config: SignatureConfig) -> torch.Tensor:
    y = apply_augmentations(x, config.augmentations)
    return signatory.signature(y, config.depth, basepoint=config.basepoint)
コード例 #16
0
def run(obj):
    result = signatory.signature(obj.path, obj.depth)
    torch.cuda.synchronize()
    return result
コード例 #17
0
    batch = signature.shape[0]
    path_derivatives = torch.zeros((batch, depth, channels))
    path = torch.zeros((batch, depth + 1, channels))

    if initial_position is not None:
        path[:, 0, :] = initial_position

    if depth == 1:
        path[:, 1, :] = path[:, 0, :] + signature
    else:
        for insertion_position in torch.arange(1, depth + 1):
            x_optimal = solve_optimization_problem(signature,
                                                   insertion_position, depth,
                                                   channels)
            path_derivatives[:, insertion_position - 1, :] = x_optimal
            path[:, insertion_position, :] = (
                path[:, insertion_position - 1, :] +
                path_derivatives[:, insertion_position - 1, :] * (1 / depth))

    return path


if __name__ == '__main__':
    depth_test = 1
    channels_test = 2
    batch_test = 10

    test_path = torch.rand((batch_test, 100, channels_test))
    signature_test = signatory.signature(test_path, depth_test)
    invert_signature(signature_test, depth_test, channels_test)
コード例 #18
0
import matplotlib
import matplotlib.pyplot as plt
import math
import signatory
import torch

matplotlib.rc('text', usetex=True)
matplotlib.rc('font', size=10)


def save(name):
    plt.tight_layout()
    plt.savefig(name)
    plt.close()


time = torch.linspace(0, 1, 10)
path = torch.stack([torch.cos(math.pi * time), torch.sin(math.pi * time)]).T.unsqueeze(0)

depth = 11
signature = signatory.signature(path, depth)

reconstructed_path = signatory.invert_signature(signature, depth, path.shape[2], initial_position=path[:, 0, :])

plt.plot(path[0, :, 0], path[0, :, 1], marker='o', label='original')
plt.plot(reconstructed_path[0, :, 0], reconstructed_path[0, :, 1], marker='o', label='reconstruction')
plt.legend()
save('Half_circle_inversion.png')
コード例 #19
0
            out = torch.cat(outs, dim=-1)

        if self.affine:
            if self.affine_graded == self.affine_channel:
                out = self._affine_layer(out)
            else:
                end = 0
                term_length = 1
                outs = []
                for affine_layer in self._affine_layers:
                    start = end
                    term_length *= self.channels
                    end = start + term_length
                    outs.append(affine_layer(out[:, start:end]))
                # TODO: not super efficient if we've just cat'd them together above, to split them apart and cat them
                #       again now.
                out = torch.cat(outs, dim=-1)

        return out


if __name__ == '__main__':
    import torch
    import signatory
    a = torch.randn(2, 100, 10)
    signature = [[signatory.signature(a, 2)]]
    normalisation = GradedNormalization(shape=signature[0][0].shape,
                                        channels=10,
                                        depth=2)
    normalisation.forward(signature)
コード例 #20
0
def run(obj):
    return signatory.signature(obj.path, obj.depth)
コード例 #21
0
    def transform(self, X):
        if self.append_zero:
            X = AppendZero().transform(X)
        return torch.cumsum(X, 1)


class AppendZero():
    """ This will append a zero starting vector to every path. """
    def __init__(self):
        pass

    def fit(self, X, y=None):
        return self

    def transform(self, X):
        zero_vec = torch.zeros(size=(X.size(0), 1, X.size(2)))
        return torch.cat((zero_vec, X), dim=1)


if __name__ == '__main__':
    a = torch.randn((10, 50, 10))
    a = torch.rand((1, 10, 2))
    penoff = PenOff().transform(a)
    true_sig = signatory.signature(penoff, 3)

    c = torch.cat((torch.ones(1, a.shape[1], 1), a), dim=2)
    basic_sig = signatory.signature(c, 3)
    d = penoff[:, -2:, :]
    new_sig = signatory.signature(d, 3, basepoint=c[:, -1, :])
    signatory.signature_combine(basic_sig, new_sig, input_channels=3, depth=3)
コード例 #22
0
def compute_signature(x, scalar, sig_depth, with_time, with_lift, with_concat,
                      m):
    y = postprocess(x, scalar, with_time, with_lift, with_concat, m)
    return signatory.signature(y, sig_depth)