private ChMelement NewElement(double mval, ChMelement mnext, ChMelement mprev, int mrow, int mcol) { if (mbuffer_added >= mbuffer_size) { MoreBuffer(2.0); } /*ChMelement[] newel = mnextel; * mnextel.Initialize(mval, mnext, mprev, mrow, mcol); * mbuffer_added++; * mnextel++;*/ ChMelement newel = mnextel[mbuffer_added]; mnextel[mbuffer_added].Initialize(mval, mnext, mprev, mrow, mcol); mbuffer_added++; //ChMelement newel = new ChMelement(); /*ChMelement newel = mnextel; * for (int i = 1; i < mnextel.Length; i++) { * * mnextel[i].Initialize(mval, mnext, mprev, mrow, mcol); * mbuffer_added++; * newel = mnextel[i + 1]; * //mnextel[i] = newel; * }*/ return(newel); }
public void Build(double fill_in) { mtot_size = 0; mbuffer_added = 0; mnextel = null; // alloc buffer of elements mbuffer_size = (int)(m_num_rows * m_num_cols * fill_in); if (m_num_rows > 5000) { mbuffer_size = (int)ChSparseMatrix.SPM_DEF_MAXELEMENTS; } if (m_num_cols > 5000) { mbuffer_size = (int)ChSparseMatrix.SPM_DEF_MAXELEMENTS; } if (mbuffer_size > (int)ChSparseMatrix.SPM_DEF_MAXELEMENTS) { mbuffer_size = (int)ChSparseMatrix.SPM_DEF_MAXELEMENTS; } if (mbuffer_size < m_num_rows * 2) { mbuffer_size = m_num_rows * 2; } //var mbuffer = (ChMelement*)Marshal.AllocHGlobal(mbuffer_size *sizeof(ChMelement)); ChMelement[] mbuffer = new ChMelement[mbuffer_size]; for (int i = 0; i < mbuffer.Length; i++) { mbuffer[i] = new ChMelement(); } mtot_size += mbuffer_size; mnextel = mbuffer; mbufferlist.AddHead(mbuffer); // alloc pointers to first column //elarray = (ChMelement[])calloc(m_num_rows, sizeof(ChMelement*)); //IntPtr array = Marshal.AllocHGlobal(m_num_rows); //Marshal.FreeHGlobal(array); //ChMelement** array = stackalloc ChMelement*[m_num_rows]; //elarray = (ChMelement**)Marshal.AllocHGlobal(m_num_rows * sizeof(ChMelement)); elarray = new ChMelement[m_num_rows]; for (int i = 0; i < elarray.Length; i++) { elarray[i] = new ChMelement(); } for (int i = 0; i < m_num_rows; i++) { ChMelement pointer = mnextel[i]; (elarray[i]) = pointer; // initialize vector of 1st col pointr pointers (mnextel[i]).Initialize(0, null, null, i, 0); // initialize 1st col.elements mbuffer_added++; // increment the counter of "used" elements. //mnextel++; pointer = mnextel[i + 1]; } }
public void Initialize(double mval, ChMelement mnext, ChMelement mprev, int mrow, int mcol) { val = mval; next = mnext; prev = mprev; col = mcol; row = mrow; }
public ChMelement(double mval, ChMelement mnext, ChMelement mprev, int mrow, int mcol) { this.val = mval; this.next = mnext; this.prev = mprev; this.row = mrow; this.col = mcol; }
// Substitution using existing LU factorization public void Solve_LU(ChMatrix b, ref ChMatrix x) { //Debug.Assert(m_num_rows == b.GetRows()); //Debug.Assert(m_num_cols == x.GetRows()); // BACKWARD substitution - L double xlast = b.GetElement(m_pindices[0], 0); x.SetElement(0, 0, xlast); for (int k = 1; k < m_num_rows; k++) { double sum = 0; ChMelement rowel = GetElarrayMel(k); for (; (rowel != null && rowel.col < k); rowel = rowel.next) { sum += rowel.val * (x.GetElement(rowel.col, 0)); } double val = (b.GetElement(m_pindices[k], 0) - sum); x.SetElement(k, 0, val); } // BACKWARD substitution - U xlast = x.GetElement(m_num_rows - 1, 0) / GetElement(m_num_rows - 1, m_num_rows - 1); x.SetElement(m_num_rows - 1, 0, xlast); for (int k = m_num_rows - 2; k >= 0; k--) { double sum = 0; ChMelement rowel = GetElarrayMel(k); for (; rowel != null; rowel = rowel.next) { if (rowel.col >= k + 1) { sum += rowel.val * (x.GetElement(rowel.col, 0)); } } double val = (x.GetElement(k, 0) - sum) / GetElement(k, k); x.SetElement(k, 0, val); } }
/// Add another buffer in buffer list, bigger of last /// (max total buffer size = col x rows) as in newbuffer = lastbuffer * inflate /// (use inflate >1, suggested 2) [mostly used internally] public void MoreBuffer(double inflate) { mbuffer_size = (int)(inflate * (double)mbuffer_size); // inflate buffer size if (m_num_rows < 5000) { if ((mtot_size + mbuffer_size) > m_num_rows * m_num_cols) { mbuffer_size = m_num_rows * m_num_cols - mtot_size; } } ChMelement[] mbuffer = new ChMelement[mbuffer_size]; for (int i = 0; i < mbuffer.Length; i++) { mbuffer[i] = new ChMelement(); } mtot_size += mbuffer_size; mnextel = mbuffer; mbufferlist.AddTail(mbuffer); // add another buffer! mbuffer_added = 0; }
/// Optimized GetElement, returning the fetched Melement* public ChMelement GetElement(int row, int col, ref double val, ChMelement guess) { /*Debug.Assert(row >= 0); * Debug.Assert(col >= 0); * Debug.Assert(row < m_num_rows); * Debug.Assert(col < m_num_cols); * Debug.Assert(guess.row == row);*/ ChMelement enext; ChMelement eprev; while (guess.col != col) { // forward search if (guess.col < col) { enext = guess.next; if (enext != null) { if (enext.col <= col) { guess = enext; // .. and repeat } else // if (enext.col > col) { val = 0; return(guess); } } else { val = 0; return(guess); } } // backward search if (guess.col > col) { eprev = guess.prev; if (eprev != null) { if (eprev.col >= col) { guess = eprev; // .. and repeat } else // if (eprev.col < col) { val = 0; return(guess); } } else { val = 0; return(guess); } } } // end while loop val = guess.val; return(guess); }
/// Optimized SetElement, returning the fetched Melement* public ChMelement SetElement(int row, int col, double val, ChMelement guess) { /*Debug.Assert(row >= 0); * Debug.Assert(col >= 0); * Debug.Assert(row < m_num_rows); * Debug.Assert(col < m_num_cols); * Debug.Assert(guess.row == row);*/ ChMelement enext; ChMelement eprev; ChMelement newguess; while (guess.col != col) { // forward search if (guess.col < col) { enext = guess.next; if (enext != null) { if (enext.col <= col) { guess = enext; // .. and repeat } else // if (enext.col > col) { newguess = NewElement(val, enext, guess, row, col); guess.next = newguess; enext.prev = newguess; return(newguess); } } else { newguess = NewElement(val, null, guess, row, col); // this one! bast! guess.next = newguess; return(newguess); } } // backward search if (guess.col > col) { eprev = guess.prev; if (eprev != null) { if (eprev.col >= col) { guess = eprev; // .. and repeat } else // if (eprev.col < col) { newguess = NewElement(val, guess, eprev, row, col); eprev.next = newguess; guess.prev = newguess; return(newguess); } } else { newguess = NewElement(val, guess, null, row, col); guess.prev = newguess; return(newguess); } } } guess.val = val; return(guess); }