tnn_error tnn_loss_debug_euclidean(tnn_loss *l){
  tnn_error ret;

  //Routine check
  if(l->t != TNN_LOSS_TYPE_EUCLIDEAN){
    return TNN_ERROR_LOSS_MISTYPE;
  }

  printf("loss (euclidean) = %p, type = %d, const = %p\n", l, l->t, l->c);
  printf("bprop = %p, fprop = %p, randomize = %p, destroy = %p, debug = %p\n", l->bprop, l->fprop, l->randomize, l-> destroy, l->debug);
  printf("paramters: ");
  if((ret = tnn_state_debug(&l->w))!=TNN_ERROR_SUCCESS){
    printf("loss (euclidean) paramter state debug error\n");
    return ret;
  }
  printf("input 1: ");
  if((ret = tnn_state_debug(l->input1)) != TNN_ERROR_SUCCESS){
    printf("loss (euclidean) input1 state debug error\n");
    return ret;
  }
  printf("input 2: ");
  if((ret = tnn_state_debug(l->input2)) != TNN_ERROR_SUCCESS){
    printf("loss (euclidean) input2 state debug error\n");
    return ret;
  }
  printf("output: ");
  if((ret = tnn_state_debug(l->output)) != TNN_ERROR_SUCCESS){
    printf("loss (euclidean) output state debug error\n");
    return ret;
  }
  return TNN_ERROR_SUCCESS;
}
tnn_error tnn_module_debug_bias(tnn_module *m){
  tnn_error ret;

  //Routine check
  if(m->t != TNN_MODULE_TYPE_BIAS){
    printf("module (bias) mistype\n");
    return TNN_ERROR_MODULE_MISTYPE;
  }

  printf("module (bias) = %p, prev = %p, next = %p, type = %d, constant = %p\n", m, m->prev, m->next, m->t, m->c);
  printf("bprop = %p, fprop = %p, randomize = %p, destroy = %p, debug = %p, clone = %p\n",
         m->bprop, m->fprop, m->randomize, m->destroy, m->debug, m->clone);
  printf("paramter: ");
  if((ret = tnn_state_debug(&m->w)) != TNN_ERROR_SUCCESS){
    printf("module (bias) parameter state debug error\n");
    return ret;
  }
  printf("input: ");
  if((ret = tnn_state_debug(m->input)) != TNN_ERROR_SUCCESS){
    printf("module (bias) input state debug error\n");
    return ret;
  }
  printf("output: ");
  if((tnn_state_debug(m->output)) != TNN_ERROR_SUCCESS){
    printf("module (bias) output state debug error\n");
    return ret;
  }

  return TNN_ERROR_SUCCESS;
}
tnn_error tnn_module_debug_sum(tnn_module *m){
  tnn_error ret;
  tnn_state **t;
  size_t i;

  //Routine check
  if(m->t != TNN_MODULE_TYPE_SUM){
    printf("module (sum) mistype\n");
    return TNN_ERROR_MODULE_MISTYPE;
  }

  printf("module (sum) = %p, prev = %p, next = %p, type = %d, constant = %p\n", m, m->prev, m->next, m->t, m->c);
  printf("bprop = %p, fprop = %p, randomize = %p, destroy = %p, debug = %p\n", m->bprop, m->fprop, m->randomize, m->destroy, m->debug);
  printf("paramter: ");
  if((ret = tnn_state_debug(&m->w)) != TNN_ERROR_SUCCESS){
    printf("module (sum) debug error\n");
    return ret;
  }
  printf("input: ");
  if((ret = tnn_state_debug(m->input)) != TNN_ERROR_SUCCESS){
    printf("module (sum) debug error\n");
    return ret;
  }
  printf("output: ");
  if((ret = tnn_state_debug(m->output)) != TNN_ERROR_SUCCESS){
    printf("module (sum) debug error\n");
    return ret;
  }
  for(t = (tnn_state **)utarray_front(((tnn_module_sum*)m->c)->sarray), i = 0L;
      t != NULL;
      t = (tnn_state **)utarray_next(((tnn_module_sum*)m->c)->sarray, t), i = i + 1L){
    printf("subinput #%ld: ", i);
    if((ret = tnn_state_debug(*t))!= TNN_ERROR_SUCCESS){
      printf("module (sum) debug error\n");
      return ret;
    }
  }
  return TNN_ERROR_SUCCESS;
}
int main(){
  tnn_param p, io;
  tnn_state in, out, *s;
  tnn_module m;
  int i;

  printf("Initializing state in: %s\n", TEST_FUNC(tnn_state_init(&in, A)));
  printf("Initializing state out: %s\n", TEST_FUNC(tnn_state_init(&out, B)));
  printf("Initializing paramter p: %s\n", TEST_FUNC(tnn_param_init(&p)));
  printf("Initializing paramter io: %s\n", TEST_FUNC(tnn_param_init(&io)));
  printf("Allocating state in: %s\n", TEST_FUNC(tnn_param_state_alloc(&io, &in)));
  printf("Allocating state out: %s\n", TEST_FUNC(tnn_param_state_alloc(&io, &out)));
  printf("Initializing module m: %s\n", TEST_FUNC(tnn_module_init_sum(&m, &in, &out, &io)));
  printf("Debugging module m: %s\n", TEST_FUNC(tnn_module_debug(&m)));

  printf("Setting input\n");
  for(i = 0; i < in.size; i = i + 1){
    gsl_vector_set(&in.x, i, (double)(C+i));
  }

  printf("Setting output\n");
  for(i = 0; i < out.size; i = i + 1){
    gsl_vector_set(&out.dx, i, 2.0*(double)(D+i));
  }

  printf("Radomizing weights using polymorphic call: %s\n", TEST_FUNC(tnn_module_randomize(&m, 1.0)));
  printf("Debugging module m: %s\n", TEST_FUNC(tnn_module_debug(&m)));

  printf("Executing fprop using polymorphic call: %s\n", TEST_FUNC(tnn_module_fprop(&m)));
  printf("Debugging module m: %s\n", TEST_FUNC(tnn_module_debug(&m)));

  printf("Executing bprop using polymorphic call: %s\n", TEST_FUNC(tnn_module_bprop(&m)));
  printf("Debugging module m: %s\n", TEST_FUNC(tnn_module_debug(&m)));

  for(i = 0; i < A/B; i = i + 1){
    printf("Executing get: %s\n", TEST_FUNC(tnn_module_sum_get(&m, &s, i)));
    printf("Debugging s: %s\n", TEST_FUNC(tnn_state_debug(s)));
  }

  printf("Debugging parameter p: %s\n", TEST_FUNC(tnn_param_debug(&p)));
  printf("Debugging parameter io: %s\n", TEST_FUNC(tnn_param_debug(&io)));

  printf("Destroying paramter p: %s\n", TEST_FUNC(tnn_param_destroy(&p)));
  printf("Destroying paramter io: %s\n", TEST_FUNC(tnn_param_destroy(&io)));
  printf("Destroy module m using polymorphic call: %s\n", TEST_FUNC(tnn_module_destroy(&m)));
  printf("Debugging module m: %s\n", TEST_FUNC(tnn_module_debug(&m)));
  
  return 0;
}
int main(){
  tnn_state s[N];
  tnn_state t, u, v;
  tnn_param p;
  tnn_state *sp;
  int i,j;

  //Initialize all the states
  for(i = 0; i < N; i = i + 1){
    printf("Initializing state %d: %s\n", i, TEST_FUNC(tnn_state_init(&s[i], i + M)));
    printf("Initialized state %d to be size %d, valid %d.\n", i, s[i].size, s[i].valid);
  }

  //Initialize the parameter
  printf("Initializing parameter: %s\n", TEST_FUNC(tnn_param_init(&p)));
  tnn_param_debug(&p);

  //Allocate states in the paramter
  for(i = 0; i < N; i = i + 1){
    printf("Allocating state %d: %s\n", i, TEST_FUNC(tnn_param_state_alloc(&p, &s[i])));
    printf("Allocated state %d to be valid %d, vector owner %d.\n", i, s[i].valid, s[i].x.owner);
    tnn_param_debug(&p);
  }

  //Initialize the values in the vector
  for(i = 0; i < p.x->size; i = i + 1){
    gsl_vector_set(p.x, i, i + A);
    gsl_vector_set(p.dx, i, i + B);
  }
  tnn_param_debug(&p);

  //Initialize values for t using calloc
  printf("Initializing state t: %s\n", TEST_FUNC(tnn_state_init(&t, I)));
  printf("Initialized state t to be size %d, valid %d.\n", t.size, t.valid);
  printf("Allocating state t: %s\n", TEST_FUNC(tnn_param_state_calloc(&p, &t)));
  printf("Allocated state t to be valid %d, vector owner %d.\n", t.valid, t.x.owner);
  tnn_param_debug(&p);

  printf("Initializing state u: %s\n", TEST_FUNC(tnn_state_init(&u, J)));
  printf("Getting subvector u: %s\n", TEST_FUNC(tnn_param_state_sub(&p, &s[N-1], &u, 1)));
  tnn_param_debug(&p);

  printf("Initializing state v: %s\n", TEST_FUNC(tnn_state_init(&v, s[N-1].size)));
  tnn_state_debug(&v);
  printf("Allocating state v: %s\n", TEST_FUNC(tnn_param_state_calloc(&p, &v)));
  printf("Copying s to v: %s\n", TEST_FUNC(tnn_state_copy(&s[N-1],&v)));
  tnn_state_debug(&v);
  tnn_param_debug(&p);

  //Destroy the parameter
  printf("Destroying the paramter: %s.\n", TEST_FUNC(tnn_param_destroy(&p)));
  printf("Destroyed paramter x = %d, dx = %d, states = %d, size = %d.\n", p.x, p.dx, p.states, p.size);
  for(i = 0; i < N; i = i + 1){
    printf("Destroyed state %d, valid: %d\n", i, s[i].valid);
  }
  printf("Destroyed state t, valid: %d\n", t.valid);
  printf("Destroyed state u, valid: %d\n", u.valid);
  tnn_param_debug(&p);

  //Delete paramter experiment
  printf("Initializing paramter: %s\n", TEST_FUNC(tnn_param_init(&p)));
  for(i = 0; i < N; i = i + 1){
    sp = (tnn_state *) malloc(sizeof(tnn_state));
    printf("Initializing sp %p: %s\n", sp, TEST_FUNC(tnn_state_init(sp,A+i)));
    printf("Allocating sp %p: %s\n", sp, TEST_FUNC(tnn_param_state_calloc(&p, sp)));
  }
  printf("Debugging paramter: %s\n", TEST_FUNC(tnn_param_debug(&p)));
  printf("Free paramter: %s\n", TEST_FUNC(tnn_param_free(&p)));
  printf("Debugging paramter: %s\n", TEST_FUNC(tnn_param_debug(&p)));
}
//Debug this trainer
tnn_error tnn_trainer_class_debug_nsgd(tnn_trainer_class *t){
  tnn_error ret;
  size_t i,j;

  //Routine check
  if(t->t != TNN_TRAINER_CLASS_TYPE_NSGD){
    printf("Trainer classifcation (Naive SGD) mistype\n");
    return TNN_ERROR_TRAINER_CLASS_MISTYPE;
  }

  ret = TNN_ERROR_SUCCESS;

  printf("Trainer classification (Naive SGD) = %p, type = %d, constant = %p, label_set = %p, lambda = %g\n", t, t->t, t->c, t->lset, t->lambda);
  printf("losses = %p, learn = %p, train = %p, debug = %p, destroy = %p\n", t->losses, t->learn, t->train, t->debug, t->destroy);
  printf("eta = %g, epsilon = %g, eiter = %ld, niter = %ld, titer = %ld\n",
	 ((tnn_trainer_class_nsgd*)t->c)->eta,
	 ((tnn_trainer_class_nsgd*)t->c)->epsilon,
	 ((tnn_trainer_class_nsgd*)t->c)->eiter,
	 ((tnn_trainer_class_nsgd*)t->c)->niter,
	 ((tnn_trainer_class_nsgd*)t->c)->titer);

  printf("machine: ");
  if((ret = tnn_machine_debug(&t->m)) != TNN_ERROR_SUCCESS && ret != TNN_ERROR_MODULE_FUNCNDEF){
    printf("machine debug error in trainer classsification\n");
    return ret;
  }

  printf("loss: ");
  if((ret = tnn_loss_debug(&t->l)) != TNN_ERROR_SUCCESS && ret != TNN_ERROR_LOSS_FUNCNDEF){
    printf("loss debug error in trainer classsification\n");
    return ret;
  }

  printf("label: ");
  if((ret = tnn_state_debug(t->label)) != TNN_ERROR_SUCCESS){
    printf("label state debug error in trainer classification\n");
    return ret;
  }

  printf("regularizer: ");
  if((ret = tnn_reg_debug(&t->r)) != TNN_ERROR_SUCCESS && ret != TNN_ERROR_REG_FUNCNDEF){
    printf("regularizer debug error in classification\n");
    return ret;
  }

  printf("label_set: size1 = %ld, size2 = %ld\n", t->lset->size1, t->lset->size2);
  for(i = 0; i < t->lset->size1; i = i + 1){
    printf("%ld:", i);
    for(j = 0; j < t->lset->size2; j = j + 1){
      printf(" %g", gsl_matrix_get(t->lset, i, j));
    }
    printf("\n");
  }

  printf("losses: size = %ld, values:", t->losses->size);
  for(i = 0; i < t->losses->size; i = i + 1){
    printf(" %g", gsl_vector_get(t->losses, i));
  }
  printf("\n");

  return ret;
}