Example #1
0
void Gradient::apply_bwd (const ExprApply& a, ExprLabel** x, const ExprLabel& y) {

	Array<Domain> d(a.nb_args);
	Array<Domain> g(a.nb_args);
	int n=0;

	for (int i=0; i<a.nb_args; i++) {
		d.set_ref(i,*x[i]->d);
		g.set_ref(i,*x[i]->g);
		n+=x[i]->d->dim.size();
	}

	// we unvectorize the components of the gradient.
	IntervalVector old_g(n);
	load(old_g, g);
	IntervalVector tmp_g(n);

	if (a.func.expr().dim.is_scalar()) {
		gradient(a.func,d,tmp_g);
		//cout << "tmp-g=" << tmp_g << endl;
		tmp_g *= y.g->i();   // pre-multiplication by y.g
		tmp_g += old_g;      // addition to the old value of g
		load(g,tmp_g);
	} else {
		assert(a.func.expr().dim.is_vector()); // matrix-valued function not implemented...
		int m=a.func.expr().dim.vec_size();
		IntervalMatrix J(m,n);
		jacobian(a.func,d,J);
		tmp_g = y.g->v()*J; // pre-multiplication by y.g
		tmp_g += old_g;
		load(g,tmp_g);
	}
}
Example #2
0
void Gradient::apply_bwd(int* x, int y) {

	const ExprApply& a = (const ExprApply&) f.node(y);

	Array<Domain> d2(a.func.nb_arg());
	Array<Domain> g2(a.nb_args);

	int n=0;

	for (int i=0; i<a.func.nb_arg(); i++) {
		d2.set_ref(i,d[x[i]]);
		g2.set_ref(i,g[x[i]]);
		n+=d[x[i]].dim.size();
	}

	// we unvectorize the components of the gradient.
	IntervalVector old_g(n);
	load(old_g, g2);
	IntervalVector tmp_g(n);

	if (a.func.expr().dim.is_scalar()) {
		a.func.deriv_calculator().gradient(d2,tmp_g);
		//cout << "tmp-g=" << tmp_g << endl;
		tmp_g *= g[y].i();   // pre-multiplication by y.g
		tmp_g += old_g;      // addition to the old value of g
		load(g2,tmp_g);
	} else {
		if (!a.func.expr().dim.is_vector())
			not_implemented("automatic differentiation of matrix-valued function");
		int m=a.func.expr().dim.vec_size();
		IntervalMatrix J(m,n);
		a.func.deriv_calculator().jacobian(d2,J);
		tmp_g = g[y].v()*J; // pre-multiplication by y.g
		tmp_g += old_g;
		load(g2,tmp_g);
	}
}