I need you to review the below code for calculating the reward, here i am getting the reward for some inputs as in lakhs, which of the computation makes it to such large result, please identify the cause of such large rewards.

LARGE_REWARD = 10
SMALL_REWARD = 1
PENALTY = 1
ADDITIONAL_PENALTY = 0.5
LARGE_PENALTY = 5

    def calculate_reward(self, c_metrics, p_metrics, transistor_regions, previous_transistor_regions):
        # Define order of metrics
        metrics_order = ['Area', 'PowerDissipation', 'SlewRate', 'Gain', 'Bandwidth3dB', 'UnityGainFreq', 'PhaseMargin']
        importance_factor = [5, 5, 2, 3, 2, 4, 3]  # Hypothetical importance weights for each metric
        current_metrics = np.array([c_metrics[k] for k in metrics_order])
        previous_metrics = np.array([p_metrics[k] for k in metrics_order])        
        
        reward = 0
    
        # Check if all transistors are in saturation
        all_in_saturation = all(region == 2 for region in transistor_regions.values())
    
        # Check if the performance metrics is within the target specification
        performance_metrics_in_target = self.is_performance_metrics_in_target(current_metrics)
        
        # Additional penalty condition check
        if current_metrics[3] < 0 and current_metrics[5] == 0 and current_metrics[6] == 0:
            # Applying a small penalty times 5 for the stated condition
            reward -= self.ADDITIONAL_PENALTY * 5
        
        # Check if the performance metrics is better or worse than before
        # Initialize an array to track if performance is getting better for each metric
        performance_metrics_getting_better = np.zeros_like(current_metrics, dtype=bool)
        
        # Iterate over each metric and define our condition for ‘better’ based on the metric
        for idx, (current, previous) in enumerate(zip(current_metrics, previous_metrics)):
            if idx < 2:  # Smaller is better for 'area' & 'power dissipation'
                improvement = previous - current
                if improvement > 0:
                    reward += improvement * importance_factor[idx] * self.SMALL_REWARD  # Dynamically scale reward
                    performance_metrics_getting_better[idx] = True
            else:  # Larger is better for the other metrics
                improvement = current - previous
                if improvement > 0:
                    reward += improvement * importance_factor[idx] * self.SMALL_REWARD
                    performance_metrics_getting_better[idx] = True
        
        # Check how many transistors were not in saturation previously and are in saturation now
        newly_in_saturation = sum(1 for current_region, previous_region in zip(transistor_regions.values(), previous_transistor_regions.values()) if current_region == 2 and previous_region != 2)
        newly_not_in_saturation = sum(1 for region, prev_region in zip(transistor_regions.values(), previous_transistor_regions.values()) if region != 2 and prev_region == 2)
        
        # Count of metrics getting better and worse
        num_better = np.count_nonzero(performance_metrics_getting_better)
        num_worse = len(current_metrics) - num_better                       
           
        # Reward if all performance metrics are improving and all transistors are in saturation
        if num_better == len(current_metrics) and all_in_saturation:
            reward += self.LARGE_REWARD
    
        # Else if performance metrics are all within target but not all transistors are in saturation, reward
        elif performance_metrics_in_target and not all_in_saturation:
            reward += self.SMALL_REWARD
    
        # Else if performance metrics are not in target, consider further details
        elif not performance_metrics_in_target:        
            if all_in_saturation:
                # Reward if all transistors are in saturation, even if metrics are not in target
                reward += self.SMALL_REWARD
            
            reward += self.SMALL_REWARD * num_better - self.PENALTY * num_worse
    
            # Reward improvement in saturation, if not already rewarded for all metrics improving
            if newly_in_saturation > 0:
                reward += self.SMALL_REWARD * newly_in_saturation
    
            # Penalize if some transistors have fallen out of saturation since the last evaluation
            if newly_not_in_saturation > 0:
                reward -= self.ADDITIONAL_PENALTY * newly_not_in_saturation
    
        # Independent of the above, penalize if any transistor is out of saturation
        penalty_count = sum(1 for region in transistor_regions.values() if region != 2)
        reward -= self.LARGE_PENALTY * penalty_count        

        normalized_rewards = int(reward)
        
        return normalized_rewards