gt:                 double x = log[j].getValue(0);
context: /*
   * EllipticalSliceOperator.java
   *
   * Copyright (c) 2002-2014 Alexei Drummond, Andrew Rambaut and Marc Suchard
   *
   * This file is part of BEAST.
   * See the NOTICE file distributed with this work for additional
   * information regarding copyright ownership and licensing.
   *
   * BEAST is free software; you can redistribute it and/or modify
   * it under the terms of the GNU Lesser General Public License as
   * published by the Free Software Foundation; either version 2
   * of the License, or (at your option) any later version.
   *
   *  BEAST is distributed in the hope that it will be useful,
   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *  GNU Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
   * License along with BEAST; if not, write to the
   * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
   * Boston, MA  02110-1301  USA
   */
  
  package dr.inference.operators;
  
  import dr.evomodel.continuous.TreeTraitNormalDistributionModel;
  import dr.inference.distribution.DistributionLikelihood;
  import dr.inference.distribution.MultivariateDistributionLikelihood;
  import dr.inference.distribution.NormalDistributionModel;
  import dr.inference.distribution.ParametricDistributionModel;
  import dr.inference.model.*;
  import dr.inference.prior.Prior;
  import dr.inferencexml.operators.EllipticalSliceOperatorParser;
  import dr.math.MathUtils;
  import dr.math.distributions.MultivariateNormalDistribution;
  import dr.util.Attribute;
  import dr.util.Transform;
  
  import java.util.ArrayList;
  import java.util.List;
  
  /**
   * Implements a generic multivariate slice sampler for a Gaussian prior
   * <p/>
   * See: Murray, Ryan, et al.
   *
   * @author Marc A. Suchard
   */
  
  public class EllipticalSliceOperator extends SimpleMetropolizedGibbsOperator implements GibbsOperator {
  
      private final MultivariateNormalDistribution normalPrior;
      private final TreeTraitNormalDistributionModel treePrior;
  
      public EllipticalSliceOperator(Parameter variable, MultivariateNormalDistribution normalPrior, boolean drawByRow) {
          this.variable = variable;
          this.normalPrior = normalPrior;
          this.treePrior=null;
          this.drawByRow=drawByRow;
      }
  
      public EllipticalSliceOperator(Parameter variable, TreeTraitNormalDistributionModel treePrior, boolean drawByRow) {
          this.variable = variable;
          this.treePrior = treePrior;
          this.normalPrior=null;
          this.drawByRow=drawByRow;
      }
  
      public Variable<Double> getVariable() {
          return variable;
      }
  
      public double doOperation(Prior prior, Likelihood likelihood) throws OperatorFailedException {
          double logPosterior = evaluate(likelihood, prior);
          double cutoffDensity = logPosterior + MathUtils.randomLogDouble(); // TODO Gaussian contribution should stay constant, check!
          drawFromSlice(prior, likelihood, cutoffDensity);
          // No need to set variable, as SliceInterval has already done this (and recomputed posterior)
          return 0;
      }
  
      private double[] pointOnEllipse(double[] x, double[] y, double phi) {
          final int dim = x.length;
          final double cos = Math.cos(phi);
          final double sin = Math.sin(phi);
  
          double[] r = new double[dim];
          for (int i = 0; i < dim; ++i) {
              r[i] = x[i] * cos + y[i] * sin;
          }
          return r;
      }
  
      private void setVariable(double[] x) {
          if(!(variable instanceof CompoundParameter))
          {variable.setParameterValueNotifyChangedAll(0, x[0]);
          for (int i = 1; i < x.length; ++i) {
              variable.setParameterValueQuietly(i, x[i]);
          }}
          else{
              if(!drawByRow) {
                  ((CompoundParameter) variable).setParameterValueNotifyChangedAll(0, current, x[0]);
                  for (int i = 1; i < x.length; ++i) {
                      ((CompoundParameter) variable).setParameterValueQuietly(i, current, x[i]);
                  }
              }
              else{
                  for (int i = 0; i < x.length; i++) {
                      ((CompoundParameter) variable).setParameterValue(current, i, x[i]);
                  }
              }
          }
  
      }
  
      private void drawFromSlice(Prior prior, Likelihood likelihood, double cutoffDensity) {
          // Do nothing
          double[] x;
          if(!(variable instanceof CompoundParameter))
              x = variable.getParameterValues();
          else{
              if(drawByRow){
                  current=MathUtils.nextInt(((CompoundParameter) variable).getParameter(0).getDimension());
                  x=new double[((CompoundParameter) variable).getParameterCount()];
                  for (int i = 0; i <x.length ; i++) {
                      x[i]=((CompoundParameter) variable).getParameter(i).getParameterValue(current);
                  }
              }
              else {
                  current = MathUtils.nextInt(((CompoundParameter) variable).getParameterCount());
                  x=((CompoundParameter) variable).getParameter(current).getParameterValues();
              }
  
          }
          double[] nu;
          if(normalPrior!=null)
              nu = normalPrior.nextMultivariateNormal();
          else
              nu = treePrior.nextRandomFast(0);
  
          double phi = MathUtils.nextDouble() * 2.0 * Math.PI;
          Interval phiInterval = new Interval(phi - 2.0 * Math.PI, phi);
  
          boolean done = false;
          while (!done) {
              double[] xx = pointOnEllipse(x, nu, phi);
              setVariable(xx);
              double density = evaluate(likelihood, prior);
              if (density > cutoffDensity) {
                  done = true;
              } else {
                  phiInterval.adjust(phi);
                  phi = phiInterval.draw();
              }
          }
      }
  
      private class Interval {
          double lower;
          double upper;
  
          Interval(double lower, double upper) {
              this.lower = lower;
              this.upper = upper;
          }
  
          void adjust(double phi) {
              if (phi > 0) {
                  upper = phi;
              } else if (phi < 0) {
                  lower = phi;
              } else {
                  throw new RuntimeException("Shrunk to current position; bad.");
              }
          }
  
          double draw() {
              return MathUtils.nextDouble() * (upper - lower) + lower;
          }
  
      }
  
      public int getStepCount() {
          return 1;
      }
  
      /**
       * Set the path parameter for sampling from power-posterior
       */
      @Override
      public void setPathParameter(double beta) {
          // Do nothing
      }
  
      public String getOperatorName() {
          return EllipticalSliceOperatorParser.ELLIPTICAL_SLICE_SAMPLER;
      }
  
      public static void main(String[] arg) {
  
          // Define normal model
          Parameter thetaParameter = new Parameter.Default(new double[]{1.0, 0.0});  // Starting values
          MaskedParameter meanParameter = new MaskedParameter(thetaParameter,
                  new Parameter.Default(new double[]{1.0, 0.0}), true);
          TransformedParameter precParameter = new TransformedParameter(
                  new MaskedParameter(thetaParameter,
                          new Parameter.Default(new double[]{0.0, 1.0}), true),
                  new Transform.LogTransform(),
                  true
          );
  
  //        System.err.println(thetaParameter);
  //        System.err.println(meanParameter);
  //        System.err.println(precParameter);
  
          ParametricDistributionModel densityModel = new NormalDistributionModel(meanParameter, precParameter, true);
          DistributionLikelihood likelihood = new DistributionLikelihood(densityModel);
  
          // Define prior
          MultivariateNormalDistribution priorDistribution = new MultivariateNormalDistribution(
                  new double[]{0.0, 0.0},
                  new double[][]{{0.001, 0.0}, {0.0, 0.001}}
          );
          MultivariateDistributionLikelihood prior = new MultivariateDistributionLikelihood(priorDistribution);
          prior.addData(thetaParameter);
  
          // Define data
  //        likelihood.addData(new Attribute.Default<double[]>("Data", new double[] {0.0, 2.0, 4.0}));
          likelihood.addData(new Attribute.Default<double[]>("Data", new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9}));
  
          List<Likelihood> list = new ArrayList<Likelihood>();
          list.add(likelihood);
          list.add(prior);
          CompoundLikelihood posterior = new CompoundLikelihood(0, list);
          EllipticalSliceOperator sliceSampler = new EllipticalSliceOperator(thetaParameter, priorDistribution, drawByRow);
  
  
          final int dim = thetaParameter.getDimension();
          final int length = 100000;
          double[] mean = new double[dim];
          double[] variance = new double[dim];
          Parameter[] log = new Parameter[dim];
          log[0] = meanParameter;
          log[1] = precParameter;
  
          for (int i = 0; i < length; i++) {
              try {
                  sliceSampler.doOperation(null, posterior);
              } catch (OperatorFailedException e) {
                  System.err.println(e.getMessage());
              }
              for (int j = 0; j < dim; ++j) {
  