Algorithm-SVMLight

 view release on metacpan or  search on metacpan

lib/Algorithm/SVMLight.xs  view on Meta::CPAN

#ifdef __cplusplus
extern "C" {
#endif
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#ifdef __cplusplus
}
#endif

/* Standard system headers: */
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>

/* Stuff from the SVM Light source: */
/* #include "kernel.h" */
#include "svm_common.h"
#include "svm_learn.h"


#define INITIAL_DOCS 8
#define EXPANSION_FACTOR 2.0

typedef struct {
  long num_features;
  long num_docs;
  long allocated_docs;
  DOC **docs;
  double *labels;
} corpus;

double ranking_callback(DOC **docs, double *rankvalue, long i, long j, LEARN_PARM *learn_parm) {
  dSP;
  SV *callback = (SV *) learn_parm->costfunccustom;
  int count;
  double result;

  /* Don't bother checking the type of 'callback' - it could be a CODE
   * reference or a string, and perl will throw its own error otherwise.
   */

  ENTER;
  SAVETMPS;

  PUSHMARK(SP);
  XPUSHs(sv_2mortal(newSVnv(rankvalue[i])));
  XPUSHs(sv_2mortal(newSVnv(rankvalue[j])));
  XPUSHs(sv_2mortal(newSVnv(docs[i]->costfactor)));
  XPUSHs(sv_2mortal(newSVnv(docs[j]->costfactor)));
  PUTBACK ;

  count = call_sv(callback, G_SCALAR);
  SPAGAIN;
  if (count != 1)
    croak("Expected 1 return value from ranking callback, but got %d", count);
  result = POPn;

  PUTBACK;
  FREETMPS;
  LEAVE;

  return result;
}


SV **
self_store(SV *self, void *ptr, const char *slot, int make_readonly) {
  HV *self_hash = (HV*) SvRV(self);
  SV **fetched = hv_fetch(self_hash, slot, strlen(slot), 1);
  if (fetched == NULL) croak("Couldn't create the %s slot in $self", slot);
  
  SvREADONLY_off(*fetched);
  sv_setiv(*fetched, (IV) ptr);
  if (make_readonly) SvREADONLY_on(*fetched);
  return fetched;
}

void *
self_fetch(SV *self, const char *slot) {
  HV *self_hash = (HV*) SvRV(self);
  SV **fetched = hv_fetch(self_hash, slot, strlen(slot), 0);
  if (fetched == NULL) croak("Couldn't fetch the %s slot in $self", slot);

  return (void *) SvIV(*fetched);
}

/* Extract the '_corpus' structure out of $self */
corpus *get_corpus (SV *self) {
  return (corpus *) self_fetch(self, "_corpus");
}

/* Convert a SV* containing an arrayref into an AV* */
AV *unpack_aref(SV *input_rv, char *name) {
  if ( !SvROK(input_rv) || SvTYPE(SvRV(input_rv)) != SVt_PVAV ) {
    croak("Argument '%s' must be array reference", name);
  }
  
  return (AV*) SvRV(input_rv);
}



( run in 1.163 second using v1.01-cache-2.11-cpan-d7f47b0818f )