AmbiVector.h revision c981c48f5bc9aefeffc0bcb0cc3934c2fae179dd
1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library 2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra. 3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> 5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla 7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed 8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_AMBIVECTOR_H 11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_AMBIVECTOR_H 12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace Eigen { 14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal { 16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal 18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Hybrid sparse/dense vector class designed for intensive read-write operations. 19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * See BasicSparseLLT and SparseProduct for usage examples. 21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _Scalar, typename _Index> 23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass AmbiVector 24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath public: 26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef _Scalar Scalar; 27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef _Index Index; 28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename NumTraits<Scalar>::Real RealScalar; 29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath AmbiVector(Index size) 31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : m_buffer(0), m_zero(0), m_size(0), m_allocatedSize(0), m_allocatedElements(0), m_mode(-1) 32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath resize(size); 34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath void init(double estimatedDensity); 37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath void init(int mode); 38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index nonZeros() const; 40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** Specifies a sub-vector to work on */ 42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath void setBounds(Index start, Index end) { m_start = start; m_end = end; } 43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath void setZero(); 45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath void restart(); 47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Scalar& coeffRef(Index i); 48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Scalar& coeff(Index i); 49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath class Iterator; 51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ~AmbiVector() { delete[] m_buffer; } 53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath void resize(Index size) 55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (m_allocatedSize < size) 57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath reallocate(size); 58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_size = size; 59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index size() const { return m_size; } 62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath protected: 64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath void reallocate(Index size) 66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // if the size of the matrix is not too large, let's allocate a bit more than needed such 68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // that we can handle dense vector even in sparse mode. 69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath delete[] m_buffer; 70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (size<1000) 71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index allocSize = (size * sizeof(ListEl))/sizeof(Scalar); 73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_allocatedElements = (allocSize*sizeof(Scalar))/sizeof(ListEl); 74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_buffer = new Scalar[allocSize]; 75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_allocatedElements = (size*sizeof(Scalar))/sizeof(ListEl); 79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_buffer = new Scalar[size]; 80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_size = size; 82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_start = 0; 83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_end = m_size; 84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath void reallocateSparse() 87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index copyElements = m_allocatedElements; 89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_allocatedElements = (std::min)(Index(m_allocatedElements*1.5),m_size); 90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index allocSize = m_allocatedElements * sizeof(ListEl); 91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath allocSize = allocSize/sizeof(Scalar) + (allocSize%sizeof(Scalar)>0?1:0); 92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Scalar* newBuffer = new Scalar[allocSize]; 93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath memcpy(newBuffer, m_buffer, copyElements * sizeof(ListEl)); 94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath delete[] m_buffer; 95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_buffer = newBuffer; 96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath protected: 99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // element type of the linked list 100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath struct ListEl 101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index next; 103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index index; 104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Scalar value; 105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // used to store data in both mode 108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Scalar* m_buffer; 109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Scalar m_zero; 110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index m_size; 111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index m_start; 112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index m_end; 113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index m_allocatedSize; 114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index m_allocatedElements; 115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index m_mode; 116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // linked list mode 118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index m_llStart; 119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index m_llCurrent; 120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index m_llSize; 121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \returns the number of non zeros in the current sub vector */ 124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _Scalar,typename _Index> 125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath_Index AmbiVector<_Scalar,_Index>::nonZeros() const 126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (m_mode==IsSparse) 128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return m_llSize; 129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return m_end - m_start; 131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _Scalar,typename _Index> 134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid AmbiVector<_Scalar,_Index>::init(double estimatedDensity) 135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (estimatedDensity>0.1) 137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath init(IsDense); 138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath init(IsSparse); 140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _Scalar,typename _Index> 143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid AmbiVector<_Scalar,_Index>::init(int mode) 144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_mode = mode; 146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (m_mode==IsSparse) 147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_llSize = 0; 149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_llStart = -1; 150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** Must be called whenever we might perform a write access 154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * with an index smaller than the previous one. 155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Don't worry, this function is extremely cheap. 157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _Scalar,typename _Index> 159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid AmbiVector<_Scalar,_Index>::restart() 160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 161c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_llCurrent = m_llStart; 162c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 163c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 164c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** Set all coefficients of current subvector to zero */ 165c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _Scalar,typename _Index> 166c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid AmbiVector<_Scalar,_Index>::setZero() 167c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 168c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (m_mode==IsDense) 169c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Index i=m_start; i<m_end; ++i) 171c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_buffer[i] = Scalar(0); 172c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 174c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_mode==IsSparse); 176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_llSize = 0; 177c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_llStart = -1; 178c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 179c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _Scalar,typename _Index> 182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath_Scalar& AmbiVector<_Scalar,_Index>::coeffRef(_Index i) 183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 184c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (m_mode==IsDense) 185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return m_buffer[i]; 186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ListEl* EIGEN_RESTRICT llElements = reinterpret_cast<ListEl*>(m_buffer); 189c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // TODO factorize the following code to reduce code generation 190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_mode==IsSparse); 191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (m_llSize==0) 192c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 193c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // this is the first element 194c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_llStart = 0; 195c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_llCurrent = 0; 196c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ++m_llSize; 197c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath llElements[0].value = Scalar(0); 198c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath llElements[0].index = i; 199c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath llElements[0].next = -1; 200c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return llElements[0].value; 201c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 202c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else if (i<llElements[m_llStart].index) 203c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 204c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // this is going to be the new first element of the list 205c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ListEl& el = llElements[m_llSize]; 206c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath el.value = Scalar(0); 207c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath el.index = i; 208c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath el.next = m_llStart; 209c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_llStart = m_llSize; 210c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ++m_llSize; 211c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_llCurrent = m_llStart; 212c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return el.value; 213c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 214c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 215c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 216c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index nextel = llElements[m_llCurrent].next; 217c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(i>=llElements[m_llCurrent].index && "you must call restart() before inserting an element with lower or equal index"); 218c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath while (nextel >= 0 && llElements[nextel].index<=i) 219c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 220c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_llCurrent = nextel; 221c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath nextel = llElements[nextel].next; 222c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 223c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 224c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (llElements[m_llCurrent].index==i) 225c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 226c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // the coefficient already exists and we found it ! 227c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return llElements[m_llCurrent].value; 228c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 229c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 231c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (m_llSize>=m_allocatedElements) 232c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 233c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath reallocateSparse(); 234c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath llElements = reinterpret_cast<ListEl*>(m_buffer); 235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 236c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_internal_assert(m_llSize<m_allocatedElements && "internal error: overflow in sparse mode"); 237c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // let's insert a new coefficient 238c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ListEl& el = llElements[m_llSize]; 239c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath el.value = Scalar(0); 240c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath el.index = i; 241c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath el.next = llElements[m_llCurrent].next; 242c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath llElements[m_llCurrent].next = m_llSize; 243c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ++m_llSize; 244c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return el.value; 245c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 246c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 247c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 248c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 249c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 250c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _Scalar,typename _Index> 251c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath_Scalar& AmbiVector<_Scalar,_Index>::coeff(_Index i) 252c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 253c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (m_mode==IsDense) 254c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return m_buffer[i]; 255c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 256c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 257c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ListEl* EIGEN_RESTRICT llElements = reinterpret_cast<ListEl*>(m_buffer); 258c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_mode==IsSparse); 259c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if ((m_llSize==0) || (i<llElements[m_llStart].index)) 260c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 261c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return m_zero; 262c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 263c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 264c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 265c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index elid = m_llStart; 266c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath while (elid >= 0 && llElements[elid].index<i) 267c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath elid = llElements[elid].next; 268c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 269c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (llElements[elid].index==i) 270c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return llElements[m_llCurrent].value; 271c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 272c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return m_zero; 273c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 274c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 275c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 276c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 277c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** Iterator over the nonzero coefficients */ 278c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _Scalar,typename _Index> 279c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass AmbiVector<_Scalar,_Index>::Iterator 280c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 281c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath public: 282c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef _Scalar Scalar; 283c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename NumTraits<Scalar>::Real RealScalar; 284c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 285c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** Default constructor 286c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \param vec the vector on which we iterate 287c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \param epsilon the minimal value used to prune zero coefficients. 288c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * In practice, all coefficients having a magnitude smaller than \a epsilon 289c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * are skipped. 290c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 291c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Iterator(const AmbiVector& vec, RealScalar epsilon = 0) 292c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : m_vector(vec) 293c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 294c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_epsilon = epsilon; 295c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_isDense = m_vector.m_mode==IsDense; 296c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (m_isDense) 297c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 298c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_currentEl = 0; // this is to avoid a compilation warning 299c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_cachedValue = 0; // this is to avoid a compilation warning 300c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_cachedIndex = m_vector.m_start-1; 301c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ++(*this); 302c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 303c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 304c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 305c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ListEl* EIGEN_RESTRICT llElements = reinterpret_cast<ListEl*>(m_vector.m_buffer); 306c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_currentEl = m_vector.m_llStart; 307c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath while (m_currentEl>=0 && internal::abs(llElements[m_currentEl].value)<=m_epsilon) 308c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_currentEl = llElements[m_currentEl].next; 309c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (m_currentEl<0) 310c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 311c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_cachedValue = 0; // this is to avoid a compilation warning 312c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_cachedIndex = -1; 313c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 314c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 315c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 316c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_cachedIndex = llElements[m_currentEl].index; 317c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_cachedValue = llElements[m_currentEl].value; 318c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 319c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 320c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 321c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 322c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index index() const { return m_cachedIndex; } 323c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Scalar value() const { return m_cachedValue; } 324c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 325c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath operator bool() const { return m_cachedIndex>=0; } 326c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 327c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Iterator& operator++() 328c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 329c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (m_isDense) 330c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 331c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath do { 332c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ++m_cachedIndex; 333c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } while (m_cachedIndex<m_vector.m_end && internal::abs(m_vector.m_buffer[m_cachedIndex])<m_epsilon); 334c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (m_cachedIndex<m_vector.m_end) 335c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_cachedValue = m_vector.m_buffer[m_cachedIndex]; 336c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 337c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_cachedIndex=-1; 338c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 339c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 340c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 341c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ListEl* EIGEN_RESTRICT llElements = reinterpret_cast<ListEl*>(m_vector.m_buffer); 342c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath do { 343c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_currentEl = llElements[m_currentEl].next; 344c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } while (m_currentEl>=0 && internal::abs(llElements[m_currentEl].value)<m_epsilon); 345c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (m_currentEl<0) 346c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 347c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_cachedIndex = -1; 348c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 349c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 350c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 351c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_cachedIndex = llElements[m_currentEl].index; 352c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_cachedValue = llElements[m_currentEl].value; 353c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 354c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 355c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return *this; 356c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 357c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 358c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath protected: 359c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const AmbiVector& m_vector; // the target vector 360c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index m_currentEl; // the current element in sparse/linked-list mode 361c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RealScalar m_epsilon; // epsilon used to prune zero coefficients 362c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index m_cachedIndex; // current coordinate 363c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Scalar m_cachedValue; // current value 364c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath bool m_isDense; // mode of the vector 365c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 366c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 367c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal 368c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 369c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace Eigen 370c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 371c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // EIGEN_AMBIVECTOR_H 372