Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions pytsne.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh
cython-3.6 pytsne.pyx
clang++ -shared -fPIC pytsne.c tsne.cpp sptree.cpp \
-L/opt/local/lib `python3.6-config --includes --ldflags` \
-I/opt/local/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/numpy/core/include \
-o pytsne.so
6 changes: 6 additions & 0 deletions pytsne.pxd
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
cdef extern:
ctypedef double double_t
void tsne_run(double* X, int N, int D, double* Y,
int no_dims, double perplexity, double theta, int rand_seed,
int skip_random_init, int max_iter, int stop_lying_iter,
int mom_switch_iter) nogil
24 changes: 24 additions & 0 deletions pytsne.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
cimport pytsne
cimport numpy as np


cdef class tsne:
@staticmethod
def run(np.ndarray[double_t, ndim=2, mode="c"] X,
int no_dims, # number of output dims
double perplexity,
double theta,
int rand_seed,
int skip_random_init,
int max_iter=1000,
int stop_lying_iter=250,
int mom_switch_iter=250):

N = X.shape[0]
D = X.shape[1]
cdef np.ndarray[double_t, ndim=2, mode="c"] Y = np.ndarray((N, no_dims))

tsne_run(&X[0, 0], N, D, &Y[0, 0], no_dims, perplexity, theta, rand_seed,
skip_random_init, max_iter, stop_lying_iter, mom_switch_iter)

return Y
5 changes: 5 additions & 0 deletions pytsne_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from pytsne import tsne
import numpy as np

a = np.random.random((1000,5))
tsne.run(a, 2, 5, 0, 0, 0)
13 changes: 13 additions & 0 deletions tsne.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ void TSNE::run(double* X, int N, int D, double* Y, int no_dims, double perplexit
P = (double*) malloc(N * N * sizeof(double));
if(P == NULL) { printf("Memory allocation failed!\n"); exit(1); }
computeGaussianPerplexity(X, N, D, P, perplexity);
printf("perplexity: %f\n", perplexity);

// Symmetrize input similarities
printf("Symmetrizing...\n");
Expand Down Expand Up @@ -702,3 +703,15 @@ void TSNE::save_data(double* data, int* landmarks, double* costs, int n, int d)
fclose(h);
printf("Wrote the %i x %i data matrix successfully!\n", n, d);
}

extern "C" {
void tsne_run(double* X, int N, int D, double* Y,
int no_dims, double perplexity, double theta,
int rand_seed, int skip_random_init,
int max_iter, int stop_lying_iter, int mom_switch_iter) {

TSNE::run(X, N, D, Y, no_dims, perplexity,
theta, rand_seed, (bool) skip_random_init,
max_iter, stop_lying_iter, mom_switch_iter);
}
}
27 changes: 14 additions & 13 deletions tsne.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,24 @@ static inline double sign(double x) { return (x == .0 ? .0 : (x < .0 ? -1.0 : 1.
class TSNE
{
public:
void run(double* X, int N, int D, double* Y, int no_dims, double perplexity, double theta, int rand_seed,
static void run(double* X, int N, int D, double* Y, int no_dims, double perplexity, double theta, int rand_seed,
bool skip_random_init, int max_iter=1000, int stop_lying_iter=250, int mom_switch_iter=250);
bool load_data(double** data, int* n, int* d, int* no_dims, double* theta, double* perplexity, int* rand_seed, int* max_iter);
void save_data(double* data, int* landmarks, double* costs, int n, int d);
void symmetrizeMatrix(unsigned int** row_P, unsigned int** col_P, double** val_P, int N); // should be static!
static bool load_data(double** data, int* n, int* d, int* no_dims, double* theta, double* perplexity, int* rand_seed, int* max_iter);
static void save_data(double* data, int* landmarks, double* costs, int n, int d);
static void symmetrizeMatrix(unsigned int** row_P, unsigned int** col_P, double** val_P, int N); // should be static!


private:
void computeGradient(double* P, unsigned int* inp_row_P, unsigned int* inp_col_P, double* inp_val_P, double* Y, int N, int D, double* dC, double theta);
void computeExactGradient(double* P, double* Y, int N, int D, double* dC);
double evaluateError(double* P, double* Y, int N, int D);
double evaluateError(unsigned int* row_P, unsigned int* col_P, double* val_P, double* Y, int N, int D, double theta);
void zeroMean(double* X, int N, int D);
void computeGaussianPerplexity(double* X, int N, int D, double* P, double perplexity);
void computeGaussianPerplexity(double* X, int N, int D, unsigned int** _row_P, unsigned int** _col_P, double** _val_P, double perplexity, int K);
void computeSquaredEuclideanDistance(double* X, int N, int D, double* DD);
double randn();
static void computeGradient(double* P, unsigned int* inp_row_P, unsigned int* inp_col_P, double* inp_val_P, double* Y, int N, int D, double* dC, double theta);
static void computeExactGradient(double* P, double* Y, int N, int D, double* dC);
static double evaluateError(double* P, double* Y, int N, int D);
static double evaluateError(unsigned int* row_P, unsigned int* col_P, double* val_P, double* Y, int N, int D, double theta);
static void zeroMean(double* X, int N, int D);
static void computeGaussianPerplexity(double* X, int N, int D, double* P, double perplexity);
static void computeGaussianPerplexity(double* X, int N, int D, unsigned int** _row_P, unsigned int** _col_P, double** _val_P, double perplexity, int K);
static void computeSquaredEuclideanDistance(double* X, int N, int D, double* DD);
static double randn();
};


#endif