class_docstr: Portfolio Optimizer
  
  The following optimization algorithms are supported:
      - `gmv`: Global Minimum Variance Portfolio
      - `mvo`: Mean Variance Optimized Portfolio
      - `rp`: Risk Parity
      - `inv`: Inverse Volatility
  
  Note:
      This optimizer always assumes full investment and no-shorting.
class_docstr_tok: ["Portfolio","Optimizer","The","following","optimization","algorithms","are","supported",":","-","`","gmv","`",":","Global","Minimum","Variance","Portfolio","-","`","mvo","`",":","Mean","Variance","Optimized","Portfolio","-","`","rp","`",":","Risk","Parity","-","`","inv","`",":","Inverse","Volatility","Note",":","This","optimizer","always","assumes","full","investment","and","no-shorting","."]
docstr: Args:
      S (np.ndarray or pd.DataFrame): covariance matrix
      r (np.ndarray or pd.Series): expected return
      w0 (np.ndarray or pd.Series): initial weights (for turnover control)
  
  Returns:
      np.ndarray or pd.Series: optimized portfolio allocation
docstr_tok: ["Args",":","S","(","np.ndarray","or","pd.DataFrame",")",":","covariance","matrix","r","(","np.ndarray","or","pd.Series",")",":","expected","return","w0","(","np.ndarray","or","pd.Series",")",":","initial","weights","(","for","turnover","control",")","Returns",":","np.ndarray","or","pd.Series",":","optimized","portfolio","allocation"]
code: def __call__(
      self,
      S: Union[np.ndarray, pd.DataFrame],
      r: Optional[Union[np.ndarray, pd.Series]] = None,
      w0: Optional[Union[np.ndarray, pd.Series]] = None,
  ) -> Union[np.ndarray, pd.Series]:
      """
      Args:
          S (np.ndarray or pd.DataFrame): covariance matrix
          r (np.ndarray or pd.Series): expected return
          w0 (np.ndarray or pd.Series): initial weights (for turnover control)
  
      Returns:
          np.ndarray or pd.Series: optimized portfolio allocation
      """
      # transform dataframe into array
      index = None
      if isinstance(S, pd.DataFrame):
          index = S.index
          S = S.values
  
      # transform return
      if r is not None:
          assert len(r) == len(S), "`r` has mismatched shape"
          if isinstance(r, pd.Series):
              assert r.index.equals(index), "`r` has mismatched index"
              r = r.values
  
      # transform initial weights
      if w0 is not None:
          assert len(w0) == len(S), "`w0` has mismatched shape"
          if isinstance(w0, pd.Series):
              assert w0.index.equals(index), "`w0` has mismatched index"
              w0 = w0.values
  
      # scale return to match volatility
      if r is not None and self.scale_return:
          r = r / r.std()
          r *= np.sqrt(np.mean(np.diag(S)))
  
      # optimize
      w = self._optimize(S, r, w0)
  
      # restore index if needed
      if index is not None:
          w = pd.Series(w, index=index)
  
      return w
  
file_path: qlib/qlib/contrib/strategy/optimizer/optimizer.py
imports: import warnings
  import numpy
  import pandas
  import scipy.optimize
  from typing import Optional, Union, Callable, List
  from .base import BaseOptimizer
label_desc: Use image node_id 2 for calling the PortfolioOptimizer obj's underlying member method code with example usage: obj.__call__(S, r, w0) and returns: w