class_docstr: Samples data from linearly parameterized arms.
  
  The reward for context X and arm i is given by X^T * theta_i, for some
  latent set of parameters {theta_i : i = 1, ..., k}.
  The thetas are sampled uniformly at random, the contexts are Gaussian,
  and Gaussian noise is added to the rewards.
class_docstr_tok: ["Samples","data","from","linearly","parameterized","arms",".","The","reward","for","context","X","and","arm","i","is","given","by","X^T","*","theta_i",",","for","some","latent","set","of","parameters","{","theta_i",":","i","=","1",",","...",",","k","}",".","The","thetas","are","sampled","uniformly","at","random",",","the","contexts","are","Gaussian",",","and","Gaussian","noise","is","added","to","the","rewards","."]
code: def __init__(self, config=None):
      self.config = copy.copy(self.DEFAULT_CONFIG_LINEAR)
      if config is not None and type(config) == dict:
          self.config.update(config)
  
      self.feature_dim = self.config["feature_dim"]
      self.num_actions = self.config["num_actions"]
      self.sigma = self.config["reward_noise_std"]
  
      self.action_space = Discrete(self.num_actions)
      self.observation_space = Box(
          low=-10, high=10, shape=(self.feature_dim,)
      )
  
      self.thetas = np.random.uniform(
          -1, 1, (self.num_actions, self.feature_dim)
      )
      self.thetas /= np.linalg.norm(self.thetas, axis=1, keepdims=True)
  
      self._elapsed_steps = 0
      self._current_context = None
  
imports: import copy
  import random
  import gymnasium
  import numpy
  from gymnasium.spaces import Box, Discrete
label_desc: Use image node_id 1 to create a new LinearDiscreteEnv object from inherited base classes: gym with example: obj = LinearDiscreteEnv(config)