33 #ifndef GENSVM_BLOCK_SIZE 34 #define GENSVM_BLOCK_SIZE 512 60 double h, omega = 0.0,
63 for (j=0; j<model->
K; j++) {
64 if (j == (data->
y[i]-1))
69 omega = (1.0/
p)*pow(omega, 1.0/
p - 1.0);
94 for (j=0; j<model->
K; j++) {
95 if (j == (data->
y[i]-1))
127 double *a,
double *b_aq)
132 const double a2g2 = 0.25*p*(2.0*p - 1.0)*pow((kappa+1.0)/2.0,p-2.0);
134 if (2.0 - model->
p < 1e-2) {
136 *b_aq = 0.5 - kappa/2.0 - q;
137 }
else if ( q <= 1.0) {
138 *b_aq = pow(1.0 - q, 3.0)/(2.0*pow(kappa + 1.0, 2.0));
144 if (q <= (p + kappa - 1.0)/(p - 2.0)) {
145 *a = 0.25*pow(p, 2.0)*pow(0.5 - kappa/2.0 - q, p - 2.0);
146 }
else if (q <= 1.0) {
149 *a = 0.25*pow(p, 2.0)*pow((p/(p - 2.0))*(0.5 -
150 kappa/2.0 - q), p - 2.0);
151 *b_aq = (*a)*(2.0*q + kappa - 1.0)/(p - 2.0) +
152 0.5*p*pow(p/(p - 2.0)*(0.5 - kappa/2.0 - q),
156 *b_aq = 0.5*p*pow(0.5 - kappa/2.0 - q, p - 1.0);
157 }
else if ( q <= 1.0) {
158 *b_aq = p*pow(1.0 - q, 2.0*p - 1.0)/pow(2*kappa+2.0, p);
184 double *a,
double *b_aq)
188 if (q <= - model->
kappa) {
189 *a = 0.25/(0.5 - model->
kappa/2.0 - q);
191 }
else if (q <= 1.0) {
192 *a = 1.0/(2.0*model->
kappa + 2.0);
193 *b_aq = (1.0 - q)*(*a);
195 *a = -0.25/(0.5 - model->
kappa/2.0 - q);
229 long i,
double *beta)
232 long j, K = model->
K;
233 double omega, a, b_aq = 0.0,
235 double *uu_row = NULL;
236 const double in = 1.0/((double) model->
n);
241 Memset(beta,
double, K-1);
242 for (j=0; j<K; j++) {
244 if (j == (data->
y[i]-1))
257 b_aq *= model->
rho[i] * omega * in;
258 uu_row = &model->
UU[((data->
y[i]-1)*K+j)*(K-1)];
259 cblas_daxpy(K-1, b_aq, uu_row, 1, beta, 1);
264 alpha *= omega * model->
rho[i] * in;
340 cblas_dsymm(CblasRowMajor, CblasLeft, CblasUpper, m+1, K-1, 1,
341 work->
ZAZ, m+1, model->
V, K-1, 1.0, work->
ZB, K-1);
346 for (i=m+2; i<=m*(m+2); i+=m+2)
351 for (i=0; i<m+1; i++)
352 for (j=0; j<K-1; j++)
353 work->
ZBc[j*(m+1)+i] = work->
ZB[i*(K-1)+j];
358 status =
dposv(
'L', m+1, K-1, work->
ZAZ, m+1, work->
ZBc, m+1);
364 err(
"[GenSVM Warning]: Received nonzero status from " 365 "dposv: %i\n", status);
366 int *IPIV =
Malloc(
int, m+1);
367 double *WORK =
Malloc(
double, 1);
368 status =
dsysv(
'L', m+1, K-1, work->
ZAZ, m+1, IPIV, work->
ZBc,
372 WORK =
Realloc(WORK,
double, LWORK);
373 status =
dsysv(
'L', m+1, K-1, work->
ZAZ, m+1, IPIV, work->
ZBc,
376 err(
"[GenSVM Warning]: Received nonzero " 377 "status from dsysv: %i\n", status);
386 for (i=0; i<m+1; i++)
387 for (j=0; j<K-1; j++)
388 work->
ZB[i*(K-1)+j] = work->
ZBc[j*(m+1)+i];
391 for (i=0; i<m+1; i++) {
392 for (j=0; j<K-1; j++) {
422 double alpha, sqalpha;
429 for (i=0; i<n; i++) {
437 sqalpha = sqrt(alpha);
438 work->
LZ[i*(m+1)] = sqalpha;
439 cblas_daxpy(m, sqalpha, &data->
Z[i*(m+1)+1], 1,
440 &work->
LZ[i*(m+1)+1], 1);
445 cblas_dger(CblasRowMajor, m+1, K-1, 1, &data->
Z[i*(m+1)], 1,
446 work->
beta, 1, work->
ZB, K-1);
451 cblas_dsyrk(CblasRowMajor, CblasUpper, CblasTrans, m+1, n, 1.0,
452 work->
LZ, m+1, 0.0, work->
ZAZ, m+1);
486 long b, i, j, k, K, jj, kk, jj_start, jj_end, blk_start, blk_end,
487 rem_size, n_blocks, n_row = data->
spZ->
n_row,
489 double temp, alpha, z_ij, *vals = NULL;
503 for (b=0; b<=n_blocks; b++) {
506 blk_end += (b == n_blocks) ? rem_size : GENSVM_BLOCK_SIZE;
509 for (i=blk_start; i<blk_end; i++) {
515 for (jj=jj_start; jj<jj_end; jj++) {
518 cblas_daxpy(K-1, z_ij, work->
beta, 1,
519 &work->
ZB[j*(K-1)], 1);
521 for (kk=jj; kk<jj_end; kk++) {
530 for (j=0; j<n_col; j++) {
531 for (k=j; k<n_col; k++) {
592 int dposv(
char UPLO,
int N,
int NRHS,
double *A,
int LDA,
double *B,
595 extern void dposv_(
char *UPLO,
int *Np,
int *NRHSp,
double *A,
596 int *LDAp,
double *B,
int *LDBp,
int *INFOp);
598 dposv_(&UPLO, &N, &NRHS, A, &LDA, B, &LDB, &INFO);
637 int dsysv(
char UPLO,
int N,
int NRHS,
double *A,
int LDA,
int *IPIV,
638 double *B,
int LDB,
double *WORK,
int LWORK)
640 extern void dsysv_(
char *UPLO,
int *Np,
int *NRHSp,
double *A,
641 int *LDAp,
int *IPIV,
double *B,
int *LDBp,
642 double *WORK,
int *LWORK,
int *INFOp);
644 dsysv_(&UPLO, &N, &NRHS, A, &LDA, IPIV, B, &LDB, WORK, &LWORK, &INFO);
double * H
Huber weighted error matrix.
double * LZ
n x (m+1) working matrix for the Z'*A*Z calculation
long * ja
column indices, should be of length nnz
long n_col
number of columns of the original matrix
void err(const char *fmt,...)
Parse a formatted string and write it to standard error.
int dposv(char UPLO, int N, int NRHS, double *A, int LDA, double *B, int LDB)
Solve AX = B where A is symmetric positive definite.
double p
parameter for the L-p norm in the loss function
double * UU
simplex difference matrix
void gensvm_calculate_ab_simple(struct GenModel *model, long i, long j, double *a, double *b_aq)
Compute majorization coefficients for simple instances.
bool gensvm_majorize_is_simple(struct GenModel *model, struct GenData *data, long i)
Check if we can do simple majorization for a given instance.
#define Memset(var, type, size)
#define matrix_get(M, cols, i, j)
void gensvm_get_update(struct GenModel *model, struct GenData *data, struct GenWork *work)
Perform a single step of the majorization algorithm to update V.
A structure to hold the GenSVM workspace.
double * ZBc
(K-1) x (m+1) working matrix for the Z'*B calculation
void gensvm_calculate_ab_non_simple(struct GenModel *model, long i, long j, double *a, double *b_aq)
Compute majorization coefficients for non-simple instance.
#define Malloc(type, size)
double * V
augmented weight matrix
#define matrix_add(M, cols, i, j, val)
double * ZAZ
(m+1) x (m+1) working matrix for the Z'*A*Z calculation
long * y
array of class labels, 1..K
A structure to represent the data.
double * values
actual nonzero values, should be of length nnz
void gensvm_get_ZAZ_ZB(struct GenModel *model, struct GenData *data, struct GenWork *work)
Wrapper around calculation of Z'*A*Z and Z'*B for sparse and dense.
A structure to represent a single GenSVM model.
void gensvm_reset_work(struct GenWork *work)
Reset all matrices of a GenWork instance.
double * ZB
(m+1) x (K-1) working matrix for the Z'*B calculation
void gensvm_get_ZAZ_ZB_sparse(struct GenModel *model, struct GenData *data, struct GenWork *work)
Calculate Z'*A*Z and Z'*B for sparse matrices.
#define Realloc(var, type, size)
double * tmpZAZ
(m+1) x (m+1) temporary working matrix for the Z'*A*Z calculation
long n
number of instances in the dataset
Header file for gensvm_update.c.
int dsysv(char UPLO, int N, int NRHS, double *A, int LDA, int *IPIV, double *B, int LDB, double *WORK, int LWORK)
Solve a system of equations AX = B where A is symmetric.
double * rho
vector of instance weights
double gensvm_calculate_omega(struct GenModel *model, struct GenData *data, long i)
Calculate the value of omega for a single instance.
double gensvm_get_alpha_beta(struct GenModel *model, struct GenData *data, long i, double *beta)
Compute the alpha_i and beta_i for an instance.
double kappa
parameter for the Huber hinge function
long K
number of classes in the dataset
void gensvm_get_ZAZ_ZB_dense(struct GenModel *model, struct GenData *data, struct GenWork *work)
Calculate Z'*A*Z and Z'*B for dense matrices.
double kappa
kappa parameter for the GenModel
#define matrix_set(M, cols, i, j, val)
#define GENSVM_BLOCK_SIZE
long m
number of predictor variables in the dataset
long * ia
cumulative row lengths, should be of length n_row+1
struct GenSparse * spZ
sparse representation of the augmented data matrix
double * beta
K-1 working vector for a row of the B matrix.
double p
p parameter for the GenModel
double lambda
regularization parameter in the loss function
long n_row
number of rows of the original matrix