25 using namespace shogun;
27 #ifndef DOXYGEN_SHOULD_SKIP_THIS
28 struct LTSA_THREAD_PARAM
41 const int32_t* neighborhood_matrix;
64 PTHREAD_LOCK_T* W_matrix_lock;
80 return "LocalTangentSpaceAlignment";
93 pthread_t* threads =
SG_MALLOC(pthread_t, num_threads);
94 LTSA_THREAD_PARAM* parameters =
SG_MALLOC(LTSA_THREAD_PARAM, num_threads);
96 int32_t num_threads = 1;
110 PTHREAD_LOCK_T W_matrix_lock;
112 PTHREAD_LOCK_INIT(&W_matrix_lock);
113 pthread_attr_init(&attr);
114 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
116 for (t=0; t<num_threads; t++)
118 parameters[t].idx_start = t;
119 parameters[t].idx_step = num_threads;
120 parameters[t].idx_stop = N;
121 parameters[t].m_k =
m_k;
123 parameters[t].neighborhood_matrix = neighborhood_matrix.
matrix;
125 parameters[t].mean_vector = mean_vector + dim*t;
126 parameters[t].local_feature_matrix = local_feature_matrix + (
m_k*dim)*t;
127 parameters[t].feature_matrix = feature_matrix.
matrix;
128 parameters[t].s_values_vector = s_values_vector + dim*t;
129 parameters[t].q_matrix = q_matrix + (
m_k*
m_k)*t;
130 parameters[t].W_matrix = W_matrix;
131 parameters[t].W_matrix_lock = &W_matrix_lock;
133 parameters[t].dim = dim;
134 parameters[t].actual_k = neighborhood_matrix.
num_rows;
135 pthread_create(&threads[t], &attr,
run_ltsa_thread, (
void*)¶meters[t]);
137 for (t=0; t<num_threads; t++)
138 pthread_join(threads[t], NULL);
139 PTHREAD_LOCK_DESTROY(&W_matrix_lock);
143 LTSA_THREAD_PARAM single_thread_param;
144 single_thread_param.idx_start = 0;
145 single_thread_param.idx_step = 1;
146 single_thread_param.idx_stop = N;
147 single_thread_param.m_k =
m_k;
149 single_thread_param.neighborhood_matrix = neighborhood_matrix.
matrix;
150 single_thread_param.G_matrix = G_matrix;
151 single_thread_param.mean_vector = mean_vector;
152 single_thread_param.local_feature_matrix = local_feature_matrix;
153 single_thread_param.feature_matrix = feature_matrix;
154 single_thread_param.s_values_vector = s_values_vector;
155 single_thread_param.q_matrix = q_matrix;
156 single_thread_param.W_matrix = W_matrix;
157 single_thread_param.N = N;
158 single_thread_param.dim = dim;
159 single_thread_param.actual_k = neighborhood_matrix.
num_rows;
170 int32_t actual_k = neighborhood_matrix.
num_rows;
171 for (int32_t i=0; i<N; i++)
173 for (int32_t j=0; j<
m_k; j++)
174 W_matrix[N*neighborhood_matrix[i*actual_k+j]+neighborhood_matrix[i*actual_k+j]] += 1.0;
182 LTSA_THREAD_PARAM* parameters = (LTSA_THREAD_PARAM*)p;
183 int32_t idx_start = parameters->idx_start;
184 int32_t idx_step = parameters->idx_step;
185 int32_t idx_stop = parameters->idx_stop;
186 int32_t
m_k = parameters->m_k;
187 int32_t target_dim = parameters->target_dim;
188 const int32_t* neighborhood_matrix = parameters->neighborhood_matrix;
189 float64_t* G_matrix = parameters->G_matrix;
190 float64_t* mean_vector = parameters->mean_vector;
191 float64_t* local_feature_matrix = parameters->local_feature_matrix;
192 const float64_t* feature_matrix = parameters->feature_matrix;
193 float64_t* s_values_vector = parameters->s_values_vector;
194 float64_t* q_matrix = parameters->q_matrix;
195 float64_t* W_matrix = parameters->W_matrix;
197 PTHREAD_LOCK_T* W_matrix_lock = parameters->W_matrix_lock;
201 int32_t N = parameters->N;
202 int32_t dim = parameters->dim;
203 int32_t actual_k = parameters->actual_k;
205 for (j=0; j<
m_k; j++)
208 for (i=idx_start; i<idx_stop; i+=idx_step)
211 memset(mean_vector,0,
sizeof(
float64_t)*dim);
214 for (j=0; j<
m_k; j++)
216 for (k=0; k<dim; k++)
217 local_feature_matrix[j*dim+k] = feature_matrix[neighborhood_matrix[i*actual_k+j]*dim+k];
219 cblas_daxpy(dim,1.0,local_feature_matrix+j*dim,1,mean_vector,1);
223 cblas_dscal(dim,1.0/m_k,mean_vector,1);
226 for (j=0; j<
m_k; j++)
227 cblas_daxpy(dim,-1.0,mean_vector,1,local_feature_matrix+j*dim,1);
231 wrap_dgesvd(
'N',
'O',dim,m_k,local_feature_matrix,dim,
232 s_values_vector,NULL,1, NULL,1,&info);
235 for (j=0; j<target_dim; j++)
237 for (k=0; k<
m_k; k++)
238 G_matrix[(j+1)*m_k+k] = local_feature_matrix[k*dim+j];
242 cblas_dgemm(CblasColMajor,CblasNoTrans,CblasTrans,
243 m_k,m_k,1+target_dim,
250 PTHREAD_LOCK(W_matrix_lock);
252 for (j=0; j<
m_k; j++)
254 for (k=0; k<
m_k; k++)
255 W_matrix[N*neighborhood_matrix[i*actual_k+k]+neighborhood_matrix[i*actual_k+j]] -= q_matrix[j*m_k+k];
258 PTHREAD_UNLOCK(W_matrix_lock);