void lstm_model_b()

in src/cpp/modules/tapenade/lstm/lstm_b.c [114:192]


void lstm_model_b(int hsize, const double *weight, double *weightb, const 
        double *bias, double *biasb, double *hidden, double *hiddenb, double *
        cell, double *cellb, const double *input, double *inputb) {
    double *gates;
    double *gatesb;
    double arg1;
    double arg1b;
    int ii1;
    double temp;
    double tempb;
    gatesb = (double *)malloc(4*hsize*sizeof(double));
    for (ii1 = 0; ii1 < 4*hsize; ++ii1)
        gatesb[ii1] = 0.0;
    gates = (double *)malloc(4*hsize*sizeof(double));
    double *forget = &(gates[0]);
    double *forgetb = &(gatesb[0]);
    double *ingate = &(gates[hsize]);
    double *ingateb = &(gatesb[hsize]);
    double *outgate = &(gates[2*hsize]);
    double *outgateb = &(gatesb[2*hsize]);
    double *change = &(gates[3*hsize]);
    double *changeb = &(gatesb[3*hsize]);
    int i;
    for (i = 0; i < hsize; ++i) {
        arg1 = input[i]*weight[i] + bias[i];
        forget[i] = sigmoid_nodiff(arg1);
        arg1 = hidden[i]*weight[hsize+i] + bias[hsize + i];
        ingate[i] = sigmoid_nodiff(arg1);
        arg1 = input[i]*weight[2*hsize+i] + bias[2*hsize + i];
        outgate[i] = sigmoid_nodiff(arg1);
        change[i] = tanh(hidden[i]*weight[3*hsize+i] + bias[3*hsize + i]);
    }
    for (i = 0; i < hsize; ++i) {
        pushReal8(cell[i]);
        cell[i] = cell[i]*forget[i] + ingate[i]*change[i];
    }
    for (i = hsize-1; i > -1; --i) {
        outgateb[i] = outgateb[i] + tanh(cell[i])*hiddenb[i];
        cellb[i] = cellb[i] + outgate[i]*(1.0-tanh(cell[i])*tanh(cell[i]))*
            hiddenb[i];
        hiddenb[i] = 0.0;
    }
    for (i = hsize-1; i > -1; --i) {
        popReal8(&(cell[i]));
        forgetb[i] = forgetb[i] + cell[i]*cellb[i];
        ingateb[i] = ingateb[i] + change[i]*cellb[i];
        changeb[i] = changeb[i] + ingate[i]*cellb[i];
        cellb[i] = forget[i]*cellb[i];
    }
    for (i = hsize-1; i > -1; --i) {
        temp = weight[3*hsize + i];
        tempb = (1.0-tanh(hidden[i]*temp+bias[3*hsize+i])*tanh(hidden[i]*temp+
            bias[3*hsize+i]))*changeb[i];
        hiddenb[i] = hiddenb[i] + temp*tempb;
        weightb[3*hsize + i] = weightb[3*hsize + i] + hidden[i]*tempb;
        biasb[3*hsize + i] = biasb[3*hsize + i] + tempb;
        changeb[i] = 0.0;
        arg1 = input[i]*weight[2*hsize+i] + bias[2*hsize + i];
        sigmoid_b(arg1, &arg1b, outgateb[i]);
        outgateb[i] = 0.0;
        inputb[i] = inputb[i] + weight[2*hsize+i]*arg1b;
        weightb[2*hsize + i] = weightb[2*hsize + i] + input[i]*arg1b;
        biasb[2*hsize + i] = biasb[2*hsize + i] + arg1b;
        arg1 = hidden[i]*weight[hsize+i] + bias[hsize + i];
        sigmoid_b(arg1, &arg1b, ingateb[i]);
        ingateb[i] = 0.0;
        hiddenb[i] = hiddenb[i] + weight[hsize+i]*arg1b;
        weightb[hsize + i] = weightb[hsize + i] + hidden[i]*arg1b;
        biasb[hsize + i] = biasb[hsize + i] + arg1b;
        arg1 = input[i]*weight[i] + bias[i];
        sigmoid_b(arg1, &arg1b, forgetb[i]);
        forgetb[i] = 0.0;
        inputb[i] = inputb[i] + weight[i]*arg1b;
        weightb[i] = weightb[i] + input[i]*arg1b;
        biasb[i] = biasb[i] + arg1b;
    }
    free(gates);
    free(gatesb);
}