Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_MATH_OPTIMIZATION_NON_SMOOTH_NEWTON_BIG_COMPUTE_PARTITIONED_JACOBIAN_H
00002 #define OPENTISSUE_CORE_MATH_OPTIMIZATION_NON_SMOOTH_NEWTON_BIG_COMPUTE_PARTITIONED_JACOBIAN_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/math/big/big_types.h>
00013 #include <OpenTissue/core/math/math_value_traits.h>
00014 #include <cmath>
00015
00016 namespace OpenTissue
00017 {
00018 namespace math
00019 {
00020 namespace optimization
00021 {
00022 namespace detail
00023 {
00024
00047 template<typename T, typename bound_function_type>
00048 inline void compute_partitioned_jacobian(
00049 ublas::compressed_matrix<T> const & A
00050 , bound_function_type const & l
00051 , bound_function_type const & u
00052 , ublas::vector<size_t> const & bitmask
00053 , ublas::vector<size_t> const & old2new
00054 , size_t const & cnt_active
00055 , size_t const & cnt_inactive
00056 , ublas::compressed_matrix<T> & A_aa
00057 , ublas::compressed_matrix<T> & A_ab
00058 , ublas::compressed_matrix<T> & C
00059 , ublas::compressed_matrix<T> & D
00060 )
00061 {
00062 using std::min;
00063
00064 typedef typename bound_function_type::vector_iterator vector_iterator;
00065 typedef typename OpenTissue::math::ValueTraits<T> value_traits;
00066
00067 static size_t const in_lower = 1;
00068 static size_t const in_upper = 2;
00069 static size_t const in_active = 4;
00070
00071 A_aa.resize( cnt_active, cnt_active, false );
00072 A_ab.resize( cnt_active, cnt_inactive, false );
00073 C.resize( cnt_inactive, cnt_active, false );
00074 D.resize( cnt_inactive, cnt_inactive, false );
00075
00076 size_t const row_end = A.filled1() - 1;
00077 for (size_t i_old = 0; i_old < row_end; ++i_old)
00078 {
00079 if( bitmask(i_old) == in_active )
00080 {
00081 size_t const i_new = old2new( i_old );
00082 size_t const begin = A.index1_data()[i_old];
00083 size_t const end = A.index1_data()[i_old + 1];
00084
00085 for (size_t j = begin; j < end; ++ j)
00086 {
00087 size_t const j_old = A.index2_data()[j];
00088 size_t const j_new = old2new( j_old );
00089 if( bitmask(j_old) == in_active )
00090 A_aa( i_new, j_new ) = A.value_data()[j];
00091 else
00092 A_ab( i_new, j_new-cnt_active ) = A.value_data()[j];
00093 }
00094 }
00095 }
00096
00097 size_t const n = cnt_active + cnt_inactive;
00098
00099 for(size_t i_old = 0; i_old < n; ++i_old)
00100 {
00101 size_t const i_new = old2new( i_old );
00102 if( bitmask(i_old) == in_lower )
00103 {
00104 vector_iterator const begin = l.partial_begin( i_old );
00105 vector_iterator const end = l.partial_end( i_old );
00106 for(vector_iterator e = begin;e!=end;++e)
00107 {
00108 size_t const j_old = e.index();
00109 size_t const j_new = old2new( j_old );
00110 if( bitmask(j_old) == in_active )
00111 C(i_new - cnt_active, j_new) = - *e;
00112 else
00113 D(i_new - cnt_active ,j_new - cnt_active) = - *e;
00114 }
00115 D(i_new - cnt_active, i_new - cnt_active) = value_traits::one();
00116 }
00117
00118 if( bitmask(i_old) == in_upper )
00119 {
00120 vector_iterator const begin = u.partial_begin( i_old );
00121 vector_iterator const end = u.partial_end( i_old );
00122 for(vector_iterator e = begin;e!=end;++e)
00123 {
00124 size_t const j_old = e.index();
00125 size_t const j_new = old2new( j_old );
00126 if( bitmask(j_old) == in_active )
00127 C(i_new - cnt_active, j_new) = - *e;
00128 else
00129 D(i_new - cnt_active ,j_new - cnt_active) = - *e;
00130 }
00131 D(i_new - cnt_active, i_new - cnt_active) = value_traits::one();
00132 }
00133 }
00134 }
00135
00136
00137 }
00138 }
00139 }
00140 }
00141
00142
00143 #endif