<commit_before>#ifndef PROJECTIONMAPPING_H
#define PROJECTIONMAPPING_H

#include "AssembledMapping.h"
#include "initCompliant.h"

#include "../utils/map.h"
#include "../utils/pair.h"

namespace sofa {

namespace component {

namespace mapping {

/*
  
  A simple projection-mapping: projects input orthogonally (canonical
  dot-product) onto given (input dof index, deriv) pairs. This is a kind of
  general-purpose mapping. Input: any vector dof. Output: 1d dofs.

  @author: <EMAIL>

*/


template <class TIn, class TOut >
class ProjectionMapping : public AssembledMapping<TIn, TOut> {
public:
	SOFA_CLASS(SOFA_TEMPLATE2(ProjectionMapping,TIn,TOut), SOFA_TEMPLATE2(AssembledMapping,TIn,TOut));
	
	typedef typename TIn::Real in_real;
	typedef typename TOut::Real out_real;

	typedef defaulttype::SerializablePair<unsigned, typename TIn::Coord> set_type;
    Data< vector< set_type > > set;
	
	Data< vector<SReal> > offset;

	typedef AssembledMapping<TIn, TOut> base;
	typedef ProjectionMapping self;

	ProjectionMapping()
		: set(initData(&set, "set", 
					   "(index, coord) vector describing projection space")),
		  offset(initData(&offset, "offset", 
						"scalar offset for each projection (if empty: 0, otherwise last value is repeated as needed)")){
		assert( base::Nout == 1 );
        assert( (unsigned)TIn::deriv_total_size == (unsigned)TIn::coord_total_size && "not vector input dofs !" );
	}
	
protected:
	
	virtual void assemble( const typename self::in_pos_type& in) {
		
		const vector<set_type>& s = set.getValue();
		
		// resize/clear jacobian
		typename self::jacobian_type::CompressedMatrix& J = this->jacobian.compressedMatrix;
		J.resize( base::Nout * s.size(), 
				  base::Nin * in.size() );
		
		J.setZero();

		for( unsigned i = 0, n = s.size(); i < n; ++i) {
			unsigned row = i;

			J.startVec( row );
			
			for( unsigned j = 0, m = self::Nin; j < m; ++j) {
				unsigned col = self::Nin * s[i].pair.first + j;

				J.insertBack(row, col) = s[i].pair.second[j];
			}
	
		}
		
		J.finalize();
		
	}
	
	virtual void apply(typename self::out_pos_type& out, 
					   const typename self::in_pos_type& in ) {
		const vector<set_type>& s = set.getValue();
		const vector<SReal>& off = offset.getValue();
		
		assert(s.size() == out.size());	

		for( unsigned i = 0, n = s.size(); i < n; ++i) {
			
			SReal delta = off.empty() ? 0 : std::min<int>(off.size() - 1, i);

			map(out[i])(0) = map(in[s[i].pair.first]).dot( map(s[i].pair.second ) ) - delta;
		}
		
	}
	
};

}
}
}



#endif
<commit_msg>r10430/sofa : Compliant: fixed projection mapping offsets<commit_after>#ifndef PROJECTIONMAPPING_H
#define PROJECTIONMAPPING_H

#include "AssembledMapping.h"
#include "initCompliant.h"

#include "../utils/map.h"
#include "../utils/pair.h"

namespace sofa {

namespace component {

namespace mapping {

/*
  
  A simple projection-mapping: projects input orthogonally (canonical
  dot-product) onto given (input dof index, deriv) pairs. This is a kind of
  general-purpose mapping. Input: any vector dof. Output: 1d dofs.

  @author: <EMAIL>

*/


template <class TIn, class TOut >
class ProjectionMapping : public AssembledMapping<TIn, TOut> {
public:
	SOFA_CLASS(SOFA_TEMPLATE2(ProjectionMapping,TIn,TOut), SOFA_TEMPLATE2(AssembledMapping,TIn,TOut));
	
	typedef typename TIn::Real in_real;
	typedef typename TOut::Real out_real;

	typedef defaulttype::SerializablePair<unsigned, typename TIn::Coord> set_type;
    Data< vector< set_type > > set;
	
	Data< vector<SReal> > offset;

	typedef AssembledMapping<TIn, TOut> base;
	typedef ProjectionMapping self;

	ProjectionMapping()
		: set(initData(&set, "set", 
					   "(index, coord) vector describing projection space")),
		  offset(initData(&offset, "offset", 
						"scalar offset for each projection (if empty: 0, otherwise last value is repeated as needed)")){
		assert( base::Nout == 1 );
        assert( (unsigned)TIn::deriv_total_size == (unsigned)TIn::coord_total_size && "not vector input dofs !" );
	}
	
protected:
	
	virtual void assemble( const typename self::in_pos_type& in) {
		
		const vector<set_type>& s = set.getValue();
		
		// resize/clear jacobian
		typename self::jacobian_type::CompressedMatrix& J = this->jacobian.compressedMatrix;
		J.resize( base::Nout * s.size(), 
				  base::Nin * in.size() );
		
		J.setZero();

		for( unsigned i = 0, n = s.size(); i < n; ++i) {
			unsigned row = i;

			J.startVec( row );
			
			for( unsigned j = 0, m = self::Nin; j < m; ++j) {
				unsigned col = self::Nin * s[i].pair.first + j;

				J.insertBack(row, col) = s[i].pair.second[j];
			}
	
		}
		
		J.finalize();
		
	}
	
	virtual void apply(typename self::out_pos_type& out, 
					   const typename self::in_pos_type& in ) {
		const vector<set_type>& s = set.getValue();
		const vector<SReal>& off = offset.getValue();
		
		assert(s.size() == out.size());	

		for( unsigned i = 0, n = s.size(); i < n; ++i) {
			
			SReal delta = off.empty() ? 0 : off[ std::min<int>(off.size() - 1, i) ];
			
			map(out[i])(0) = map(in[s[i].pair.first]).dot( map(s[i].pair.second ) ) - delta;
		}
		
	}
	
};

}
}
}



#endif

{'fraction_non_alphanumeric': 0.14972527472527472, 'fraction_numerical': 0.005298273155416013, 'mean_word_length': 3.715078630897317, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3312542', 'n_tokens_mistral': 2051, 'n_tokens_neox': 1765, 'n_words': 448}