function [inconstrained, dNetin_dNetinraw_imask] = impose_input_constraints(in, net, pp)
%#codegen
if nargout>1 % calculate derivatives?
  calcder = true;
else
  calcder = false;
end

%% init
inconstrained = in; % initialized
cc = pp.constrainInputs; % flag whether input should be constrained or not
%% saturate input values if exceed training range (with margin)
inputsMin = net.feature_min + (1-pp.margin) .* abs(net.feature_min);
inputsMax = net.feature_max - (1-pp.margin) .* abs(net.feature_max);

% val_constrained = min(max(value,val_min),val_max)
inconstrained(:,cc) = bsxfun(@min,bsxfun(@max,in(:,cc),inputsMin(cc)),inputsMax(cc));
if calcder
  dNetin_dNetinraw_imask = (inconstrained==in);
end
return