// Algebraic system
if (a[0] == b[0]) {
connect(input, output);
} else {
Scale scaleD = new Scale(this, "ScaleD");
scaleD.factor.setToken(new DoubleToken(b[0] / a[0]));
connect(input, scaleD.input);
connect(output, scaleD.output);
}
} else {
double d = b[0] / a[0];
int order = n - 1;
AddSubtract inputAdder = new AddSubtract(this, "InputAdder");
AddSubtract outputAdder = new AddSubtract(this, "OutputAdder");
Integrator[] integrators = new Integrator[order];
IORelation[] nodes = new IORelation[order];
Scale[] feedback = new Scale[order];
Scale[] feedforward = new Scale[order];
for (int i = 0; i < order; i++) {
// The integrator names are d0x, d1x, etc.
integrators[i] = new Integrator(this, "Integrator" + i);
feedback[i] = new Scale(this, "Feedback" + i);
feedback[i].factor.setToken(new DoubleToken(-a[i + 1]
/ a[0]));
feedforward[i] = new Scale(this, "Feedforward" + i);
feedforward[i].factor.setToken(new DoubleToken(
(b[i + 1] - (d * a[i + 1])) / a[0]));
// connections
nodes[i] = (IORelation) connect(integrators[i].output,
feedforward[i].input, "node" + i);
feedback[i].input.link(nodes[i]);
connect(feedback[i].output, inputAdder.plus);
connect(feedforward[i].output, outputAdder.plus);
if (i >= 1) {
integrators[i].input.link(nodes[i - 1]);
}
}
connect(inputAdder.output, integrators[0].input);
IORelation inputRelation = (IORelation) connect(input,
inputAdder.plus, "inputRelation");
connect(output, outputAdder.output, "outputRelation");
if (d != 0) {
Scale scaleD = new Scale(this, "ScaleD");
scaleD.factor.setToken(new DoubleToken(d));
scaleD.input.link(inputRelation);
connect(scaleD.output, outputAdder.plus);
}
}