Skip to content

Commit

Permalink
Merge branch 'slep' of git://github.com/lisitsyn/shogun
Browse files Browse the repository at this point in the history
  • Loading branch information
lisitsyn committed Jun 27, 2012
2 parents c9b592d + 814db1d commit e80c646
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 39 deletions.
7 changes: 5 additions & 2 deletions src/shogun/transfer/multitask/Task.cpp
Expand Up @@ -16,7 +16,8 @@ CTask::CTask() : CSGObject(),
m_min_index(0), m_max_index(0),
m_weight(1.0), m_subtasks(NULL)
{
m_subtasks = new CList();
m_subtasks = new CList(true);
SG_REF(m_subtasks);
}

CTask::CTask(index_t min_index, index_t max_index,
Expand All @@ -25,7 +26,8 @@ CTask::CTask(index_t min_index, index_t max_index,
m_min_index(min_index), m_max_index(max_index),
m_weight(weight), m_subtasks(NULL)
{
m_subtasks = new CList();
m_subtasks = new CList(true);
SG_REF(m_subtasks);
}

CTask::~CTask()
Expand All @@ -42,5 +44,6 @@ void CTask::add_subtask(CTask* subtask)

CList* CTask::get_subtasks()
{
SG_REF(m_subtasks);
return m_subtasks;
}
37 changes: 4 additions & 33 deletions src/shogun/transfer/multitask/TaskGroup.cpp
Expand Up @@ -38,52 +38,23 @@ bool CTaskGroup::is_valid() const

SGVector<index_t> CTaskGroup::get_SLEP_ind()
{
check_task_list(m_tasks);
int32_t n_subtasks = m_tasks->get_num_elements();
SGVector<index_t> ind(n_subtasks+1);
index_t* min_idxs = SG_MALLOC(index_t, n_subtasks);
index_t* max_idxs = SG_MALLOC(index_t, n_subtasks);
index_t* task_idxs_min = SG_MALLOC(index_t, n_subtasks);
index_t* task_idxs_max = SG_MALLOC(index_t, n_subtasks);

CTask* iter_task = (CTask*)(m_tasks->get_first_element());
ind[0] = 0;
for (int32_t i=0; i<n_subtasks; i++)
{
min_idxs[i] = iter_task->get_min_index();
max_idxs[i] = iter_task->get_max_index();
task_idxs_min[i] = i;
task_idxs_max[i] = i;
SG_UNREF(iter_task);
iter_task = (CTask*)(m_tasks->get_next_element());
}
CMath::qsort_index(min_idxs, task_idxs_min, n_subtasks);
CMath::qsort_index(max_idxs, task_idxs_max, n_subtasks);

for (int32_t i=0; i<n_subtasks; i++)
{
if (task_idxs_min[i] != task_idxs_max[i])
SG_ERROR("Tasks do overlap and it is not supported, please use TaskOverlappingGroup\n");
}
if (min_idxs[0] != 0)
SG_ERROR("Task with smallest indices start from %d while 0 is required\n", min_idxs[0]);
else
ind[0] = 0;
for (int32_t i=1; i<n_subtasks; i++)
{
if (min_idxs[i] > max_idxs[i-1])
SG_ERROR("There is an unsupported gap between %d and %d vectors\n", max_idxs[i-1], min_idxs[i]);
else if (min_idxs[i] < max_idxs[i-1])
SG_ERROR("Tasks do overlap and it is not supported, please use TaskOverlappingGroup\n");

ind[i] = min_idxs[i];
ind[i+1] = iter_task->get_max_index();
}
ind[n_subtasks] = max_idxs[n_subtasks-1];

#ifdef DEBUG_SLEP
ind.display_vector();
#endif

SG_FREE(min_idxs);
SG_FREE(max_idxs);
SG_FREE(task_idxs_min);
SG_FREE(task_idxs_max);
return ind;
}
57 changes: 57 additions & 0 deletions src/shogun/transfer/multitask/TaskRelation.cpp
@@ -0,0 +1,57 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* Copyright (C) 2012 Sergey Lisitsyn
*/

#include <shogun/transfer/multitask/TaskRelation.h>
#include <shogun/transfer/multitask/Task.h>
#include <shogun/lib/SGVector.h>

using namespace shogun;

bool CTaskRelation::check_task_list(CList* tasks)
{
int32_t n_subtasks = tasks->get_num_elements();
index_t* min_idxs = SG_MALLOC(index_t, n_subtasks);
index_t* max_idxs = SG_MALLOC(index_t, n_subtasks);
index_t* task_idxs_min = SG_MALLOC(index_t, n_subtasks);
index_t* task_idxs_max = SG_MALLOC(index_t, n_subtasks);
CTask* iter_task = (CTask*)(tasks->get_first_element());
for (int32_t i=0; i<n_subtasks; i++)
{
min_idxs[i] = iter_task->get_min_index();
max_idxs[i] = iter_task->get_max_index();
task_idxs_min[i] = i;
task_idxs_max[i] = i;
SG_UNREF(iter_task);
iter_task = (CTask*)(tasks->get_next_element());
}
CMath::qsort_index(min_idxs, task_idxs_min, n_subtasks);
CMath::qsort_index(max_idxs, task_idxs_max, n_subtasks);

for (int32_t i=0; i<n_subtasks; i++)
{
if (task_idxs_min[i] != task_idxs_max[i])
SG_ERROR("Tasks do overlap and it is not supported, please use TaskOverlappingGroup\n");
}
if (min_idxs[0] != 0)
SG_ERROR("Task with smallest indices start from %d while 0 is required\n", min_idxs[0]);

for (int32_t i=1; i<n_subtasks; i++)
{
if (min_idxs[i] > max_idxs[i-1])
SG_ERROR("There is an unsupported gap between %d and %d vectors\n", max_idxs[i-1], min_idxs[i]);
else if (min_idxs[i] < max_idxs[i-1])
SG_ERROR("Tasks do overlap and it is not supported, please use TaskOverlappingGroup\n");
}

SG_FREE(min_idxs);
SG_FREE(max_idxs);
SG_FREE(task_idxs_min);
SG_FREE(task_idxs_max);
return true;
}
6 changes: 6 additions & 0 deletions src/shogun/transfer/multitask/TaskRelation.h
Expand Up @@ -11,6 +11,7 @@
#define TASKRELATION_H_

#include <shogun/base/SGObject.h>
#include <shogun/lib/List.h>

namespace shogun
{
Expand Down Expand Up @@ -46,6 +47,11 @@ class CTaskRelation : public CSGObject

/** get relation type */
virtual ETaskRelationType get_relation_type() const = 0;

protected:

bool check_task_list(CList* tasks);

};

}
Expand Down
81 changes: 77 additions & 4 deletions src/shogun/transfer/multitask/TaskTree.cpp
Expand Up @@ -41,13 +41,56 @@ void CTaskTree::set_root_task(CTask* root_task)

SGVector<index_t> CTaskTree::get_SLEP_ind()
{
CList* tasks = new CList();
collect_tasks_recursive(m_root_task, tasks);
CList* tasks = new CList(true);
collect_leaf_tasks_recursive(m_root_task, tasks);
check_task_list(tasks);

SG_DEBUG("Collected %d leaf tasks\n", tasks->get_num_elements());

SGVector<index_t> ind(tasks->get_num_elements()+1);

int t_i = 0;
ind[0] = 0;
CTask* iterator = (CTask*)tasks->get_first_element();
do
{
ind[t_i+1] = iterator->get_max_index();
SG_DEBUG("Task = [%d,%d]\n", iterator->get_min_index(), iterator->get_max_index());
SG_UNREF(iterator);
t_i++;
}
while ((iterator = (CTask*)tasks->get_next_element()) != NULL);

SG_UNREF(tasks);

return ind;
}

SGVector<float64_t> CTaskTree::get_SLEP_ind_t()
{
return SGVector<float64_t>();
CList* tasks = new CList(true);
collect_tasks_recursive(m_root_task, tasks);

SG_DEBUG("Collected %d tree tasks\n", tasks->get_num_elements());

SGVector<float64_t> ind_t(3*tasks->get_num_elements());

int t_i = 0;
CTask* iterator = (CTask*)tasks->get_first_element();
do
{
ind_t[t_i*3] = iterator->get_min_index();
ind_t[t_i*3+1] = iterator->get_max_index();
ind_t[t_i*3+2] = iterator->get_weight();
SG_DEBUG("Task = [%f,%f,%f]\n", ind_t[t_i*3], ind_t[t_i*3+1], ind_t[t_i*3+2]);
SG_UNREF(iterator);
t_i++;
}
while ((iterator = (CTask*)tasks->get_next_element()) != NULL);

SG_UNREF(tasks);

return ind_t;
}

bool CTaskTree::is_valid() const
Expand All @@ -59,5 +102,35 @@ void CTaskTree::collect_tasks_recursive(CTask* subtree_root_task, CList* list)
{
list->append_element(subtree_root_task);

CList* root_task_subtasks = subtree_root_task->get_subtasks();
CList* subtasks = subtree_root_task->get_subtasks();
if (subtasks->get_num_elements() != 0)
{
CTask* iterator = (CTask*)subtasks->get_first_element();
do
{
collect_tasks_recursive(iterator, list);
SG_UNREF(iterator);
}
while ((iterator = (CTask*)subtasks->get_next_element()) != NULL);
}
}

void CTaskTree::collect_leaf_tasks_recursive(CTask* subtree_root_task, CList* list)
{
CList* subtasks = subtree_root_task->get_subtasks();
if (subtasks->get_num_elements() == 0)
{
list->append_element(subtree_root_task);
}
else
{
CTask* iterator = (CTask*)subtasks->get_first_element();
do
{
collect_leaf_tasks_recursive(iterator, list);
SG_UNREF(iterator);
}
while ((iterator = (CTask*)subtasks->get_next_element()) != NULL);
}
SG_UNREF(subtasks);
}
2 changes: 2 additions & 0 deletions src/shogun/transfer/multitask/TaskTree.h
Expand Up @@ -57,6 +57,8 @@ class CTaskTree : public CTaskRelation
protected:

void collect_tasks_recursive(CTask* subtree_root_node, CList* list);

void collect_leaf_tasks_recursive(CTask* subtree_root_node, CList* list);

private:

Expand Down

0 comments on commit e80c646

Please sign in to comment.