]> git.donarmstrong.com Git - lilypond.git/commitdiff
lilypond-0.0.1
authorfred <fred>
Sat, 5 Oct 1996 15:49:40 +0000 (15:49 +0000)
committerfred <fred>
Sat, 5 Oct 1996 15:49:40 +0000 (15:49 +0000)
parser.y [new file with mode: 0644]
qlpsolve.cc [new file with mode: 0644]
rhythmstaf.cc [new file with mode: 0644]

diff --git a/parser.y b/parser.y
new file mode 100644 (file)
index 0000000..23987a2
--- /dev/null
+++ b/parser.y
@@ -0,0 +1,121 @@
+%{ // -*-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();
+}
diff --git a/qlpsolve.cc b/qlpsolve.cc
new file mode 100644 (file)
index 0000000..0884223
--- /dev/null
@@ -0,0 +1,230 @@
+#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
+    */
diff --git a/rhythmstaf.cc b/rhythmstaf.cc
new file mode 100644 (file)
index 0000000..61eca84
--- /dev/null
@@ -0,0 +1,150 @@
+#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;
+}