//#define SVD

using System.Diagnostics;
using System.Windows.Controls;

using miew.Matrix;

namespace agree.Wpf.Util
{
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>
	/// 
	/// </summary>
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	public partial class DagLayoutPanel : Panel
	{
		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		///
		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		class DagLayoutCalc
		{
			DagLayoutPanel panel;

			public DagLayoutCalc(DagLayoutPanel panel)
			{
				this.panel = panel;
			}

#if SVD
			public Matrix B;

			public void ComputeSingularValueDecomposition(int n_reduce_dims)
			{
				Matrix A = new double[panel._dag.Count, panel._dag.Count];

				int i = 0;
				foreach (var node in panel._dag)
				{
					double[] v = new double[panel._dag.Count];

					foreach (var pnode in node.Parents)
					{
						v[pnode.Index] = 1;// panel.dag.MaxLevel - (li.level - li2.level);
					}

					v[node.Index] = 2;// panel.dag.MaxLevel;

					foreach (var cnode in node.Children)
					{
						v[cnode.Index] = 1;// panel.dag.MaxLevel - (li2.level - li.level);
					}

					A.SetColumnValues(i, v);
					i++;
				}

				Debug.Print("Starting Singular Value Decomposition for matrix A[{0},{1}]", A.RowCount, A.ColumnCount);
				Stopwatch stopwatch = Stopwatch.StartNew();

				double[] w;
				Matrix VV;
				{
					Matrix V;
					Matrix.SingularValueDecomposition(A, out w, out V);
					Debug.Print("SVD complete in {0} ms.", stopwatch.Elapsed.TotalMilliseconds);

					VV = n_reduce_dims < V.RowCount ? V.TakeKRows(n_reduce_dims) : V;
				}

				/// populate w (the singular values) to the diagonal of a new square matrix and multiply by the first n rows of V.
				B = new Matrix(w, n_reduce_dims) * VV;

				Debug.Print("Dimensionality reduction to B[{0},{1}] complete.", B.RowCount, B.ColumnCount);
			}
#endif
		};
	}
}