int loss = 0;
int L = data.length;
// 稀疏矩阵表示(f(x,y)-f(x,\bar{y}))
TIntIntHashMap diffF = new TIntIntHashMap(); // 最多有2*L*numTemplets个不同
for (int o = -templets.maxOrder - 1, l = 0; l < L; o++, l++) {
tS = tS * numLabels % templets.numStates + target[l]; // 目标值:计算当前状态组合的y空间偏移
pS = pS * numLabels % templets.numStates + predict[l];// 预测值:计算当前状态组合的y空间偏移
if (predict[l] != target[l])
ne++;
if (o >= 0 && (predict[o] != target[o]))
ne--; // 减去移出clique的节点的label差异
if (ne > 0) { // 当前clique有不相同label
loss++; // L(y,ybar)
for (int t = 0; t < numTemplets; t++) {
if (data[l][t] == -1)
continue;
int tI = data[l][t] + templets.offset[t][tS]; // 特征索引:找到对应weights的维数
int pI = data[l][t] + templets.offset[t][pS]; // 特征索引:找到对应weights的维数
if (tI != pI) {
diffF.adjustOrPutValue(tI, 1, 1);
diffF.adjustOrPutValue(pI, -1, -1);
diffW += weights[tI] - weights[pI]; // w^T(f(x,y)-f(x,ybar))
}
}
}
}
float diff = 0;
TIntIntIterator it = diffF.iterator();
for (int i = diffF.size(); i-- > 0;) {
it.advance();
diff += it.value() * it.value();
}
it = null;
float alpha;
float delta;
if (useLoss) {
delta = loss;
} else
delta = 1;
if (diffW < delta) {
tS = 0;
pS = 0;
ne = 0;
alpha = (delta - diffW) / diff;
// System.out.println(alpha);
alpha = Math.min(c, alpha);
it = diffF.iterator();
for (int i = diffF.size(); i-- > 0;) {
it.advance();
weights[it.key()] += it.value() * alpha;
}
return loss;