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);
}
Ejemplo n.º 2
0
    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;
    }