--- /dev/null
+%{ // -*-Fundamental-*-
+#include <iostream.h>
+//#include "mudobs.hh"
+#include "lexer.hh"
+#include "staff.hh"
+#include "score.hh"
+#include "keyword.hh"
+#include "globvars.hh"
+#include "debug.hh"
+#include "parseconstruct.hh"
+#define YYDEBUG 1
+
+
+%}
+
+
+%union {
+ int i;
+ Real real;
+ Command *command;
+ Identifier *id;
+
+ Voice *voice;
+ Voice_element *el;
+ Staff *staff;
+ String *string;
+ Score *score;
+}
+
+%token VOICE STAFF SCORE TITLE RHYTHMSTAFF BAR NOTENAME
+
+%token <id> IDENTIFIER
+%token <string> PITCH DURATION RESTNAME
+%token <real> REAL
+
+
+%type <voice> voice_block voice_body voice_elts voice_elts_dollar
+%type <el> voice_elt
+%type <command> score_command
+%type <score> score_block score_body
+%type <staff> staff_block rhythmstaff_block rhythmstaff_body
+
+%%
+
+mudela:
+ score_block {
+ delete the_score;
+ the_score = $1;
+ }
+ ;
+
+
+score_block: SCORE '{' score_body '}' { $$ = $3; }
+ ;
+
+score_body: { $$ = new Score; }
+ | score_body staff_block { $$->add($2); }
+ | score_body score_command { $$->add($2); }
+ ;
+
+staff_block:
+ rhythmstaff_block
+ ;
+
+rhythmstaff_block:
+ RHYTHMSTAFF '{' rhythmstaff_body '}' { $$ = $3; }
+ ;
+
+rhythmstaff_body:
+ /* empty */ { $$ = get_new_rhythmstaff(); }
+ | rhythmstaff_body voice_block { $$->add_voice($2); }
+ ;
+
+voice_block:
+ VOICE '{' voice_body '}' { $$ = $3; }
+ ;
+
+
+voice_body:
+ REAL voice_elts_dollar { $$ = $2; $$->start = $1; }
+ | voice_elts_dollar { $$ = $1; }
+ ;
+
+voice_elts_dollar:
+ '$' voice_elts '$' { $$ = $2; }
+ ;
+
+voice_elts:
+ /* empty */ {
+ $$ = new Voice;
+ }
+ | voice_elts voice_elt {
+ $$->add($2);
+ }
+ ;
+
+voice_elt:
+ PITCH DURATION { $$ = get_note_element(*$1, *$2);
+
+ }
+ | RESTNAME DURATION { $$ = get_rest_element(*$1, *$2);
+
+ }
+ ;
+
+score_command:
+ BAR REAL {
+ $$ = get_bar_command($2);
+ }
+ ;
+
+%%
+
+void
+parse_file(String s)
+{
+ *mlog << "Parsing ... ";
+ yydebug = debug_flags & DEBUGPARSER;
+ new_input(s);
+ yyparse();
+}
--- /dev/null
+#include "qlpsolve.hh"
+#include "debug.hh"
+#include "choleski.hh"
+
+const Real TOL=1e-2; // roughly 1/10 mm
+
+String
+Active_constraints::status() const
+{
+ String s("Active|Inactive [");
+ for (int i=0; i< active.sz(); i++) {
+ s += String(active[i]) + " ";
+ }
+
+ s+="|";
+ for (int i=0; i< inactive.sz(); i++) {
+ s += String(inactive[i]) + " ";
+ }
+ s+="]";
+
+ return s;
+}
+
+void
+Active_constraints::OK() {
+ H.OK();
+ A.OK();
+ assert(active.sz() +inactive.sz() == opt->cons.sz());
+ assert(H.dim() == opt->dim());
+ assert(active.sz() == A.rows());
+ svec<int> allcons;
+
+ for (int i=0; i < opt->cons.sz(); i++)
+ allcons.add(0);
+ for (int i=0; i < active.sz(); i++) {
+ int j = active[i];
+ allcons[j]++;
+ }
+ for (int i=0; i < inactive.sz(); i++) {
+ int j = inactive[i];
+ allcons[j]++;
+ }
+ for (int i=0; i < allcons.sz(); i++)
+ assert(allcons[i] == 1);
+}
+
+Vector
+Active_constraints::get_lagrange(Vector gradient)
+{
+ Vector l(A*gradient);
+
+ return l;
+}
+
+void
+Active_constraints::add(int k)
+{
+ // add indices
+ int cidx=inactive[k];
+ active.add(cidx);
+
+ inactive.swap(k,inactive.sz()-1);
+ inactive.pop();
+
+ Vector a( opt->cons[cidx] );
+ // update of matrices
+ Vector Ha = H*a;
+ Real aHa = a*Ha;
+
+ H -= Matrix(Ha , Ha)/(aHa);
+
+ Vector addrow(Ha/(aHa));
+ A -= Matrix(A*a, addrow);
+ A.insert_row(addrow,A.rows());
+}
+
+void
+Active_constraints::drop(int k)
+{
+ int q=active.sz()-1;
+
+ // drop indices
+ inactive.add(active[k]);
+ active.swap(k,q);
+ A.swap_rows(k,q);
+ active.pop();
+
+ Vector a(A.row(q));
+ H += Matrix(a,a)/(a*opt->quad*a);
+ A -= A*opt->quad*Matrix(a,a)/(a*opt->quad*a);
+
+ Vector rem_row(A.row(q));
+ assert(rem_row.norm() < EPS);
+ A.delete_row(q);
+}
+
+
+Active_constraints::Active_constraints(Ineq_constrained_qp const *op)
+ : A(0,op->dim()),
+ H(op->dim()),
+ opt(op)
+{
+ for (int i=0; i < op->cons.sz(); i++)
+ inactive.add(i);
+ Choleski_decomposition chol(op->quad);
+ H=chol.inverse();
+}
+
+/* Find the optimum which is in the planes generated by the active
+ constraints.
+ */
+Vector
+Active_constraints::find_active_optimum(Vector g)
+{
+ return H*g;
+}
+
+/****************************************************************/
+
+int
+min_elt_index(Vector v)
+{
+ Real m=INFTY; int idx=-1;
+ for (int i = 0; i < v.dim(); i++)
+ if (v(i) < m) {
+ idx = i;
+ m = v(i);
+ }
+ return idx;
+}
+
+///the numerical solving
+Vector
+Ineq_constrained_qp::solve(Vector start) const
+{
+ Active_constraints act(this);
+
+
+ act.OK();
+
+
+ Vector x(start);
+ Vector gradient=quad*x+lin;
+
+
+ Vector last_gradient(gradient);
+ int iterations=0;
+
+ while (iterations++ < MAXITER) {
+ Vector direction= - act.find_active_optimum(gradient);
+
+ // mtor << "gradient "<< gradient<< "\ndirection " << direction<<"\n";
+
+ if (direction.norm() > EPS) {
+ // mtor << act.status() << '\n';
+
+ Real minalf = INFTY;
+
+ Inactive_iter minidx(act);
+
+
+ /*
+ we know the optimum on this "hyperplane". Check if we
+ bump into the edges of the simplex
+ */
+
+ for (Inactive_iter ia(act); ia.ok(); ia++) {
+
+ if (ia.vec() * direction >= 0)
+ continue;
+ Real alfa= - (ia.vec()*x - ia.rhs())/
+ (ia.vec()*direction);
+
+ if (minalf > alfa) {
+ minidx = ia;
+ minalf = alfa;
+ }
+ }
+ Real unbounded_alfa = 1.0;
+ Real optimal_step = MIN(minalf, unbounded_alfa);
+
+ Vector deltax=direction * optimal_step;
+ x += deltax;
+ gradient += optimal_step * (quad * deltax);
+
+ //mtor << "step = " << optimal_step<< " (|dx| = " <<
+ //deltax.norm() << ")\n";
+
+ if (minalf < unbounded_alfa) {
+ /* bumped into an edge. try again, in smaller space. */
+ act.add(minidx.idx());
+ continue;
+ }
+ /*ASSERT: we are at optimal solution for this "plane"*/
+
+
+ }
+
+ Vector lagrange_mult=act.get_lagrange(gradient);
+ int m= min_elt_index(lagrange_mult);
+
+ if (m>=0 && lagrange_mult(m) > 0) {
+ break; // optimal sol.
+ } else if (m<0 && gradient.norm() < EPS) {
+ break;
+ }
+
+ mtor << "dropping cons " << m<<'\n';
+ act.drop(m);
+ }
+ if (iterations >= MAXITER)
+ WARN<<"didn't converge!\n";
+
+ // mtor << ": found " << x<<" in " << iterations <<" iterations\n";
+ assert_solution(x);
+ return x;
+}
+
+/** Mordecai Avriel, Nonlinear Programming: analysis and methods (1976)
+ Prentice Hall.
+
+ Section 13.3
+
+ This is a "projected gradient" algorithm. Starting
+ from a point x the next point is found in a direction determined by
+ projecting the gradient onto the active constraints. */
+
+/*
+ thoroughly hacked to barely living tiny pieces by HW
+ */
--- /dev/null
+#include "request.hh"
+#include "debug.hh"
+#include "linestaff.hh"
+#include "staff.hh"
+#include "pstaff.hh"
+#include "pscore.hh"
+#include "command.hh"
+#include "molecule.hh"
+#include "rhythmstaf.hh"
+
+
+
+Rhythmic_column::Rhythmic_column(Score_column*s, Rhythmic_staff *rs)
+ : Staff_column(s)
+{
+ the_note = 0;
+ staff_ = rs;
+}
+
+
+void
+Rhythmic_staff::set_output(PScore* ps )
+{
+ theline = new Linestaff(1);
+ pscore_ = ps;
+ pscore_->add(theline);
+}
+
+// should integrate handling of BREAK commands into Staff_column
+void
+Rhythmic_column::process_commands( )
+{
+ int breakstat = BREAK_END;
+ for (int i = 0 ; i < s_commands.sz(); i++) {
+ Command *com = s_commands[i];
+ switch (com->code){
+ case INTERPRET:
+ break;
+ case BREAK_PRE:
+ case BREAK_MIDDLE:
+ case BREAK_POST:
+ case BREAK_END:
+ score_column->set_breakable();
+ breakstat = com->code;
+ break;
+
+ case TYPESET:
+ typeset_command ( com , breakstat);
+ break;
+ default :
+ break;
+ }
+
+ }
+}
+/**
+ accept:
+
+ BREAK: all
+ TYPESET: bar, meter
+
+ */
+
+
+
+void
+Rhythmic_column::process_requests()
+{
+ for (int i = 0 ; i < v_elts.sz(); i ++)
+ for (PCursor<Request *> rqc(v_elts[i]->reqs); rqc.ok(); rqc++) {
+ Request *rq= rqc;
+ switch(rq->tag){
+ case Request::NOTE:
+ case Request::REST:
+ if (the_note){
+ WARN << "too many notes.\n";
+ return;
+ }
+ the_note = rq;
+ break;
+
+ default:
+ return;
+ }
+ }
+
+}
+
+
+void
+Rhythmic_column::typeset_command(Command *com, int breakst)
+{
+ Item *i = new Item;
+ const Symbol*s=0;
+
+ if (com -> args[0] == "|" ) {
+ s = Symbol::find_bar("|");
+ } else
+ assert(false);
+
+ i->output=new Molecule(Atom(s));
+ staff_->pscore_->typeset_item(i, score_column->pcol,
+ staff_->theline,breakst);
+}
+
+void
+Rhythmic_column::typeset_req(Request *rq)
+{
+ Item *i = new Item;
+ const Symbol*s=0;
+
+ switch(rq->tag){
+ case Request::NOTE:
+ s = Symbol::find_ball(rq->note()->balltype);
+ break;
+ case Request::REST:
+ s = Symbol::find_rest(rq->rest()->balltype);
+ break;
+ default:
+ assert(false);
+ break;
+ }
+ i->output = new Molecule(Atom(s));
+
+ staff_->pscore_->typeset_item(i, score_column->pcol, staff_->theline,0 );
+}
+
+void
+Rhythmic_staff::grant_requests()
+{
+ for (PCursor<Staff_column*> cc(cols); cc.ok(); cc++) {
+ Rhythmic_column *rp = (Rhythmic_column*)*cc;
+ if (rp->the_note)
+ rp->typeset_req( rp->the_note);
+ }
+}
+
+Staff_column*
+Rhythmic_staff::create_col(Score_column*s)
+{
+ Rhythmic_column *rc = new Rhythmic_column(s,this);
+
+ return rc;
+}
+
+Staff *
+get_new_rhythmstaff()
+{
+ return new Rhythmic_staff;
+}