%mathpiper

LoadScriptOnce("proposed.rep/equations.mpi");

//Retract("SolveLinearSysViaMatrix",*);

//Retract("SolveLinearSystemViaGauss",*);

//Retract("CheckEquationSolution",*);



10 # SolveLinearSysViaMatrix( eqns_IsList, vars_IsList ) <--
[
    /*** NOTE: This function appears to be fully functional, and     */
    /***       gives correct answers, but                            */
    /***       needs some more work to get answers into desired form */ 

    Local(LE,LV,E,LHS,X,M,RHS,LL,eqn,row,ans,Det);
    If(InVerboseMode(),Tell(SolveLinearSysViaMatrix,{eqns,vars}));
    LE := Length(eqns);
    LV := Length(vars);
    E  := Assert() LE=LV;
    Check(E, "Argument", "Number of equations != Number of variables");
    
    LHS := {};
    RHS := {};
    X   := vars;
    M   := FillList(1,LE);
    ForEach(eqn,eqns) 
    [
        E   := FunctionToList(eqn);
        LL  := E[2];
        RHS := E[3]:RHS;
        row := Map("Coef",{FillList(LL,LE),X,M});
        LHS := row:LHS;   
    ];
    LHS := DestructiveReverse(LHS);
    RHS := DestructiveReverse(RHS);
    Det := Determinant(LHS);
    //Tell(det,Det);
    
    ans :=MatrixSolve(LHS,RHS);
];

12 # SolveLinearSysViaMatrix( _eqns, _vars ) <-- False;




10 # SolveLinearSystemViaGauss( eqns_IsList, vars_IsList ) <--
[
    /***** WARNING: This version is valid for TWO equations only *****/

    Local(LE,LV,E,E2,s,s1,s2,s3,ans);
    If(InVerboseMode(),Tell(SolveLinearSysViaGauss,{eqns,vars}));
    LE := Length(eqns);
    LV := Length(vars);
    E  := Assert() LE=LV;
    Check(E, "Argument", "Number of equations != Number of variables");
    
    If(InVerboseMode(),Tell(0,{LE,LV,E}));
    s  := Solve( eqns, vars )[1];
    If(InVerboseMode(),Tell(1,s));
    s1 := s[1];
    s2 := s[2];
    s3 := s[3];
    E2 := FunctionToList(s3);
    s2 := (s2 Where s3);
    s1 := (s1 Where s2 And s3);
    If( E2[2]=E2[3], ans:=Inconsistent-Set, ans:=List(s1,s2,s3));
    ans;
];

12 # SolveLinearSystemViaGauss( _eqns, _vars ) <-- False;




10 # CheckEquationSolution( eqn_IsEquation, soln_IsList ) <--
[
    Local(EL,LHS,RHS,L,svar,sval);
    If(InVerboseMode(),Tell(CheckOneEq,{eqn,soln}));
    EL   := FunctionToList(eqn);
    LHS  := Expand(Simplify( EL[2] ));
    RHS  := Expand(Simplify( EL[3] ));
    L    := FunctionToList(soln[1]);
    svar := L[2];
    sval := L[3];
    If( InVerboseMode(), [Tell(2,{LHS,RHS}); Tell(3,{svar,sval});]);
    V    := Eliminate(svar,sval,LHS);
    If(InVerboseMode(),Tell(4,V));
    V = RHS;
];

12 # CheckEquationSolution( eqns_IsList, solns_IsList ) <--
[
    Tell(CheckSetOfEqns,{eqns,solns});
    Check(False, "Unimplemented", "Not implemented yet");
];

14 # CheckEquationSolution( _eq, _soln ) <-- 
[
    Tell(CheckEqnLeftovers,{eq,soln});
    False;
];


%/mathpiper

    %output,preserve="false"
      Result: True
.   %/output




///////////////////////////////////////////////////////////////////////////////

%mathpiper,scope="nobuild",subtype="manual_test"

Unbind(eqns1,eqns2,eqns3,eqns4,eqns5,solution);

// --- Test the new solver for sets of linear equations ---

NewLine();

eqns1 := {2*x-2*y+z==(-7),3*x+y+2*z==(-2),5*x+3*y-3*z==(-7)};  //  3 eqns, 3 unknowns
Tell(Independent,eqns1);
solution := SolveLinearSysViaMatrix(eqns1,{x,y,z});
Tell(11,solution);
NewLine();

eqns2 := {3*x-2*y+z==1,x-y-z==2,6*x-4*y+2*z==3};  // 3 eqns, 3 unks, inconsistent
Tell(Inconsistent,eqns2);
solution := SolveLinearSysViaMatrix(eqns2,{x,y,z});
Tell(13,solution);
NewLine();

eqns3 := {2*x+3*y==12,3*x+2*y==12};  // 2 eqns, 2 unknown, independent
Tell(Independent,eqns3);
solution := SolveLinearSysViaMatrix(eqns3,{x,y});
Tell(15,solution);
NewLine();

eqns4 := {2*x+3*y==6,4*x+6*y==12};  // 2 eqns, 2 unknowns, dependent
Tell(Dependent,eqns4);
solution := SolveLinearSysViaMatrix(eqns4,{x,y});
Tell(17,solution);
NewLine();

eqns5 := {2*x+3*y==6,2*x+3*y==8};  // 2 eqns, 2 unknowns, parallel (inconsistent)
Tell(Inconsistent,eqns5);
solution := SolveLinearSysViaMatrix(eqns5,{x,y});
Tell(19,solution);
NewLine();

%/mathpiper

    %output,preserve="false"
      Result: True
      
      Side effects:
      << Independent >> eqns1 {2*x-2*y+z==(-7),3*x+y+2*z==(-2),5*x+3*y-3*z==(-7)} 
      << det >> Det -52 
      << 11 >> solution {-2,2,1} 
      
      << Inconsistent >> eqns2 {3*x-2*y+z==1,x-y-z==2,6*x-4*y+2*z==3} 
      << det >> Det 0 
      << 13 >> solution {Undefined,Infinity,Infinity} 
      
      << Independent >> eqns3 {2*x+3*y==12,3*x+2*y==12} 
      << det >> Det -5 
      << 15 >> solution {12/5,12/5} 
      
      << Dependent >> eqns4 {2*x+3*y==6,4*x+6*y==12} 
      << det >> Det 0 
      << 17 >> solution {Undefined,Undefined} 
      
      << Inconsistent >> eqns5 {2*x+3*y==6,2*x+3*y==8} 
      << det >> Det 0 
      << 19 >> solution {Infinity,Infinity}
.   %/output



