/// <summary>
		/// EP message to 'second'
		/// </summary>
		/// <param name="concat">Incoming message from 'concat'. Must be a proper distribution.  If any element is uniform, the result will be uniform.</param>
		/// <param name="first">Constant value for 'first'.</param>
		/// <param name="result">Modified to contain the outgoing message</param>
		/// <returns><paramref name="result"/></returns>
		/// <remarks><para>
		/// The outgoing message is a distribution matching the moments of 'second' as the random arguments are varied.
		/// The formula is <c>proj[p(second) sum_(concat) p(concat) factor(concat,first,second)]/p(second)</c>.
		/// </para></remarks>
		/// <exception cref="ImproperMessageException"><paramref name="concat"/> is not a proper distribution</exception>
		public static VectorGaussian SecondAverageConditional([SkipIfUniform] VectorGaussian concat, Vector first, VectorGaussian result)
		{
			// prec = concat.Precision[dim2,dim2]
			// meanTimesPrec = concat.MeanTimesPrecision[dim2] - concat.Precision[dim2,dim1]*first
			int dim1 = first.Count;
			int dim2 = result.Dimension;
			if (concat.Dimension != dim1 + dim2) throw new ArgumentException("concat.Dimension ("+concat.Dimension+") != first.Dimension ("+dim1+") + second.Dimension ("+dim2+")");
			result.Precision.SetToSubmatrix(concat.Precision, dim1, dim1);
			Matrix prec21 = new Matrix(dim2, dim1);
			prec21.SetToSubmatrix(concat.Precision, dim1, 0);
			Vector prec21first = Vector.Zero(dim2);
			prec21first.SetToProduct(prec21, first);
			result.MeanTimesPrecision.SetToSubvector(concat.MeanTimesPrecision, dim1);
			result.MeanTimesPrecision.SetToDifference(result.MeanTimesPrecision, prec21first);
			return result;
		}
		/// <summary>
		/// EP message to 'first'
		/// </summary>
		/// <param name="concat">Incoming message from 'concat'. Must be a proper distribution.  If any element is uniform, the result will be uniform.</param>
		/// <param name="second">Constant value for 'second'.</param>
		/// <param name="result">Modified to contain the outgoing message</param>
		/// <returns><paramref name="result"/></returns>
		/// <remarks><para>
		/// The outgoing message is a distribution matching the moments of 'first' as the random arguments are varied.
		/// The formula is <c>proj[p(first) sum_(concat) p(concat) factor(concat,first,second)]/p(first)</c>.
		/// </para></remarks>
		/// <exception cref="ImproperMessageException"><paramref name="concat"/> is not a proper distribution</exception>
		public static VectorGaussian FirstAverageConditional([SkipIfUniform] VectorGaussian concat, Vector second, VectorGaussian result)
		{
			// joint distribution is proportional to: exp(-0.5 [first-mean1; second-mean2]' [prec11 prec12; prec21 prec22] [first-mean1; second-mean2])
			// posterior for first is proportional to: exp(-0.5 ((first-mean1)' prec11 (first-mean1) + 2 (first-mean1)' prec12 (second-mean2)))
			// = exp(-0.5 (first' prec11 first - 2 first' prec11 mean1 + 2 first' prec12 (second-mean2)))
			// first.precision = prec11
			// first.meanTimesPrecision = prec11 mean1 - prec12 (second-mean2) = [prec11; prec12] mean - prec12 second
			int dim1 = result.Dimension;
			int dim2 = second.Count;
			if (concat.Dimension != dim1 + dim2) throw new ArgumentException("concat.Dimension ("+concat.Dimension+") != first.Dimension ("+dim1+") + second.Dimension ("+dim2+")");
			result.Precision.SetToSubmatrix(concat.Precision, 0, 0);
			Matrix prec12 = new Matrix(dim1, dim2);
			prec12.SetToSubmatrix(concat.Precision, 0, dim1);
			Vector prec12second = Vector.Zero(dim1);
			prec12second.SetToProduct(prec12, second);
			result.MeanTimesPrecision.SetToSubvector(concat.MeanTimesPrecision, 0);
			result.MeanTimesPrecision.SetToDifference(result.MeanTimesPrecision, prec12second);
			return result;
		}