aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGertjan van den Burg <burg@ese.eur.nl>2016-09-30 20:22:18 +0200
committerGertjan van den Burg <burg@ese.eur.nl>2016-09-30 20:22:18 +0200
commit369fd7c981bc468e9002be6f4813e08664413a81 (patch)
tree37312074e6dabb06b1375f298666a7fe63a78237
parentremove unnecessary W and t matrices (diff)
downloadgensvm-369fd7c981bc468e9002be6f4813e08664413a81.tar.gz
gensvm-369fd7c981bc468e9002be6f4813e08664413a81.zip
Remove category matrix from implementation
It's a remnant from the Matlab implementation, where it actually makes sense to use. Here it becomes a significant memory burden for large datasets, and doesn't provide any speedup
-rw-r--r--include/gensvm_base.h3
-rw-r--r--include/gensvm_optimize.h8
-rw-r--r--src/gensvm_base.c6
-rw-r--r--src/gensvm_optimize.c53
-rw-r--r--tests/src/test_gensvm_optimize.c74
5 files changed, 24 insertions, 120 deletions
diff --git a/include/gensvm_base.h b/include/gensvm_base.h
index ded0149..390a9b6 100644
--- a/include/gensvm_base.h
+++ b/include/gensvm_base.h
@@ -87,9 +87,6 @@ struct GenModel {
///< error matrix
double *H;
///< Huber weighted error matrix
- double *R;
- ///< 0-1 auixiliary matrix, this matrix is n x K, with for row i a 0 on
- ///< column y[i]-1, and 1 everywhere else.
double *rho;
///< vector of instance weights
double training_error;
diff --git a/include/gensvm_optimize.h b/include/gensvm_optimize.h
index bef9669..3fd9607 100644
--- a/include/gensvm_optimize.h
+++ b/include/gensvm_optimize.h
@@ -22,8 +22,10 @@ void gensvm_optimize(struct GenModel *model, struct GenData *data);
double gensvm_get_loss(struct GenModel *model, struct GenData *data,
double *ZV);
-double gensvm_calculate_omega(struct GenModel *model, long i);
-bool gensvm_majorize_is_simple(struct GenModel *model, long i);
+double gensvm_calculate_omega(struct GenModel *model, struct GenData *data,
+ long i);
+bool gensvm_majorize_is_simple(struct GenModel *model, struct GenData *data,
+ long i);
void gensvm_calculate_ab_non_simple(struct GenModel *model, long i, long j,
double *a, double *b_aq);
void gensvm_calculate_ab_simple(struct GenModel *model, long i, long j,
@@ -34,8 +36,6 @@ double gensvm_get_Avalue_update_B(struct GenModel *model, long i, double *B);
void gensvm_get_update(struct GenModel *model, struct GenData *data,
double *B, double *ZAZ, double *ZAZV, double *ZAZVT);
-void gensvm_category_matrix(struct GenModel *model, struct GenData *data);
-void gensvm_simplex_diff(struct GenModel *model, struct GenData *dataset);
void gensvm_calculate_errors(struct GenModel *model, struct GenData *data,
double *ZV);
void gensvm_calculate_huber(struct GenModel *model);
diff --git a/src/gensvm_base.c b/src/gensvm_base.c
index 7710fc9..2c30530 100644
--- a/src/gensvm_base.c
+++ b/src/gensvm_base.c
@@ -94,7 +94,6 @@ struct GenModel *gensvm_init_model()
model->UU = NULL;
model->Q = NULL;
model->H = NULL;
- model->R = NULL;
model->rho = NULL;
model->data_file = NULL;
@@ -123,7 +122,6 @@ void gensvm_allocate_model(struct GenModel *model)
model->UU = Calloc(double, n*K*(K-1));
model->Q = Calloc(double, n*K);
model->H = Calloc(double, n*K);
- model->R = Calloc(double, n*K);
model->rho = Calloc(double, n);
}
@@ -156,9 +154,6 @@ void gensvm_reallocate_model(struct GenModel *model, long n, long m)
model->H = Realloc(model->H, double, n*K);
Memset(model->H, double, n*K);
- model->R = Realloc(model->R, double, n*K);
- Memset(model->R, double, n*K);
-
model->rho = Realloc(model->rho, double, n);
Memset(model->rho, double, n);
@@ -197,7 +192,6 @@ void gensvm_free_model(struct GenModel *model)
free(model->Q);
free(model->H);
free(model->rho);
- free(model->R);
free(model->kernelparam);
free(model->data_file);
diff --git a/src/gensvm_optimize.c b/src/gensvm_optimize.c
index 19e697e..d08f917 100644
--- a/src/gensvm_optimize.c
+++ b/src/gensvm_optimize.c
@@ -68,7 +68,7 @@ void gensvm_optimize(struct GenModel *model, struct GenData *data)
gensvm_simplex(model->K, model->U);
gensvm_simplex_diff(model, data);
- gensvm_category_matrix(model, data);
+ gensvm_simplex(model);
L = gensvm_get_loss(model, data, ZV);
Lbar = L + 2.0*model->epsilon*L;
@@ -141,9 +141,10 @@ double gensvm_get_loss(struct GenModel *model, struct GenData *data,
rowvalue = 0;
value = 0;
for (j=0; j<K; j++) {
+ if (j == (data->y[i]-1))
+ continue;
value = matrix_get(model->H, K, i, j);
value = pow(value, model->p);
- value *= matrix_get(model->R, K, i, j);
rowvalue += value;
}
rowvalue = pow(rowvalue, 1.0/(model->p));
@@ -181,16 +182,18 @@ double gensvm_get_loss(struct GenModel *model, struct GenData *data,
* @returns the value of omega for instance i
*
*/
-double gensvm_calculate_omega(struct GenModel *model, long i)
+double gensvm_calculate_omega(struct GenModel *model, struct GenData *data,
+ long i)
{
long j;
- double h, r, omega = 0.0,
+ double h, omega = 0.0,
p = model->p;
for (j=0; j<model->K; j++) {
+ if (j == (data->y[i]-1))
+ continue;
h = matrix_get(model->H, model->K, i, j);
- r = matrix_get(model->R, model->K, i, j);
- omega += pow(h, p)*r;
+ omega += pow(h, p);
}
omega = (1.0/p)*pow(omega, 1.0/p - 1.0);
@@ -211,14 +214,16 @@ double gensvm_calculate_omega(struct GenModel *model, long i)
* @returns whether or not we can do simple majorization
*
*/
-bool gensvm_majorize_is_simple(struct GenModel *model, long i)
+bool gensvm_majorize_is_simple(struct GenModel *model, struct GenData *data,
+ long i)
{
long j;
- double h, r, value = 0;
+ double h, value = 0;
for (j=0; j<model->K; j++) {
+ if (j == (data->y[i]-1))
+ continue;
h = matrix_get(model->H, model->K, i, j);
- r = matrix_get(model->R, model->K, i, j);
- value += (h*r > 0) ? 1 : 0;
+ value += (h > 0) ? 1 : 0;
if (value > 1)
return false;
}
@@ -572,34 +577,6 @@ void gensvm_get_update(struct GenModel *model, struct GenData *data,
}
/**
- * @brief Generate the category matrix
- *
- * @details
- * Generate the category matrix R. The category matrix has 1's everywhere
- * except at the column corresponding to the label of instance i, there the
- * element is 0.
- *
- * @param[in,out] model corresponding GenModel
- * @param[in] dataset corresponding GenData
- *
- */
-void gensvm_category_matrix(struct GenModel *model, struct GenData *data)
-{
- long i, j;
- long n = model->n;
- long K = model->K;
-
- for (i=0; i<n; i++) {
- for (j=0; j<K; j++) {
- if (data->y[i] != j+1)
- matrix_set(model->R, K, i, j, 1.0);
- else
- matrix_set(model->R, K, i, j, 0.0);
- }
- }
-}
-
-/**
* @brief Generate the simplex difference matrix
*
* @details
diff --git a/tests/src/test_gensvm_optimize.c b/tests/src/test_gensvm_optimize.c
index a91ece7..f0947a4 100644
--- a/tests/src/test_gensvm_optimize.c
+++ b/tests/src/test_gensvm_optimize.c
@@ -198,7 +198,6 @@ char *test_gensvm_get_loss_1()
gensvm_initialize_weights(data, model);
gensvm_simplex(model->K, model->U);
gensvm_simplex_diff(model, data);
- gensvm_category_matrix(model, data);
matrix_set(model->V, model->K-1, 0, 0, 0.6019309459245683);
matrix_set(model->V, model->K-1, 0, 1, 0.0063825200426701);
@@ -297,7 +296,6 @@ char *test_gensvm_get_loss_2()
gensvm_initialize_weights(data, model);
gensvm_simplex(model->K, model->U);
gensvm_simplex_diff(model, data);
- gensvm_category_matrix(model, data);
matrix_set(model->V, model->K-1, 0, 0, 0.6019309459245683);
matrix_set(model->V, model->K-1, 0, 1, 0.0063825200426701);
@@ -349,7 +347,6 @@ char *test_gensvm_calculate_omega()
model->K = K;
model->p = 1.213;
gensvm_allocate_model(model);
- gensvm_category_matrix(model, data);
matrix_set(model->H, model->K, 0, 0, 0.8465725800087526);
matrix_set(model->H, model->K, 0, 1, 1.2876921677680249);
@@ -417,7 +414,6 @@ char *test_gensvm_majorize_is_simple()
model->K = K;
model->p = 1.213;
gensvm_allocate_model(model);
- gensvm_category_matrix(model, data);
matrix_set(model->H, model->K, 0, 0, 0.8465725800087526);
matrix_set(model->H, model->K, 0, 1, 1.2876921677680249);
@@ -436,15 +432,15 @@ char *test_gensvm_majorize_is_simple()
matrix_set(model->H, model->K, 4, 2, 0.8184193969741095);
// start test code //
- mu_assert(gensvm_majorize_is_simple(model, 0) == false,
+ mu_assert(gensvm_majorize_is_simple(model, data, 0) == false,
"Incorrect simple at 0");
- mu_assert(gensvm_majorize_is_simple(model, 1) == true,
+ mu_assert(gensvm_majorize_is_simple(model, data, 1) == true,
"Incorrect simple at 1");
- mu_assert(gensvm_majorize_is_simple(model, 2) == true,
+ mu_assert(gensvm_majorize_is_simple(model, data, 2) == true,
"Incorrect simple at 2");
- mu_assert(gensvm_majorize_is_simple(model, 3) == true,
+ mu_assert(gensvm_majorize_is_simple(model, data, 3) == true,
"Incorrect simple at 3");
- mu_assert(gensvm_majorize_is_simple(model, 4) == false,
+ mu_assert(gensvm_majorize_is_simple(model, data, 4) == false,
"Incorrect simple at 4");
// end test code //
@@ -599,7 +595,6 @@ char *test_gensvm_update_B()
gensvm_allocate_model(model);
gensvm_simplex(model->K, model->U);
gensvm_simplex_diff(model, data);
- gensvm_category_matrix(model, data);
gensvm_initialize_weights(data, model);
// start test code //
@@ -716,7 +711,6 @@ char *test_gensvm_get_update()
gensvm_initialize_weights(data, model);
gensvm_simplex(model->K, model->U);
gensvm_simplex_diff(model, data);
- gensvm_category_matrix(model, data);
// initialize V
matrix_set(model->V, model->K-1, 0, 0, -0.7593642121025029);
@@ -780,63 +774,6 @@ char *test_gensvm_get_update()
return NULL;
}
-char *test_gensvm_category_matrix()
-{
- struct GenModel *model = gensvm_init_model();
- struct GenData *data = gensvm_init_data();
-
- int n = 5,
- m = 3,
- K = 3;
-
- data->n = n;
- data->m = m;
- data->K = K;
-
- model->n = n;
- model->m = m;
- model->K = K;
-
- gensvm_allocate_model(model);
- data->y = Calloc(long, data->n);
- data->y[0] = 1;
- data->y[1] = 2;
- data->y[2] = 3;
- data->y[3] = 2;
- data->y[4] = 1;
-
- // start test code //
-
- gensvm_category_matrix(model, data);
-
- mu_assert(matrix_get(model->R, K, 0, 0) == 0, "Incorrect R at 0, 0");
- mu_assert(matrix_get(model->R, K, 0, 1) == 1, "Incorrect R at 0, 1");
- mu_assert(matrix_get(model->R, K, 0, 2) == 1, "Incorrect R at 0, 2");
-
- mu_assert(matrix_get(model->R, K, 1, 0) == 1, "Incorrect R at 1, 0");
- mu_assert(matrix_get(model->R, K, 1, 1) == 0, "Incorrect R at 1, 1");
- mu_assert(matrix_get(model->R, K, 1, 2) == 1, "Incorrect R at 1, 2");
-
- mu_assert(matrix_get(model->R, K, 2, 0) == 1, "Incorrect R at 2, 0");
- mu_assert(matrix_get(model->R, K, 2, 1) == 1, "Incorrect R at 2, 1");
- mu_assert(matrix_get(model->R, K, 2, 2) == 0, "Incorrect R at 2, 2");
-
- mu_assert(matrix_get(model->R, K, 3, 0) == 1, "Incorrect R at 3, 0");
- mu_assert(matrix_get(model->R, K, 3, 1) == 0, "Incorrect R at 3, 1");
- mu_assert(matrix_get(model->R, K, 3, 2) == 1, "Incorrect R at 3, 2");
-
- mu_assert(matrix_get(model->R, K, 4, 0) == 0, "Incorrect R at 4, 0");
- mu_assert(matrix_get(model->R, K, 4, 1) == 1, "Incorrect R at 4, 1");
- mu_assert(matrix_get(model->R, K, 4, 2) == 1, "Incorrect R at 4, 2");
-
- // end test code //
-
- gensvm_free_model(model);
- gensvm_free_data(data);
-
- return NULL;
-}
-
char *test_gensvm_simplex_diff()
{
struct GenData *data = gensvm_init_data();
@@ -1692,7 +1629,6 @@ char *all_tests()
mu_run_test(test_gensvm_get_Avalue_update_B);
mu_run_test(test_gensvm_get_update);
- mu_run_test(test_gensvm_category_matrix);
mu_run_test(test_gensvm_simplex_diff);
mu_run_test(test_gensvm_calculate_errors);
mu_run_test(test_gensvm_calculate_huber);