void Matrix::lu(Matrix& L, Matrix& U) const { if (m_nrows != m_ncols) throw Error(" matrix is not square "); Matrix A = *this; Matrix Lf(m_nrows), dI(m_nrows), P(m_nrows); dI = dI + dI; for (size_t i = 0; i < m_nrows - 1; i++) { /* // check if pivot == 0 // if so, try to find a valid pivot // if no valid pivot found, matrix isn't invertible (quit) // update permutation matrix // */ Matrix Lt(m_nrows); for (size_t j = i + 1; j < m_nrows; j++) Lt(j, i) = -A(j, i) / A(i, i); A = Lt * A; Lf = Lf * (dI - Lt); } U = A; L = Lf; }
unsigned int Matrix::lup(Matrix& L, Matrix& U, Matrix& P) const { if (m_nrows != m_ncols) throw Error(" matrix is not square "); unsigned int permutations = 0; Matrix A = *this; Matrix Lf(m_nrows), dI(m_nrows), Per(m_nrows); dI = dI + dI; for (size_t i = 0; i < m_nrows - 1; i++) { if (Matrix::precision >= std::fabs(A(i, i))) { bool p = 0; for (size_t k = i + 1; k < m_nrows; k++) if (Matrix::precision >= std::fabs(A(k, i))) { A.swapRows(i, k); Per.swapRows(i, k); p = true; break; } if (!p) throw Error("matrix is not invertible"); else permutations++; } Matrix Lt(m_nrows); // gaussian matrix for (size_t j = i + 1; j < m_nrows; j++) Lt(j, i) = -A(j, i) / A(i, i); /* A = Lt * A; Lf = Lf * (dI - Lt); */ A = Lt.multiply(A); Lf = Lf.multiply((dI - Lt)); // dI-Lt is the inverse of Lt (gaussian matrix) } P = Per; U = A; L = Lf; return permutations; }
void Execute(void) { Instruction I; int temp, temp1, temp2,temp3, Addr; char tempc; /* Start here */ I = StartInstruction; while (OpCodeOf(I) != HALTOP) { if (TraceSpecified) TraceExecution(I); if (ValidOpCode(I)) { switch (OpCodeOf(I)) { case NOP : break; case LITOP : PushLf(Operand1Of(I)); break; case LLVOP : PushLf(Lf(Operand1Of(I))); break; case LGVOP : PushLf(Gf(Operand1Of(I))); break; case SLVOP : UpdateLf(Operand1Of(I),PopLf()); break; case SGVOP : UpdateGf(Operand1Of(I),PopLf()); break; case LLIVOP : PushLf(Gf(Lf(Operand1Of(I)))); break; case LGIVOP : PushLf(Gf(Gf(Operand1Of(I)))); break; case SLIVOP : UpdateGf(Lf(Operand1Of(I)),PopLf()); break; case SGIVOP : UpdateGf(Gf(Operand1Of(I)),PopLf()); break; case LLAOP : PushLf(LocalAddress(Operand1Of(I))); break; case LGAOP : PushLf(GlobalAddress(Operand1Of(I))); break; case LUVOP : Addr = LocalAddress(0); for (temp = 1; temp <= Operand1Of(I); temp++) { if (Addr == 0) { fprintf(output, "TOO MANY FRAMES SPECIFIED IN LUV\n"); FatalError(); } Addr = Gf(Addr); } PushLf(Gf(Addr + Operand2Of(I))); break; case SUVOP : Addr = LocalAddress(0); for (temp = 1; temp <= Operand1Of(I); temp++) { if (Addr == 0) { fprintf(output, "TOO MANY FRAMES SPECIFIED IN SUV\n"); FatalError(); } Addr = Gf(Addr); } UpdateGf (Addr+Operand2Of(I),PopLf()); break; case UOPOP : temp = PopLf(); switch (Operand1Of(I)) { case UNOT : PushLf(1 - temp); break; case UNEG : PushLf(- temp); break; case USUCC : PushLf(temp + 1); break; case UPRED : PushLf(temp - 1); break; } break; case BOPOP : temp2 = PopLf(); temp1 = PopLf(); if (ValidBinOp(I)) { switch (Operand1Of(I)) { case BAND : PushLf(temp1 * temp2); break; case BOR : if ((temp1+temp2) > 0) PushLf (1); else PushLf(0); break; case BPLUS : PushLf(temp1 + temp2); break; case BMINUS : PushLf(temp1 - temp2); break; case BMULT : PushLf(temp1 * temp2); break; case BDIV : if (temp2 == 0) { fprintf(output, "<<< MACHINE ERROR >>>: "); fprintf(output, "DIVISION BY ZERO.\n"); DumpMemory(output); FatalError(); } else PushLf(temp1 / temp2); break; case BEXP : if (temp2 < 0) { fprintf(output, "<<< MACHINE ERROR >>>: "); fprintf(output, "NEGATIVE EXPONENT. \n"); DumpMemory(output); FatalError(); } else { temp = 1; for (temp3=1; temp3<=temp2; temp3++) temp = temp * temp1; PushLf(temp); } break; case BMOD : PushLf(temp1 % temp2); break; case BEQ : if (temp1 == temp2) PushLf(1); else PushLf(0); break; case BNE : if (temp1 != temp2) PushLf(1); else PushLf(0); break; case BLE : if (temp1 <= temp2) PushLf(1); else PushLf (0); break; case BGE : if (temp1 >= temp2) PushLf (1); else PushLf (0); break; case BLT : if (temp1 < temp2) PushLf(1); else PushLf(0); break; case BGT : if (temp1 > temp2) PushLf(1); else PushLf(0); break; } /* switch(Operand1Of(I)) */ } else { fprintf(output,"<<< MACHINE ERROR >>>: "); fprintf(output,"UNKNOWN OPERAND NAME: "); fprintf(TraceFile," %d ",Operand1Of(I)); fprintf(output,"\n"); DumpMemory(output); FatalError(); } break; case POPOP : PopOffLf(Operand1Of(I)); break; case DUPOP : PushLf(TopLf()); break; case SWAPOP : temp1 = PopLf(); temp2 = PopLf(); PushLf(temp1); PushLf(temp2); break; case CALLOP : PushReturnStack(I); OpenFrame(Operand1Of(I)); I = PopLf() - 1; break; case RTNOP : temp = DepthLf() - Operand1Of(I); if (temp > 0) { for (temp1 = 0; temp1 <= (Operand1Of(I) - 1); temp1++) UpdateLf(temp1, Lf(temp + temp1)); PopOffLf(temp); } I = PopReturnStack(); CloseFrame (Operand1Of(I)); break; case GOTOOP : I = Operand1Of(I) - 1; break; case CONDOP : temp = PopLf(); if (temp == 0) I = Operand2Of(I) - 1; else I = Operand1Of(I) - 1; break; case CODEOP : PushLf(Operand1Of(I)); break; case LIMITOP : temp2 = PopLf(); /* U */ temp1 = PopLf(); /* L */ temp = PopLf(); /* X */ if ((temp >= temp1) && (temp <= temp2)) PushLf(temp); else { fprintf(output,"<<< MACHINE ERROR >>>: "); fprintf(output,"VALUE OUT OF RANGE\n"); DumpMemory(output); FatalError(); } break; case SOSOP : if (ValidOsOp(I)) { switch (Operand1Of(I)) { case TRACEX : if (TraceSpecified) TraceSpecified = false; else TraceSpecified = true; break; case DUMPMEM : DumpMemory(output); break; case OSINPUT : fscanf(input," "); if (feof(input)) { fprintf(output, "<<< MACHINE ERROR >>>: "); fprintf(output, "TRIED TO READ PAST <EOF>\n"); DumpMemory(output); FatalError(); } else { fscanf(input,"%d",&temp); PushLf(temp); } break; case OSINPUTC : fscanf(input," "); if (feof(input)) { fprintf(output, "<<< MACHINE ERROR >>>: "); fprintf(output, "TRIED TO READ PAST <EOF>\n"); DumpMemory(output); FatalError(); } else { fscanf(input,"%c",&tempc); PushLf(tempc); } break; case OSOUTPUT : temp = PopLf(); fprintf(output,"%d ",temp); break; case OSOUTPUTC: tempc = PopLf(); fprintf(output,"%c",tempc); break; case OSOUTPUTL: fprintf(output,"\n"); break; case OSEOF : fscanf(input," "); if (feof(input)) PushLf(1); else PushLf(0); break; } } else { fprintf(output,"%s","<<< MACHINE ERROR >>>: "); fprintf(output,"%s%1d `", "UNKNOWN OPERAND NAME: ",Operand1Of(I)); fprintf(TraceFile," %d ",Operand1Of(I)); fprintf(output, "` \n"); DumpMemory(output); FatalError(); } break; } /* switch (OpCodeOf(I)) */ } else { fprintf(output,"%s","<<< MACHINE ERROR >>>: "); fprintf(output,"%s","UNKNOWN OP CODE NAME: "); fprintf(output," %d ",OpCodeOf(I)); fprintf(output,"\n"); FatalError(); } I++; } }