} if (key < 0) { key = -key;
  private double kernel(int id1, int id2, Instance inst1) throws Exception {    double result = 0;    int key = -1, location = -1;    // we can only cache if we know the indexes    if (id1 >= 0) {      if (id1 > id2) {	key = id1 * m_alpha.length + id2;      } else {	key = id2 * m_alpha.length + id1;      }      location = key % m_keys.length;      if (m_keys[location] == (key + 1)) {	return m_storage[location];      }    }	    // we can do a fast dot product    Instance inst2 = m_data.instance(id2);    int n1 = inst1.numValues(); int n2 = inst2.numValues();    int classIndex = m_data.classIndex();    for (int p1 = 0, p2 = 0; p1 < n1 && p2 < n2;) {      int ind1 = inst1.index(p1);       int ind2 = inst2.index(p2);      if (ind1 == ind2) {	if (ind1 != classIndex) {	  result += inst1.valueSparse(p1) * inst2.valueSparse(p2);	}	p1++; p2++;      } else if (ind1 > ind2) {	p2++;      } else { 	p1++;      }    }        // Use lower order terms?    if (m_lowerOrder) {      result += 1.0;    }    // Rescale kernel?    if (m_rescale) {      result /= (double)m_data.numAttributes() - 1;    }              if (m_exponent != 1.0) {      result = Math.pow(result, m_exponent);    }    m_kernelEvals++;        // store result in cache 	    if (key != -1){      m_storage[location] = result;      m_keys[location] = (key + 1);    }    return result;  }