public void calculateWeight(CPDataInstance feature,
                                       double gradient,
                                       CPWeights threadWeights) {


        //determine method for updating non-sparse data
        switch (TYPE) {
            case RANDOM: randomizeNonSparseUpdate(gradient, feature);
                         break;
            case LOCK: lockNonSparseUpdate(gradient, feature);
                        break;
            case SINGLE_THREAD:
                        oneThreadUpdate(gradient, feature);
                        break;
            case REPLICATE:
                        replicateUpdate(gradient, feature, threadWeights);
                        break;
            default:    normalNonSparseUpdate(gradient, feature, null);
                        break;
        }


        //update tokens, sparse data
        int[] tokens = feature.tokens;
        for (int token : tokens) {
            double tokenWeight = weights.wTokens[token];
            weights.wTokens[token] =tokenWeight * (1 - lambda * step) + (step * gradient);
        }
    }