def project(self, x, vector):
scale = np.linalg.norm(vector)<EOL>if scale == <NUM_LIT:0.0>:<EOL><INDENT>return vector<EOL><DEDENT>self.lock[:] = False<EOL>normals, signs = self._compute_equations(x)[::<NUM_LIT:3>]<EOL>if len(normals) == <NUM_LIT:0>:<EOL><INDENT>return vector<EOL><DEDENT>vector = vector/scale<EOL>mask = signs == <NUM_LIT:0><EOL>result = vector.copy()<EOL>changed = True<EOL>counter = <NUM_LIT:0><EOL>while changed:<EOL><INDENT>changed = False<EOL>y = np.dot(normals, result)<EOL>for i, sign in enumerate(signs):<EOL><INDENT>if sign != <NUM_LIT:0>:<EOL><INDENT>if sign*y[i] < -self.threshold:<EOL><INDENT>mask[i] = True<EOL>changed = True<EOL><DEDENT>elif mask[i] and np.dot(normals[i], result-vector) < <NUM_LIT:0>:<EOL><INDENT>mask[i] = False<EOL>changed = True<EOL><DEDENT><DEDENT><DEDENT>if mask.any():<EOL><INDENT>normals_select = normals[mask]<EOL>y = np.dot(normals_select, vector)<EOL>U, S, Vt = np.linalg.svd(normals_select, full_matrices=False)<EOL>if S.min() == <NUM_LIT:0.0>:<EOL><INDENT>Sinv = S/(S**<NUM_LIT:2>+self.rcond1)<EOL><DEDENT>else:<EOL><INDENT>Sinv = <NUM_LIT:1.0>/S<EOL><DEDENT>result = vector - np.dot(Vt.transpose(), np.dot(U.transpose(), y)*Sinv)<EOL><DEDENT>else:<EOL><INDENT>result = vector.copy()<EOL><DEDENT>if counter > self.max_iter:<EOL><INDENT>raise ConstraintError('<STR_LIT>')<EOL><DEDENT>counter += <NUM_LIT:1><EOL><DEDENT>return result*scale<EOL>
Project a vector (gradient or direction) on the active constraints.

           Arguments:
            | ``x`` -- The unknowns.
            | ``vector`` -- A numpy array with a direction or a gradient.

           The return value is a gradient or direction, where the components
           that point away from the constraints are projected out. In case of
           half-open constraints, the projection is only active of the vector
           points into the infeasible region.