class_docstr: Funsor representing a batched Gaussian log-density function.
  
  Gaussians are the internal representation for joint and conditional
  multivariate normal distributions and multivariate normal likelihoods.
  Mathematically, a Gaussian represents the quadratic log density function::
  
      f(x) = -0.5 * || x @ prec_sqrt - white_vec ||^2
           = -0.5 * < x @ prec_sqrt - white_vec | x @ prec_sqrt - white_vec >
           = -0.5 * < x | prec_sqrt @ prec_sqrt.T | x>
             + < x | prec_sqrt | white_vec > - 0.5 ||white_vec||^2
  
  Internally Gaussians use a square root information filter (SRIF)
  representation consisting of a square root of the precision matrix
  ``prec_sqrt`` and a vector in the whitened space ``white_vec``. This
  representation allows space-efficient construction of Gaussians with
  incomplete information, i.e. with zero eigenvalues in the precision matrix.
  These incomplete log densities arise when making low-dimensional
  observations of higher-dimensional hidden state. Sampling and
  marginalization are supported only for full-rank Gaussians or full-rank
  subsets of Gaussians. See the :meth:`rank` and :meth:`is_full_rank`
  properties.
  
  .. note:: :class:`Gaussian` s are not normalized probability distributions,
      rather they are canonicalized to evaluate to zero log density at their
      maximum: ``f(prec_sqrt \ white_vec) = 0``. Not only are Gaussians
      non-normalized, but they may be rank deficient and non-normalizable, in
      which case sampling and marginalization are supported only un full-rank
      subsets of variables.
  
  :param torch.Tensor white_vec: An batched white noise vector, where
      ``white_vec = prec_sqrt.T @ mean``. Alternatively you can specify one
      of the kwargs ``mean`` or ``info_vec``, which will be converted to
      ``white_vec``.
  :param torch.Tensor prec_sqrt: A batched square root of the positive
      semidefinite precision matrix. This need not be square, and typically
      has shape ``prec_sqrt.shape == white_vec.shape[:-1] + (dim, rank)``,
      where ``dim`` is the total flattened size of real inputs and
      ``rank = white_vec.shape[-1]``.  Alternatively you can specify one of
      the kwargs ``precision``, ``covariance``, or ``scale_tril``, which will
      be converted to ``prec_sqrt``.
  :param OrderedDict inputs: Mapping from name to
      :class:`~funsor.domains.Domain` .
class_docstr_tok: ["Funsor","representing","a","batched","Gaussian","log-density","function",".","Gaussians","are","the","internal","representation","for","joint","and","conditional","multivariate","normal","distributions","and","multivariate","normal","likelihoods",".","Mathematically",",","a","Gaussian","represents","the","quadratic","log","density","function",":",":","f","(","x",")","=","-0.5","*","||","x","@","prec_sqrt","-","white_vec","||^2","=","-0.5","*","<","x","@","prec_sqrt","-","white_vec","|","x","@","prec_sqrt","-","white_vec",">","=","-0.5","*","<","x","|","prec_sqrt","@","prec_sqrt.T","|","x",">","+","<","x","|","prec_sqrt","|","white_vec",">","-","0.5","||white_vec||^2","Internally","Gaussians","use","a","square","root","information","filter","(","SRIF",")","representation","consisting","of","a","square","root","of","the","precision","matrix","``","prec_sqrt","``","and","a","vector","in","the","whitened","space","``","white_vec","``",".","This","representation","allows","space-efficient","construction","of","Gaussians","with","incomplete","information",",","i.e",".","with","zero","eigenvalues","in","the","precision","matrix",".","These","incomplete","log","densities","arise","when","making","low-dimensional","observations","of","higher-dimensional","hidden","state",".","Sampling","and","marginalization","are","supported","only","for","full-rank","Gaussians","or","full-rank","subsets","of","Gaussians",".","See","the",":","meth",":","`","rank","`","and",":","meth",":","`","is_full_rank","`","properties",".","..","note",":",":",":","class",":","`","Gaussian","`","s","are","not","normalized","probability","distributions",",","rather","they","are","canonicalized","to","evaluate","to","zero","log","density","at","their","maximum",":","``","f","(","prec_sqrt","\\","white_vec",")","=","0","``",".","Not","only","are","Gaussians","non-normalized",",","but","they","may","be","rank","deficient","and","non-normalizable",",","in","which","case","sampling","and","marginalization","are","supported","only","un","full-rank","subsets","of","variables",".",":","param","torch.Tensor","white_vec",":","An","batched","white","noise","vector",",","where","``","white_vec","=","prec_sqrt.T","@","mean","``",".","Alternatively","you","can","specify","one","of","the","kwargs","``","mean","``","or","``","info_vec","``",",","which","will","be","converted","to","``","white_vec","``",".",":","param","torch.Tensor","prec_sqrt",":","A","batched","square","root","of","the","positive","semidefinite","precision","matrix",".","This","need","not","be","square",",","and","typically","has","shape","``","prec_sqrt.shape","==","white_vec.shape","[",":","-1","]","+","(","dim",",","rank",")","``",",","where","``","dim","``","is","the","total","flattened","size","of","real","inputs","and","``","rank","=","white_vec.shape","[","-1","]","``",".","Alternatively","you","can","specify","one","of","the","kwargs","``","precision","``",",","``","covariance","``",",","or","``","scale_tril","``",",","which","will","be","converted","to","``","prec_sqrt","``",".",":","param","OrderedDict","inputs",":","Mapping","from","name","to",":","class",":","`","~funsor.domains.Domain","`","."]
docstr: Context manager to set rank compression threshold.
  
  To save space Gaussians compress wide ``prec_sqrt`` matrices down to
  square. However compression uses a QR decomposition which can be
  expensive and which has unstable gradients when the resulting precision
  matrix is rank deficient. To balance space and time costs and numerical
  stability, compression is trigger only on ``prec_sqrt`` matrices whose
  width to height ratio is greater than ``threshold``.
  
  :param float threshold: Defaults to 2. To optimize for space and
      deterministic computations, set ``threshold = 1``. To optimize for
      fewest QR decompositions and numerical stability, set ``threshold =
      math.inf``.
