int main(int argc, char** argv) { int m = 10; int p = 20; /// external allocation for the matrix double* prD = new double[m*p]; Matrix<double> D(prD,m,p); D.setAleat(); D.normalize(); /// Allocate a matrix of size m x p Matrix<double> D2(m,p); D2.setAleat(); D2.normalize(); int n = 100; Matrix<double> X(m,n); X.setAleat(); /// create empty sparse marix SpMatrix<double> spa; lasso2(X,D,spa,10,0.15); // first simple example /// extern allocation for the matrix D requires /// manually unallocating prD delete[](prD); }
virtual void run(Voxel& voxel, VoxelData& data) { if (!voxel.odf_decomposition) return; std::vector<float> old_odf(data.odf); normalize_vector(data.odf.begin(),data.odf.end()); std::vector<float> w; lasso2(data.odf,Rt,w,m); std::vector<int> dir_list; for(unsigned int index = 0;index < half_odf_size;++index) if(w[index] > 0.0) dir_list.push_back(index); std::vector<float> results; int has_isotropic = 1; while(1) { if(dir_list.empty()) { results.resize(1); results[0] = image::mean(old_odf.begin(),old_odf.end()); has_isotropic = 1; break; } std::vector<float> RRt; if(has_isotropic) { RRt.resize(half_odf_size); std::fill(RRt.begin(),RRt.end(),1.0); } for (unsigned int index = 0;index < dir_list.size();++index) { int dir = dir_list[index]; std::copy(oRt.begin()+dir*half_odf_size, oRt.begin()+(1+dir)*half_odf_size, std::back_inserter(RRt)); } results.resize(dir_list.size()+has_isotropic); image::matrix::pseudo_inverse_solve(&*RRt.begin(),&*old_odf.begin(),&*results.begin(),image::dyndim(results.size(),half_odf_size)); // drop negative int min_index = std::min_element(results.begin()+has_isotropic,results.end())-results.begin(); if(results[min_index] < 0.0) { dir_list.erase(dir_list.begin()+min_index-has_isotropic); results.erase(results.begin()+min_index); continue; } if(has_isotropic && results[0] < 0.0) { has_isotropic = 0; continue; } // drop non local maximum std::vector<int> neighbors; for(unsigned int i = 0;i < dir_list.size();++i) for(unsigned int j = i+1;j < dir_list.size();++j) if(is_neighbor[dir_list[i]][dir_list[j]]) { neighbors.push_back(i); neighbors.push_back(j); } if(neighbors.empty()) break; int smallest_neighbor = neighbors[0]; float value = results[smallest_neighbor+has_isotropic]; for(unsigned int i = 1;i < neighbors.size();++i) if(results[neighbors[i]+has_isotropic] < value) { smallest_neighbor = neighbors[i]; value = results[smallest_neighbor+has_isotropic]; } dir_list.erase(dir_list.begin()+smallest_neighbor); results.erase(results.begin()+smallest_neighbor+has_isotropic); } float fiber_sum = std::accumulate(results.begin()+has_isotropic,results.end(),0.0f); data.min_odf = has_isotropic ? std::max<float>(results[0],0.0):0.0; std::fill(data.odf.begin(),data.odf.end(), data.min_odf); for(int index = 0;index < dir_list.size();++index) data.odf[dir_list[index]] += results[index+has_isotropic]; if(data.min_odf > max_iso) max_iso = data.min_odf; fiber_ratio[data.voxel_index] = fiber_sum; }