@Override
    final public void computeGradient() {
        //
        final int last = this.frameidx;
        //
        // from last to first layer.
        //
        for (int l = this.structure.layers.length - 1; l >= 0; l--) {
            //
            if (l == this.structure.inputlayer) continue;
            final Layer layer = this.structure.layers[l];
            //
            // regular or reversed layer? 
            //
            if (layer.tag == LayerTag.REGULAR) {
                this.setFrameIdx(last);
                for (int t = last; t >= 0; t--) {
                    //
                    if (t < last) {
                        this.copyGradOutput(
                            this.frameidx + 1, this.frameidx, l
                        );
                    }
                    this.computeLayerGradients(l);
                    //
                    this.decrFrameIdx();
                }
            } else {
                this.setFrameIdx(0);
                for (int t = 0; t <= last; t++) {
                    //
                    if (t > 0) {
                        this.copyGradOutput(
                            this.frameidx - 1, this.frameidx, l
                        );
                    }
                    this.computeLayerGradients(l);
                    //
                    this.incrFrameIdx();
                    
                }

            }
        }
        //
        this.setFrameIdx(last);
    }