Project: s41467-024-46976-4 | Function: infer_step (python)

system: You are an expert Python programmer implementing algorithms from scientific papers.
Complete the masked function based on the algorithm description.
Follow Python best practices and maintain consistent code style.
Return **only** the complete Python function code.

user: Complete this Python function:

**DESCRIPTION:** Implements the core inference step of SQHN using mean-shifted cosine similarity to compute conditional probabilities, performing vector quantization through discrete neural codes for associative memory recall

**KEY TERMS:** {
  "input": "input vector x or image patch x_cl",
  "wts.weight": "memory vectors matrix M_l with columns m_l,j",
  "simFunc": "similarity function selector (2 = mean-shifted cosine)",
  "nm": "normalization factor using L2 norms",
  "out": "computed conditional probabilities h_l",
  "matmul": "matrix multiplication for dot product computation"
}

**CONTEXT CODE:** 

    def detect(self, mxlk, mxC):
        # MASKED: Dynamic neuron growth mechanism with exponentially decaying threshold implementation
        raise NotImplementedError("This function is masked for testing purposes.")



    def rules(self, lk, z, targ):
        with torch.no_grad():
            mxlk = torch.max(lk)
            mxC = torch.argmax(lk)
            new_detect = self.detect(mxlk, mxC)

            # If new cluster detected
            if new_detect and self.wtUp != 2:

                z *= 0
                N = torch.argmin(self.counts)
                z[0, N] = 1
                self.counts[N] = 1
                self.prior[N] = 1
                self.wt_update(targ, z, N)

            elif self.wtUp != 1:
                self.counts[mxC] += 1
                self.update_prior(mxlk, mxC)
                self.wt_update(targ, z, mxC)

            self.age += 1



    def rule2(self, z, targ):
        # Update cluster with max likelihood of data with a gradient step
        with torch.no_grad():
            N = torch.argmax(z)
            self.wt_update(targ, z, N)
            self.age += 1




    def update_prior(self, mxlk, mxC):
        '''new_angle = torch.arccos(self.prior[mxC]) + (torch.arccos(mxlk) - torch.arccos(self.prior[mxC])) / (self.counts[mxC] + 1)
        self.prior[mxC] = torch.cos(new_angle)'''
        self.prior[mxC] = self.prior[mxC] + (mxlk - self.prior[mxC]) / (self.counts[mxC] + 1)



    def infer_step(self, input):
        # MASKED: Core MAP inference using mean-shifted cosine similarity implementation
        raise NotImplementedError("This function is masked for testing purposes.")




    def predict(self, z):
        return self.wts(z)


    def recall(self, targ):
        with torch.no_grad():
            t = targ.clone().view(targ.size(0), -1)
            a = self.infer_step(t)
            if self.actFunc == 0:
                z = F.one_hot(torch.argmax(a, dim=1), num_classes=self.layer_szs[1]).float().to('cpu')
            else:
                z = softmax(a * self.beta)

            return self.predict(z)



    def recognize(self, targ):
        with torch.no_grad():
            t = targ.clone().view(targ.size(0), -1)
            a = self.infer_step(t)
            mxlk = torch.max(a, dim=1)[0]
            mxC = torch.argmax(a, dim=1)
            return mxlk >= (self.prior[mxC] * self.gamma)



    def recognize2(self, targ):
        with torch.no_grad():
            t = targ.clone().view(targ.size(0), -1)
            p = self.recall(t)
            err = torch.mean(torch.square(t - p), dim=1)
            return err <= (self.err_avg * self.gamma)

Complete the function implementation replacing "raise NotImplementedError".