docstr_tok: ["Context","manager","to","set","rank","compression","threshold",".","To","save","space","Gaussians","compress","wide","``","prec_sqrt","``","matrices","down","to","square",".","However","compression","uses","a","QR","decomposition","which","can","be","expensive","and","which","has","unstable","gradients","when","the","resulting","precision","matrix","is","rank","deficient",".","To","balance","space","and","time","costs","and","numerical","stability",",","compression","is","trigger","only","on","``","prec_sqrt","``","matrices","whose","width","to","height","ratio","is","greater","than","``","threshold","``",".",":","param","float","threshold",":","Defaults","to","2",".","To","optimize","for","space","and","deterministic","computations",",","set","``","threshold","=","1","``",".","To","optimize","for","fewest","QR","decompositions","and","numerical","stability",",","set","``","threshold","=","math.inf","``","."]
code: def set_compression_threshold(cls, threshold: float):
      """
      Context manager to set rank compression threshold.
  
      To save space Gaussians compress wide ``prec_sqrt`` matrices down to
      square. However compression uses a QR decomposition which can be
      expensive and which has unstable gradients when the resulting precision
      matrix is rank deficient. To balance space and time costs and numerical
      stability, compression is trigger only on ``prec_sqrt`` matrices whose
      width to height ratio is greater than ``threshold``.
  
      :param float threshold: Defaults to 2. To optimize for space and
          deterministic computations, set ``threshold = 1``. To optimize for
          fewest QR decompositions and numerical stability, set ``threshold =
          math.inf``.
      """
      assert isinstance(threshold, (int, float))
      assert threshold >= 1
      old = cls.compression_threshold
      try:
          cls.compression_threshold = threshold
          yield
      finally:
          cls.compression_threshold = old
  
imports: import math
  from collections import OrderedDict, defaultdict
  from contextlib import contextmanager
  from functools import reduce
  import funsor.ops
  from funsor.affine import affine_inputs, extract_affine, is_affine
  from funsor.delta import Delta
  from funsor.domains import Real, Reals
  from funsor.interpretations import compress_gaussians
  from funsor.ops import AddOp, SubOp
  from funsor.tensor import Tensor, align_tensor, align_tensors
  from funsor.terms import Binary, Funsor, FunsorMeta, Number, Slice, Subs, Variable, eager, reflect
  from funsor.util import broadcast_shape, get_tracing_state, lazy_property
label_desc: Use image node_id 2 for calling the Gaussian obj's underlying member method code with example usage: obj.set_compression_threshold(cls, threshold) without return types