void Initialize(bool docAlso)
        {
            if (_view != null)
            {
                _view.IndependentColor = _doc.IndependentColor;
                _view.StrokePen        = _doc.Pen;
                _view.IndependentSize  = _doc.IndependentSymbolSize;
                _view.LineSymbolGap    = _doc.SymbolGap;
                _view.ShowEndBars      = _doc.ShowEndBars;
                _view.DoNotShiftIndependentVariable = _doc.DoNotShiftIndependentVariable;
                _view.IsHorizontalStyle             = _doc.IsHorizontalStyle;

                _tempSymbolSize = _doc.SymbolSize;
                _view.InitializeSymbolSizeList(new string[] { Serialization.GUIConversion.ToString(_tempSymbolSize) }, 0);

                _tempSkipFreq       = _doc.SkipFrequency;
                _view.SkipFrequency = Serialization.GUIConversion.ToString(_tempSkipFreq);


                // Errors
                _tempPosErrorColumn = _doc.PositiveErrorColumn;
                _tempNegErrorColumn = _doc.NegativeErrorColumn;
                string posError = null == _tempPosErrorColumn ? string.Empty : _tempPosErrorColumn.FullName;
                string negError = null == _tempNegErrorColumn ? string.Empty : _tempNegErrorColumn.FullName;
                _view.IndependentNegativeError = !object.ReferenceEquals(_tempPosErrorColumn, _tempNegErrorColumn);
                _view.PositiveError            = posError;
                _view.NegativeError            = negError;
            }
        }
        /// <summary>
        /// Creates and fills the column header vector.
        /// </summary>
        private void GetColumnHeaderVector()
        {
            // find out if there is a y property column or not
            _columnHeaderColumn = null;
            if (null != _selectedPropertyColumns && _selectedPropertyColumns.Count > 0)
            {
                // then use the first numeric column as y column that you find
                for (int i = 0; i < _selectedPropertyColumns.Count; i++)
                {
                    if (_sourceTable.PropCols[_selectedPropertyColumns[i]] is INumericColumn)
                    {
                        _columnHeaderColumn = (INumericColumn)_sourceTable.PropCols[_selectedPropertyColumns[i]];
                        break;
                    }
                }
            }

            if (null != _columnHeaderColumn)
            {
                double[] arr = new double[_participatingDataColumns.Count];
                for (int i = 0; i < _participatingDataColumns.Count; ++i)
                {
                    arr[i] = _columnHeaderColumn[_participatingDataColumns[i]];
                }
                _columnHeaderVector = VectorMath.ToVector(arr);
            }
        }
Beispiel #3
0
		/// <summary>
		/// Creates an <see cref="INumericColumnProxy"/> from a given column.
		/// </summary>
		/// <param name="column">The column.</param>
		/// <returns>An instance of <see cref="INumericColumnProxy"/>. The type of instance returned depends on the type of the provided column (e.g. whether the column is part of the document or not).</returns>
		public static INumericColumnProxy FromColumn(INumericColumn column)
		{
			if (column is IDocumentLeafNode)
				return NumericColumnProxy.FromColumn(column);
			else
				return NumericColumnProxyForStandaloneColumns.FromColumn(column);
		}
Beispiel #4
0
 public void Dispose()
 {
     _col             = null;
     _srctable        = null;
     _selectedColumns = null;
     _selectedRows    = null;
 }
Beispiel #5
0
		public static NumericColumnProxyForStandaloneColumns FromColumn(INumericColumn column)
		{
			var colAsDocumentNode = column as IDocumentLeafNode;
			if (null != colAsDocumentNode)
				throw new ArgumentException(string.Format("column does implement {0}. The actual type of column is {1}", typeof(IDocumentLeafNode), column.GetType()));

			return new NumericColumnProxyForStandaloneColumns(column); ;
		}
Beispiel #6
0
 /// <summary>
 /// Creates an <see cref="INumericColumnProxy"/> from a given column.
 /// </summary>
 /// <param name="column">The column.</param>
 /// <returns>An instance of <see cref="INumericColumnProxy"/>. The type of instance returned depends on the type of the provided column (e.g. whether the column is part of the document or not).</returns>
 public static INumericColumnProxy FromColumn(INumericColumn column)
 {
     if (column is IDocumentLeafNode)
     {
         return(NumericColumnProxy.FromColumn(column));
     }
     else
     {
         return(NumericColumnProxyForStandaloneColumns.FromColumn(column));
     }
 }
Beispiel #7
0
        public FitElement(INumericColumn xColumn, INumericColumn yColumn, int start, int count)
        {
            _independentVariables    = new NumericColumnProxy[1];
            _independentVariables[0] = new NumericColumnProxy(xColumn);

            _dependentVariables    = new NumericColumnProxy[1];
            _dependentVariables[0] = new NumericColumnProxy(yColumn);

            _errorEvaluation    = new IVarianceScaling[1];
            _errorEvaluation[0] = new ConstantVarianceScaling();

            _rangeOfRows = PositiveIntegerRange.NewFromFirstAndCount(start, count);
        }
Beispiel #8
0
        public static NumericColumnProxyForStandaloneColumns FromColumn(INumericColumn column)
        {
            var colAsDocumentNode = column as IDocumentLeafNode;

            if (null != colAsDocumentNode)
            {
                throw new ArgumentException(string.Format("column does implement {0}. The actual type of column is {1}", typeof(IDocumentLeafNode), column.GetType()));
            }

            return(new NumericColumnProxyForStandaloneColumns(column));

            ;
        }
Beispiel #9
0
        public static NumericColumnProxy FromColumn(INumericColumn column)
        {
            if (null == column)
            {
                throw new ArgumentNullException("column");
            }
            var colAsDocumentNode = column as IDocumentLeafNode;

            if (null == colAsDocumentNode)
            {
                throw new ArgumentException(string.Format("column does not implement {0}. The actual type of column is {1}", typeof(IDocumentLeafNode), column.GetType()));
            }

            return(new NumericColumnProxy(colAsDocumentNode));
        }
Beispiel #10
0
        /// <summary>
        /// Sets the ith dependent variable column. The column is hold by a reference aware of disposed events, so that it can be null if retrieved afterwards.
        /// </summary>
        /// <param name="i">Index.</param>
        /// <param name="col">Dependent variable column to set.</param>
        public void SetDependentVariable(int i, INumericColumn col)
        {
            this._dependentVariables[i] = new NumericColumnProxy(col);

            if (col != null)
            {
                if (this._errorEvaluation[i] == null)
                {
                    this._errorEvaluation[i] = new ConstantVarianceScaling();
                }
            }
            else
            {
                this._errorEvaluation[i] = null;
            }
        }
        /// <summary>
        /// This returns a read-only vector of a <see cref="INumericColumn" />, but the data are copyied before. Thus, if you change the data
        /// into the numeric column, the data of the returned vector is not influenced.
        /// </summary>
        /// <param name="col">The column to wrap.</param>
        /// <returns>A read-only vector which contains data copied from the numeric column.</returns>
        public static IROVector ToROVectorCopy(DataColumn col)
        {
            if (!(col is INumericColumn))
            {
                throw new ArgumentException("Argument col can not be wrapped to a vector because it is not a numeric column");
            }

            INumericColumn ncol = col as INumericColumn;

            double[] vec = new double[col.Count];
            for (int i = col.Count - 1; i >= 0; i--)
            {
                vec[i] = ncol[i];
            }

            return(VectorMath.ToROVector(vec));
        }
        void EhView_ChooseNegativeError(object sender, EventArgs e)
        {
            SingleColumnChoice choice = new SingleColumnChoice();

            choice.SelectedColumn = _tempNegErrorColumn != null ? _tempNegErrorColumn as DataColumn: _doc.NegativeErrorColumn as DataColumn;
            object choiceAsObject = choice;

            if (Current.Gui.ShowDialog(ref choiceAsObject, "Select negative error column"))
            {
                choice = (SingleColumnChoice)choiceAsObject;

                if (choice.SelectedColumn is INumericColumn)
                {
                    _tempNegErrorColumn = (INumericColumn)choice.SelectedColumn;
                    _view.NegativeError = _tempNegErrorColumn.FullName;
                }
            }
        }
        /// <summary>
        /// Creates and fills the row header vector.
        /// </summary>
        private void GetRowHeaderVector()
        {
            // find out if there is a xcolumn or not
            int        group = _sourceTable.DataColumns.GetColumnGroup(_participatingDataColumns[0]);
            DataColumn xcol  = _sourceTable.DataColumns.FindXColumnOfGroup(group);

            _rowHeaderColumn = xcol as INumericColumn;

            if (null != _rowHeaderColumn)
            {
                double[] arr = new double[_participatingDataRows.Count];
                for (int i = 0; i < _participatingDataRows.Count; ++i)
                {
                    arr[i] = _rowHeaderColumn[_participatingDataRows[i]];
                }
                _rowHeaderVector = VectorMath.ToVector(arr);
            }
        }
Beispiel #14
0
        public IAscendingIntegerCollection CalculateValidNumericRows()
        {
            // also obtain the valid rows both of the independent and of the dependent variables
            INumericColumn[] cols = new INumericColumn[_independentVariables.Length + _dependentVariables.Length];
            int i;
            AscendingIntegerCollection selectedCols = new AscendingIntegerCollection();
            // note: for a fitting session all independent variables columns must
            // be not null
            int maxLength = int.MaxValue;

            for (i = 0; i < _independentVariables.Length; i++)
            {
                cols[i] = _independentVariables[i].Document;
                selectedCols.Add(i);
                if (cols[i] is IDefinedCount)
                {
                    maxLength = Math.Min(maxLength, ((IDefinedCount)cols[i]).Count);
                }
            }

            // note: for a fitting session some of the dependent variables can be null
            for (int j = 0; j < _dependentVariables.Length; ++j, ++i)
            {
                if (_dependentVariables[j] != null && _dependentVariables[j].Document != null)
                {
                    cols[i] = _dependentVariables[j].Document;
                    selectedCols.Add(i);
                    if (cols[i] is IDefinedCount)
                    {
                        maxLength = Math.Min(maxLength, ((IDefinedCount)cols[i]).Count);
                    }
                }
            }
            if (maxLength == int.MaxValue)
            {
                maxLength = 0;
            }

            maxLength = Math.Min(maxLength, this._rangeOfRows.End);

            bool[] arr = Altaxo.Calc.LinearAlgebra.DataTableWrapper.GetValidNumericRows(cols, selectedCols, maxLength);
            return(Altaxo.Calc.LinearAlgebra.DataTableWrapper.GetCollectionOfValidNumericRows(arr));
        }
Beispiel #15
0
        /// <summary>
        /// Determines which of the rows of a set of columns is truly numeric, i.e. all columns in this row contains a value, which is not double.NaN.
        /// </summary>
        /// <param name="table">Array of numeric columns.</param>
        /// <param name="selectedCols">The indizes of the columns in question into the collection.</param>
        /// <param name="rowCount">The minimum row count of all the selected columns.</param>
        /// <returns>A boolean array. If an element of the array is true at a given index, that row contains valid numeric values in all columns.</returns>
        public static bool[] GetValidNumericRows(INumericColumn[] table, IAscendingIntegerCollection selectedCols, int rowCount)
        {
            // determine the number of valid rows
            bool[] rowValid = new bool[rowCount];
            for (int i = 0; i < rowCount; i++)
            {
                rowValid[i] = true;
            }

            for (int i = 0; i < selectedCols.Count; i++)
            {
                INumericColumn col = (INumericColumn)table[selectedCols[i]];
                for (int j = 0; j < rowCount; j++)
                {
                    if (double.IsNaN(col[j]))
                    {
                        rowValid[j] = false;
                    }
                }
            }
            return(rowValid);
        }
Beispiel #16
0
 public bool MoveNext()
 {
     if (null != _col)
     {
         if (_nRow < _selectedRows.Count - 1)
         {
             ++_nRow;
             return(true);
         }
         else
         {
             ++_nCol;
             if (_nCol < _selectedColumns.Count)
             {
                 _nRow = 0;
                 _col  = (INumericColumn)_srctable.DataColumns[_selectedColumns[_nCol]];
                 return(true);
             }
             else
             {
                 _col = null;
                 return(false);
             }
         }
     }
     else // _col is null
     {
         if (_nCol < 0)
         {
             _nCol = 0;
             _nRow = 0;
             _col  = (INumericColumn)_srctable.DataColumns[_selectedColumns[_nCol]];
             return(true);
         }
     }
     return(false);
 }
Beispiel #17
0
 /// <summary>
 /// Sets the ith dependent variable column. The column is hold by a reference aware of disposed events, so that it can be null if retrieved afterwards.
 /// </summary>
 /// <param name="i">Index.</param>
 /// <param name="col">Dependent variable column to set.</param>
 public void SetDependentVariable(int i, INumericColumn col)
 {
   this._dependentVariables[i] = new NumericColumnProxy(col);
   
   if(col!=null)
   {
     if(this._errorEvaluation[i]==null)
       this._errorEvaluation[i] = new ConstantVarianceScaling();
   }
   else
   {
     this._errorEvaluation[i] = null;
   }
 }
Beispiel #18
0
 /// <summary>
 /// Sets the ith independent variable column. The column is hold by a reference aware of disposed events, so that it can be null if retrieved afterwards.
 /// </summary>
 /// <param name="i">Index.</param>
 /// <param name="col">Independent variable column to set.</param>
 public void SetIndependentVariable(int i, INumericColumn col)
 {
   this._independentVariables[i] = new NumericColumnProxy(col);
   
   this.OnChanged();
 }
Beispiel #19
0
    public FitElement(INumericColumn xColumn, INumericColumn yColumn, int start, int count)
    {
      _independentVariables = new NumericColumnProxy[1];
      _independentVariables[0] = new NumericColumnProxy(xColumn);

      _dependentVariables = new NumericColumnProxy[1];
      _dependentVariables[0] = new NumericColumnProxy(yColumn);

      _errorEvaluation = new IVarianceScaling[1];
      _errorEvaluation[0] = new ConstantVarianceScaling();

      _rangeOfRows = PositiveIntegerRange.NewFromFirstAndCount(start,count);

    }
 /// <summary>
 /// Constructor by giving a numeric column.
 /// </summary>
 /// <param name="column">The numeric column to hold.</param>
 public NumericColumnProxy(INumericColumn column)
   : base(column)
 {
 }
Beispiel #21
0
 /// <summary>
 /// This returns a read-only vector of a <see cref="INumericColumn" />
 /// </summary>
 /// <param name="col">The column to wrap as a IVector.</param>
 /// <param name="nStart">The starting index of the wrapped column.</param>
 /// <param name="nRows">The number of rows to use for the vector.</param>
 /// <returns>An IVector wrapping the <see cref="INumericColumn" />.</returns>
 public static IROVector <double> ToROVector(this INumericColumn col, int nStart, int nRows)
 {
     return(new NumericColumnToROVectorWrapper(col, nStart, nRows));
 }
Beispiel #22
0
        public static string TestAgainstStandardDistribution(IList <double> sortedListOfData, LinearBinning binning, INumericColumn colBinPosition, INumericColumn colBinCounts)
        {
            var stb = new StringBuilder();

            var stat = new Calc.Regression.QuickStatistics();

            foreach (var v in sortedListOfData)
            {
                stat.Add(v);
            }

            // Test the probability against the normal distribution

            // First make a fit of the normal distribution to get mu and sigma
            // guess of mu
            double guessedMu    = stat.Mean;
            double guessedSigma = stat.SampleStandardDeviation;

            /*
             *                        Altaxo.Calc.Regression.Nonlinear.SimpleNonlinearFit fit = new Altaxo.Calc.Regression.Nonlinear.SimpleNonlinearFit(
             *                                delegate (double[] indep, double[] p, double[] res)
             *                                {
             *                                        // 3 Parameter:  mu and sigma
             *                                        res[0] = Calc.Probability.NormalDistribution.PDF(indep[0], p[0], p[1]);
             *                                },
             *                                new double[] { guessedMu, guessedSigma },
             *                                colBinPosition,
             *                                colProbabilityDensity,
             *                                0, // Start (first point)
             *                                binning.Count // point count
             *                                );
             *
             *                        fit.Fit();
             *
             *                        guessedMu = fit.GetParameter(0);
             *                        guessedSigma = fit.GetParameter(1);
             *
             */

            // Test hypothesis that we have a normal distribution

            double chiSquare = 0;

            int degreesOfFreedom = binning.NumberOfBins - 1 - 2; // -2 because we lost two degrees of freedom in the previous fitting

            for (int nBinIndex = 0; nBinIndex < binning.NumberOfBins; ++nBinIndex)
            {
                var    bin        = binning.Bins[nBinIndex];
                double lowerBound = bin.LowerBound;
                double upperBound = bin.UpperBound;

                var    probability = Calc.Probability.NormalDistribution.CDF(upperBound, guessedMu, guessedSigma) - Calc.Probability.NormalDistribution.CDF(lowerBound, guessedMu, guessedSigma);
                double n0          = probability * sortedListOfData.Count;

                chiSquare += RMath.Pow2(n0 - colBinCounts[nBinIndex]) / n0;
            }

            double chiSquareThreshold = Calc.Probability.ChiSquareDistribution.Quantile(0.95, degreesOfFreedom);

            if (chiSquare <= chiSquareThreshold)
            {
                stb.AppendFormat("The hypothesis that this is a normal distribution with mu={0} and sigma={1} can not be rejected. ChiSquare ({2}) is less than ChiSquare needed to reject hypothesis ({3})", guessedMu, guessedSigma, chiSquare, chiSquareThreshold);
            }
            else
            {
                stb.AppendFormat("The hypothesis that this is a normal distribution with mu={0} and sigma={1} must be rejected with a confidence of {2}%. ChiSquare ({3}) is greater than ChiSquare needed to reject hypothesis ({4})", guessedMu, guessedSigma, 100 * Altaxo.Calc.Probability.ChiSquareDistribution.CDF(chiSquare, degreesOfFreedom), chiSquare, chiSquareThreshold);
            }

            return(stb.ToString());
        }
    void Initialize(bool docAlso)
    {
      if (_view != null)
      {
        _view.IndependentColor = _doc.IndependentColor;
        _view.StrokePen = _doc.Pen;
        _view.IndependentSize = _doc.IndependentSymbolSize;
        _view.LineSymbolGap = _doc.SymbolGap;
        _view.ShowEndBars = _doc.ShowEndBars;
        _view.DoNotShiftIndependentVariable = _doc.DoNotShiftIndependentVariable;
        _view.IsHorizontalStyle = _doc.IsHorizontalStyle;

        _tempSymbolSize = _doc.SymbolSize;
        _view.InitializeSymbolSizeList(new string[] { Serialization.GUIConversion.ToString(_tempSymbolSize) }, 0);

        _tempSkipFreq = _doc.SkipFrequency;
        _view.SkipFrequency = Serialization.GUIConversion.ToString(_tempSkipFreq);


        // Errors
        _tempPosErrorColumn = _doc.PositiveErrorColumn;
        _tempNegErrorColumn = _doc.NegativeErrorColumn;
        string posError = null == _tempPosErrorColumn ? string.Empty : _tempPosErrorColumn.FullName;
        string negError = null == _tempNegErrorColumn ? string.Empty : _tempNegErrorColumn.FullName;
        _view.IndependentNegativeError = !object.ReferenceEquals(_tempPosErrorColumn, _tempNegErrorColumn);
        _view.PositiveError = posError;
        _view.NegativeError = negError;
      }
    }
Beispiel #24
0
		/// <summary>
		/// Constructor by giving a numeric column.
		/// </summary>
		/// <param name="column">The numeric column to hold.</param>
		protected NumericColumnProxyForStandaloneColumns(INumericColumn column)
		{
			_column = column;
		}
		/// <summary>
		/// Creates and fills the column header vector.
		/// </summary>
		private void GetColumnHeaderVector()
		{
			// find out if there is a y property column or not
			_columnHeaderColumn = null;
			if (null != _selectedPropertyColumns && _selectedPropertyColumns.Count > 0)
			{
				// then use the first numeric column as y column that you find
				for (int i = 0; i < _selectedPropertyColumns.Count; i++)
				{
					if (_sourceTable.PropCols[_selectedPropertyColumns[i]] is INumericColumn)
					{
						_columnHeaderColumn = (INumericColumn)_sourceTable.PropCols[_selectedPropertyColumns[i]];
						break;
					}
				}
			}

			if (null != _columnHeaderColumn)
			{
				double[] arr = new double[_participatingDataColumns.Count];
				for (int i = 0; i < _participatingDataColumns.Count; ++i)
					arr[i] = _columnHeaderColumn[_participatingDataColumns[i]];
				_columnHeaderVector = VectorMath.ToVector(arr);
			}
		}
Beispiel #26
0
        protected void PaintXErrorBars(System.Drawing.Graphics g, IPlotArea layer, Altaxo.Graph.Gdi.Plot.Data.Processed2DPlotData pdata)
        {
            // Plot error bars for the independent variable (x)
            PlotRangeList rangeList = pdata.RangeList;

            PointF[]       ptArray   = pdata.PlotPointsInAbsoluteLayerCoordinates;
            INumericColumn posErrCol = _positiveErrorColumn.Document;
            INumericColumn negErrCol = _negativeErrorColumn.Document;

            if (posErrCol == null && negErrCol == null)
            {
                return; // nothing to do if both error columns are null
            }
            System.Drawing.Drawing2D.GraphicsPath errorBarPath = new System.Drawing.Drawing2D.GraphicsPath();

            Region oldClippingRegion = g.Clip;
            Region newClip           = (Region)oldClippingRegion.Clone();

            foreach (PlotRange r in rangeList)
            {
                int lower  = r.LowerBound;
                int upper  = r.UpperBound;
                int offset = r.OffsetToOriginal;
                for (int j = lower; j < upper; j++)
                {
                    AltaxoVariant x  = pdata.GetXPhysical(j + offset);
                    Logical3D     lm = layer.GetLogical3D(pdata, j + offset);
                    lm.RX += _cachedLogicalShiftOfIndependent;
                    if (lm.IsNaN)
                    {
                        continue;
                    }

                    Logical3D lh      = lm;
                    Logical3D ll      = lm;
                    bool      lhvalid = false;
                    bool      llvalid = false;
                    if (posErrCol != null)
                    {
                        lh.RX   = layer.XAxis.PhysicalVariantToNormal(x + Math.Abs(posErrCol[j + offset]));
                        lhvalid = !lh.IsNaN;
                    }
                    if (negErrCol != null)
                    {
                        ll.RX   = layer.XAxis.PhysicalVariantToNormal(x - Math.Abs(negErrCol[j + offset]));
                        llvalid = !ll.IsNaN;
                    }
                    if (!(lhvalid || llvalid))
                    {
                        continue; // nothing to do for this point if both pos and neg logical point are invalid.
                    }
                    // now paint the error bar
                    if (_symbolGap) // if symbol gap, then clip the painting, exclude a rectangle of size symbolSize x symbolSize
                    {
                        double xlm, ylm;
                        layer.CoordinateSystem.LogicalToLayerCoordinates(lm, out xlm, out ylm);
                        newClip.Union(oldClippingRegion);
                        newClip.Exclude(new RectangleF((float)(xlm - _symbolSize / 2), (float)(ylm - _symbolSize / 2), _symbolSize, _symbolSize));
                        g.Clip = newClip;
                    }

                    if (lhvalid && llvalid)
                    {
                        errorBarPath.Reset();
                        layer.CoordinateSystem.GetIsoline(errorBarPath, ll, lm);
                        layer.CoordinateSystem.GetIsoline(errorBarPath, lm, lh);
                        g.DrawPath(_strokePen, errorBarPath);
                    }
                    else if (llvalid)
                    {
                        layer.CoordinateSystem.DrawIsoline(g, _strokePen, ll, lm);
                    }
                    else if (lhvalid)
                    {
                        layer.CoordinateSystem.DrawIsoline(g, _strokePen, lm, lh);
                    }


                    // now the end bars
                    if (_showEndBars)
                    {
                        if (lhvalid)
                        {
                            PointF outDir;
                            layer.CoordinateSystem.GetNormalizedDirection(lm, lh, 1, new Logical3D(0, 1), out outDir);
                            outDir.X *= _symbolSize / 2;
                            outDir.Y *= _symbolSize / 2;
                            double xlay, ylay;
                            layer.CoordinateSystem.LogicalToLayerCoordinates(lh, out xlay, out ylay);
                            // Draw a line from x,y to
                            g.DrawLine(_strokePen, (float)(xlay - outDir.X), (float)(ylay - outDir.Y), (float)(xlay + outDir.X), (float)(ylay + outDir.Y));
                        }

                        if (llvalid)
                        {
                            PointF outDir;
                            layer.CoordinateSystem.GetNormalizedDirection(lm, ll, 1, new Logical3D(0, 1), out outDir);
                            outDir.X *= _symbolSize / 2;
                            outDir.Y *= _symbolSize / 2;
                            double xlay, ylay;
                            layer.CoordinateSystem.LogicalToLayerCoordinates(ll, out xlay, out ylay);
                            // Draw a line from x,y to
                            g.DrawLine(_strokePen, (float)(xlay - outDir.X), (float)(ylay - outDir.Y), (float)(xlay + outDir.X), (float)(ylay + outDir.Y));
                        }
                    }
                }
            }

            g.Clip = oldClippingRegion;
        }
 void EhView_ClearNegativeError(object sender, EventArgs e)
 {
     _tempNegErrorColumn = null;
     _view.NegativeError = string.Empty;
 }
		/// <summary>
		/// Creates and fills the row header vector.
		/// </summary>
		private void GetRowHeaderVector()
		{
			// find out if there is a xcolumn or not
			int group = _sourceTable.DataColumns.GetColumnGroup(_participatingDataColumns[0]);
			DataColumn xcol = _sourceTable.DataColumns.FindXColumnOfGroup(group);
			_rowHeaderColumn = xcol as INumericColumn;

			if (null != _rowHeaderColumn)
			{
				double[] arr = new double[_participatingDataRows.Count];
				for (int i = 0; i < _participatingDataRows.Count; ++i)
					arr[i] = _rowHeaderColumn[_participatingDataRows[i]];
				_rowHeaderVector = VectorMath.ToVector(arr);
			}
		}
 void EhView_ClearPositiveError(object sender, EventArgs e)
 {
     _tempPosErrorColumn = null;
     _view.PositiveError = string.Empty;
 }
Beispiel #30
0
    public IAscendingIntegerCollection CalculateValidNumericRows()
    {
      // also obtain the valid rows both of the independent and of the dependent variables
      INumericColumn[] cols = new INumericColumn[_independentVariables.Length + _dependentVariables.Length];
      int i;
      AscendingIntegerCollection selectedCols = new AscendingIntegerCollection();
      // note: for a fitting session all independent variables columns must
      // be not null
      int maxLength = int.MaxValue;
      for (i = 0; i < _independentVariables.Length; i++)
      {
        cols[i] = _independentVariables[i].Document;
        selectedCols.Add(i);
        if (cols[i] is IDefinedCount)
          maxLength = Math.Min(maxLength, ((IDefinedCount)cols[i]).Count);
      }

      // note: for a fitting session some of the dependent variables can be null
      for (int j = 0; j < _dependentVariables.Length; ++j, ++i)
      {
        if (_dependentVariables[j] != null && _dependentVariables[j].Document != null)
        {
          cols[i] = _dependentVariables[j].Document;
          selectedCols.Add(i);
          if (cols[i] is IDefinedCount)
            maxLength = Math.Min(maxLength, ((IDefinedCount)cols[i]).Count);
        }
      }
      if (maxLength == int.MaxValue)
        maxLength = 0;

      maxLength = Math.Min(maxLength, this._rangeOfRows.End);

      bool[] arr = Altaxo.Calc.LinearAlgebra.DataTableWrapper.GetValidNumericRows(cols, selectedCols, maxLength);
      return Altaxo.Calc.LinearAlgebra.DataTableWrapper.GetCollectionOfValidNumericRows(arr);

    }
Beispiel #31
0
		public static NumericColumnProxy FromColumn(INumericColumn column)
		{
			if (null == column)
				throw new ArgumentNullException("column");
			var colAsDocumentNode = column as IDocumentLeafNode;
			if (null == colAsDocumentNode)
				throw new ArgumentException(string.Format("column does not implement {0}. The actual type of column is {1}", typeof(IDocumentLeafNode), column.GetType()));

			return new NumericColumnProxy(colAsDocumentNode);
		}
 /// <summary>
 /// Constructor by giving a numeric column.
 /// </summary>
 /// <param name="column">The numeric column to hold.</param>
 public NumericColumnProxy(INumericColumn column)
     : base(column)
 {
 }
 /// <summary>
 /// This returns a vertical oriented, readonly matrix of a <see cref="DoubleColumn" />
 /// </summary>
 /// <param name="col">The column to wrap as a IVector.</param>
 /// <param name="nRows">The number of rows to use for the vector.</param>
 /// <returns>An vertical oriented <see cref="IROMatrix" /> wrapping the <see cref="DoubleColumn" />.</returns>
 public static IROMatrix ToVertROMatrix(INumericColumn col, int nRows)
 {
     return(new NumericColumnToROVertMatrixWrapper((INumericColumn)col, nRows));
 }
Beispiel #34
0
 public void Reset()
 {
     _col  = null;
     _nCol = -1;
     _nRow = 0;
 }
Beispiel #35
0
		/// <summary>
		/// Gets the fractional index for merging of two tables.
		/// </summary>
		/// <param name="masterColumn">X-column of the master table.</param>
		/// <param name="slaveColumn">X-column of the slave table.</param>
		/// <returns>Array of fractional indices. Each item points into the slaveTable to the value that should be included in the master column at the item's index.</returns>
		public static DoubleColumn GetFractionalIndex(INumericColumn masterColumn, INumericColumn slaveColumn)
		{
			if (!(masterColumn.Count.HasValue))
				throw new ArgumentException("masterColumn has no defined count");
			if (!(slaveColumn.Count.HasValue))
				throw new ArgumentException("slaveColumn has no defined count");

			int masterCount = masterColumn.Count.Value;
			int slaveCount = slaveColumn.Count.Value;

			var result = new DoubleColumn();
			var dict = new SortedDictionary<double, int>();
			for (int i = slaveCount - 1; i >= 0; i--)
				dict[slaveColumn[i]] = i;

			var sortedSlaveValues = dict.Keys.ToArray();
			var sortedSlaveIndices = dict.Values.ToArray();

			for (int masterIdx = 0; masterIdx < masterCount; masterIdx++)
			{
				var masterValue = masterColumn[masterIdx];
				if (double.IsNaN(masterValue))
				{
					result[masterIdx] = double.NaN;
					continue;
				}
				int dictIdx = Array.BinarySearch(sortedSlaveValues, masterValue);

				if (dictIdx >= 0)
				{
					result[masterIdx] = sortedSlaveIndices[dictIdx];
					continue;
				}

				// dictIdx was negative, we have to take the complement
				dictIdx = ~dictIdx;
				if (dictIdx >= sortedSlaveIndices.Length)
				{
					result[masterIdx] = double.NaN;
					continue;
				}
				else if (dictIdx == 0)
				{
					result[masterIdx] = double.NaN;
					continue;
				}
				else
				{
					int firstSlaveIdx = sortedSlaveIndices[dictIdx - 1];
					int secondSlaveIdx = sortedSlaveIndices[dictIdx];
					double firstSlaveValue = sortedSlaveValues[dictIdx - 1];
					double secondSlaveValue = sortedSlaveValues[dictIdx];

					double diff = secondSlaveValue - firstSlaveValue;

					if (diff == 0)
					{
						result[masterIdx] = firstSlaveIdx;
						continue;
					}
					else
					{
						result[masterIdx] = firstSlaveIdx + (secondSlaveIdx - firstSlaveIdx) * (masterValue - firstSlaveValue) / diff;
						continue;
					}
				}
			}

			return result;
		}
Beispiel #36
0
 /// <summary>
 /// This returns a vertical oriented, readonly matrix of a <see cref="DoubleColumn" />
 /// </summary>
 /// <param name="col">The column to wrap as a IVector.</param>
 /// <param name="nRows">The number of rows to use for the vector.</param>
 /// <returns>An vertical oriented <see cref="IROMatrix{Double}" /> wrapping the <see cref="DoubleColumn" />.</returns>
 public static IROMatrix <double> ToVertROMatrix(this INumericColumn col, int nRows)
 {
     return(new NumericColumnToROVertMatrixWrapper(col, nRows));
 }
Beispiel #37
0
        protected override void OnPaint(PaintEventArgs e)
        {
            StringFormat leftJustified = new StringFormat(StringFormat.GenericTypographic);

            //      stringFormat.Alignment = StringAlignment.Center;
            leftJustified.LineAlignment = StringAlignment.Center;

            StringFormat rightJustified = new StringFormat(StringFormat.GenericTypographic);

            rightJustified.Alignment     = StringAlignment.Far;
            rightJustified.LineAlignment = StringAlignment.Center;

            StringFormat bothCentered = new StringFormat(StringFormat.GenericTypographic);

            bothCentered.Alignment     = StringAlignment.Center;
            bothCentered.LineAlignment = StringAlignment.Center;

            _fitBoxLocation = new Point(this.ClientSize.Width / 3, 0);
            _fitBoxSize     = new Size(this.ClientSize.Width / 3, _totalSlots * _slotHeight);


            e.Graphics.DrawRectangle(_pen, _fitBoxLocation.X, _fitBoxLocation.Y, _fitBoxSize.Width, _fitBoxSize.Height - 1);


            int currentY = 0;

            // Draw the independent variables

            for (int i = 0; i < _numberOfX; i++)
            {
                Point triangleStart = new Point(_fitBoxLocation.X, currentY + (1 * _slotHeight) / 4);
                Point triangleMidst = new Point(_fitBoxLocation.X + _slotHeight / 2, currentY + _slotHeight / 2);
                Point triangleEnd   = new Point(_fitBoxLocation.X, currentY + (3 * _slotHeight) / 4);

                e.Graphics.DrawLine(_pen, triangleStart, triangleMidst);
                e.Graphics.DrawLine(_pen, triangleMidst, triangleEnd);
                if (_fitElement.FitFunction != null)
                {
                    e.Graphics.DrawString(
                        _fitElement.FitFunction.IndependentVariableName(i),
                        System.Windows.Forms.SystemInformation.MenuFont,
                        System.Drawing.Brushes.Black,
                        new Rectangle(_fitBoxLocation.X + _slotHeight / 2 + 2, currentY, _fitBoxSize.Width - 1 - _slotHeight / 2, _slotHeight),
                        leftJustified
                        );
                }
                currentY += _slotHeight;
            }



            // now draw the dependent variables
            _DependentVariablesY = (_totalSlots - _numberOfY) * _slotHeight;
            currentY             = _DependentVariablesY;

            _errorFunctionWidth = (6 * _slotHeight) / 4;
            _errorFunctionX     = _fitBoxLocation.X - _errorFunctionWidth / 2;

            for (int i = 0; i < _numberOfY; i++)
            {
                Rectangle errorFuncRect = new Rectangle(
                    _errorFunctionX,
                    currentY,
                    _errorFunctionWidth,
                    _slotHeight - 1);


                e.Graphics.FillRectangle(Brushes.WhiteSmoke, errorFuncRect);
                e.Graphics.DrawRectangle(_pen, errorFuncRect);
                if (_fitElement.ErrorEvaluation(i) != null)
                {
                    e.Graphics.DrawString(_fitElement.ErrorEvaluation(i).ShortName,
                                          System.Windows.Forms.SystemInformation.MenuFont,
                                          System.Drawing.Brushes.Black,
                                          errorFuncRect,
                                          bothCentered);
                }



                if (_fitElement.FitFunction != null)
                {
                    e.Graphics.DrawString(
                        _fitElement.FitFunction.DependentVariableName(i),
                        System.Windows.Forms.SystemInformation.MenuFont,
                        System.Drawing.Brushes.Black,
                        new Rectangle(_errorFunctionX + _errorFunctionWidth + (1 * _slotHeight) / 4, currentY, _fitBoxSize.Width - 1 - _slotHeight / 2, _slotHeight),
                        leftJustified
                        );
                }

                currentY += _slotHeight;
            }


            // now draw the internal parameters
            currentY = 0;

            for (int i = 0; i < _numberOfParameter; i++)
            {
                e.Graphics.DrawEllipse(_pen, _fitBoxLocation.X + _fitBoxSize.Width - _slotHeight / 4, currentY + _slotHeight / 4, _slotHeight / 2, _slotHeight / 2);
                if (_fitElement.FitFunction != null)
                {
                    e.Graphics.DrawString(
                        _fitElement.FitFunction.ParameterName(i),
                        System.Windows.Forms.SystemInformation.MenuFont,
                        System.Drawing.Brushes.Black,
                        new Rectangle(_fitBoxLocation.X, currentY, _fitBoxSize.Width - 1 - _slotHeight / 4, _slotHeight),
                        rightJustified
                        );
                }

                currentY += _slotHeight;
            }


            // now draw the external parameters
            currentY = 0;

            _externalParametersX     = _fitBoxLocation.X + _fitBoxSize.Width + _slotHeight / 2;
            _externalParametersWidth = this.ClientSize.Width - _externalParametersX;
            for (int i = 0; i < _numberOfParameter; i++)
            {
                Rectangle rect = new Rectangle(_externalParametersX, currentY, _externalParametersWidth, _slotHeight);

                System.Windows.Forms.ControlPaint.DrawBorder3D(e.Graphics,
                                                               rect.X - 2, rect.Y, rect.Width + 2, rect.Height,
                                                               System.Windows.Forms.Border3DStyle.Etched,
                                                               System.Windows.Forms.Border3DSide.All);

                e.Graphics.DrawString(
                    _fitElement.ParameterName(i),
                    System.Windows.Forms.SystemInformation.MenuFont,
                    System.Drawing.Brushes.Black,
                    new Rectangle(_externalParametersX, currentY, _externalParametersWidth, _slotHeight),
                    leftJustified
                    );

                currentY += _slotHeight;
            }

            // Draw the names of the independent columns
            currentY    = 0;
            _VariablesX = 0;
            _IndependentVariablesWidth = _fitBoxLocation.X - _slotHeight / 4;
            for (int i = 0; i < _numberOfX; i++)
            {
                Rectangle rect = new Rectangle(0, currentY, _IndependentVariablesWidth, _slotHeight);
                System.Windows.Forms.ControlPaint.DrawBorder3D(e.Graphics,
                                                               rect.X, rect.Y, rect.Width + 2, rect.Height,
                                                               System.Windows.Forms.Border3DStyle.Etched,
                                                               System.Windows.Forms.Border3DSide.All);

                INumericColumn col = _fitElement.IndependentVariables(i);
                if (col != null)
                {
                    string name = col.FullName;

                    e.Graphics.DrawString(
                        name,
                        System.Windows.Forms.SystemInformation.MenuFont,
                        System.Drawing.Brushes.Black,
                        rect,
                        rightJustified
                        );
                }
                currentY += _slotHeight;
            }

            {
                // draw the plot range
                var       plotRange   = _fitElement.GetRowRange();
                string    rangestring = "Range: " + plotRange.Start.ToString() + " to " + (plotRange.IsInfinite ? "infinity" : plotRange.Last.ToString());
                Rectangle rect        = new Rectangle(0, currentY, _IndependentVariablesWidth, _slotHeight);
                System.Windows.Forms.ControlPaint.DrawBorder3D(e.Graphics,
                                                               rect.X, rect.Y, rect.Width + 2, rect.Height,
                                                               System.Windows.Forms.Border3DStyle.Etched,
                                                               System.Windows.Forms.Border3DSide.All);
                e.Graphics.DrawString(
                    rangestring,
                    System.Windows.Forms.SystemInformation.MenuFont,
                    System.Drawing.Brushes.Black,
                    rect,
                    rightJustified
                    );
            }
            // Draw the names of the dependent columns
            currentY = _DependentVariablesY;
            _DependentVariablesWidth = _errorFunctionX - (2 * _slotHeight) / 8;
            for (int i = 0; i < _numberOfY; i++)
            {
                Rectangle rect = new Rectangle(0, currentY, _DependentVariablesWidth, _slotHeight);

                System.Windows.Forms.ControlPaint.DrawBorder3D(e.Graphics,
                                                               rect.X, rect.Y, rect.Width + 2, rect.Height,
                                                               System.Windows.Forms.Border3DStyle.Etched,
                                                               System.Windows.Forms.Border3DSide.All);

                INumericColumn col = _fitElement.DependentVariables(i);
                if (col != null)
                {
                    string name = col.FullName;

                    e.Graphics.DrawString(
                        name,
                        System.Windows.Forms.SystemInformation.MenuFont,
                        System.Drawing.Brushes.Black,
                        rect,
                        rightJustified
                        );
                }
                currentY += _slotHeight;
            }

            string fitFuncName = null;

            if (_fitElement.FitFunction == null)
            {
                fitFuncName = "?";
            }
            else if (_fitElement.FitFunction is Altaxo.Scripting.IFitFunctionScriptText)
            {
                fitFuncName = (_fitElement.FitFunction as Altaxo.Scripting.IFitFunctionScriptText).FitFunctionName;
            }
            else
            {
                fitFuncName = _fitElement.FitFunction.ToString();
            }

            Rectangle fitFuncBox = new Rectangle(
                _fitBoxLocation.X + _fitBoxSize.Width / 4,
                _fitBoxLocation.Y + _fitBoxSize.Height / 4,
                _fitBoxSize.Width / 2,
                _fitBoxSize.Height / 2);

            e.Graphics.DrawString(fitFuncName,
                                  System.Windows.Forms.SystemInformation.MenuFont,
                                  System.Drawing.Brushes.Black,
                                  fitFuncBox
                                  );

            if (this._fitFunctionSelected)
            {
                e.Graphics.DrawRectangle(Pens.Red, fitFuncBox);
            }



            base.OnPaint(e);
        }
 void EhView_ChooseNegativeError(object sender, EventArgs e)
 {
   SingleColumnChoice choice = new SingleColumnChoice();
   choice.SelectedColumn = _tempNegErrorColumn != null ? _tempNegErrorColumn as DataColumn: _doc.NegativeErrorColumn as DataColumn;
   object choiceAsObject = choice;
   if (Current.Gui.ShowDialog(ref choiceAsObject, "Select negative error column"))
   {
     choice = (SingleColumnChoice)choiceAsObject;

     if (choice.SelectedColumn is INumericColumn)
     {
       _tempNegErrorColumn = (INumericColumn)choice.SelectedColumn;
       _view.NegativeError = _tempNegErrorColumn.FullName;
     }
   }
 }
Beispiel #39
0
        /// <summary>
        /// Sets the ith independent variable column. The column is hold by a reference aware of disposed events, so that it can be null if retrieved afterwards.
        /// </summary>
        /// <param name="i">Index.</param>
        /// <param name="col">Independent variable column to set.</param>
        public void SetIndependentVariable(int i, INumericColumn col)
        {
            this._independentVariables[i] = new NumericColumnProxy(col);

            this.OnChanged();
        }
Beispiel #40
0
 /// <summary>
 /// Constructor by giving a numeric column.
 /// </summary>
 /// <param name="column">The numeric column to hold.</param>
 protected NumericColumnProxyForStandaloneColumns(INumericColumn column)
 {
     _column = column;
 }
Beispiel #41
0
		/// <summary>
		/// Determines which of the rows of a set of columns is truly numeric, i.e. all columns in this row contains a value, which is not double.NaN.
		/// </summary>
		/// <param name="table">Array of numeric columns.</param>
		/// <param name="selectedCols">The indizes of the columns in question into the collection.</param>
		/// <param name="selectedRowIndices">The selected data row indices.</param>
		/// <param name="rowCount">The minimum row count of all the selected columns.</param>
		/// <returns>A boolean array. If an element of the array is true at a given index, that row contains valid numeric values in all columns.</returns>
		public static bool[] GetValidNumericRows(INumericColumn[] table, IAscendingIntegerCollection selectedCols, IEnumerable<int> selectedRowIndices, int rowCount)
		{
			// determine the number of valid rows
			bool[] rowValid = new bool[rowCount];

			foreach (int i in selectedRowIndices)
				rowValid[i] = true;

			for (int i = 0; i < selectedCols.Count; i++)
			{
				INumericColumn col = (INumericColumn)table[selectedCols[i]];
				for (int j = 0; j < rowCount; j++)
				{
					if (double.IsNaN(col[j]))
						rowValid[j] = false;
				}
			}
			return rowValid;
		}
 void EhView_ClearPositiveError(object sender, EventArgs e)
 {
   _tempPosErrorColumn = null;
   _view.PositiveError = string.Empty;
 }
Beispiel #43
0
        public static string Fit(Altaxo.Graph.GUI.GraphController ctrl)
        {
            if (ctrl.CurrentPlotNumber < 0)
            {
                return("No active plot!");
            }

            IGPlotItem plotItem = ctrl.ActiveLayer.PlotItems.Flattened[ctrl.CurrentPlotNumber];

            XYColumnPlotItem xyPlotItem = plotItem as XYColumnPlotItem;

            if (xyPlotItem == null)
            {
                return("Active plot is not a X-Y Plot!");
            }

            INumericColumn xColumn = xyPlotItem.XYColumnPlotData.XColumn as INumericColumn;
            INumericColumn yColumn = xyPlotItem.XYColumnPlotData.YColumn as INumericColumn;

            if (xColumn == null)
            {
                return("The x-column is not numeric");
            }

            if (yColumn == null)
            {
                return("The y-column is not numeric");
            }


            Calc.Regression.Nonlinear.NonlinearFitDocument localdoc = ctrl.Doc.GetGraphProperty(FitDocumentPropertyName) as Calc.Regression.Nonlinear.NonlinearFitDocument;


            if (localdoc == null)
            {
                if (_lastFitDocument == null)
                {
                    localdoc = new Altaxo.Calc.Regression.Nonlinear.NonlinearFitDocument();
                }
                else
                {
                    localdoc = (Altaxo.Calc.Regression.Nonlinear.NonlinearFitDocument)_lastFitDocument.Clone();
                }
            }


            if (localdoc.FitEnsemble.Count == 0)
            {
                Calc.Regression.Nonlinear.FitElement fitele = new Altaxo.Calc.Regression.Nonlinear.FitElement(
                    xColumn,
                    yColumn,
                    xyPlotItem.XYColumnPlotData.PlotRangeStart,
                    xyPlotItem.XYColumnPlotData.PlotRangeLength);

                localdoc.FitEnsemble.Add(fitele);
            }
            else // localdoc.FitEnsemble.Count>0
            {
                localdoc.FitEnsemble[0].SetIndependentVariable(0, xColumn);
                localdoc.FitEnsemble[0].SetDependentVariable(0, yColumn);
                localdoc.FitEnsemble[0].SetRowRange(xyPlotItem.XYColumnPlotData.PlotRangeStart, xyPlotItem.XYColumnPlotData.PlotRangeLength);
            }

            localdoc.FitContext = ctrl;


            object fitdocasobject = localdoc;

            if (true == Current.Gui.ShowDialog(ref fitdocasobject, "Non-linear fitting"))
            {
                // store the fit document in the graphs property
                ctrl.Doc.SetGraphProperty(FitDocumentPropertyName, localdoc);

                _lastFitDocument = (Altaxo.Calc.Regression.Nonlinear.NonlinearFitDocument)localdoc.Clone();
            }


            return(null);
        }
 void EhView_ClearNegativeError(object sender, EventArgs e)
 {
   _tempNegErrorColumn = null;
   _view.NegativeError = string.Empty;
 }
 /// <summary>
 /// This returns a read-only vector of a <see cref="INumericColumn" />
 /// </summary>
 /// <param name="col">The column to wrap as a IVector.</param>
 /// <param name="nRows">The number of rows to use for the vector.</param>
 /// <returns>An IVector wrapping the <see cref="INumericColumn" />.</returns>
 public static IROVector ToROVector(INumericColumn col, int nRows)
 {
     return(new NumericColumnToROVectorWrapper(col, nRows));
 }
Beispiel #46
0
        /// <summary>
        /// Gets the fractional index for merging of two tables.
        /// </summary>
        /// <param name="masterColumn">X-column of the master table.</param>
        /// <param name="slaveColumn">X-column of the slave table.</param>
        /// <returns>Array of fractional indices. Each item points into the slaveTable to the value that should be included in the master column at the item's index.</returns>
        public static DoubleColumn GetFractionalIndex(INumericColumn masterColumn, INumericColumn slaveColumn)
        {
            if (!(masterColumn.Count.HasValue))
            {
                throw new ArgumentException("masterColumn has no defined count");
            }
            if (!(slaveColumn.Count.HasValue))
            {
                throw new ArgumentException("slaveColumn has no defined count");
            }

            int masterCount = masterColumn.Count.Value;
            int slaveCount  = slaveColumn.Count.Value;

            var result = new DoubleColumn();
            var dict   = new SortedDictionary <double, int>();

            for (int i = slaveCount - 1; i >= 0; i--)
            {
                dict[slaveColumn[i]] = i;
            }

            var sortedSlaveValues  = dict.Keys.ToArray();
            var sortedSlaveIndices = dict.Values.ToArray();

            for (int masterIdx = 0; masterIdx < masterCount; masterIdx++)
            {
                var masterValue = masterColumn[masterIdx];
                if (double.IsNaN(masterValue))
                {
                    result[masterIdx] = double.NaN;
                    continue;
                }
                int dictIdx = Array.BinarySearch(sortedSlaveValues, masterValue);

                if (dictIdx >= 0)
                {
                    result[masterIdx] = sortedSlaveIndices[dictIdx];
                    continue;
                }

                // dictIdx was negative, we have to take the complement
                dictIdx = ~dictIdx;
                if (dictIdx >= sortedSlaveIndices.Length)
                {
                    result[masterIdx] = double.NaN;
                    continue;
                }
                else if (dictIdx == 0)
                {
                    result[masterIdx] = double.NaN;
                    continue;
                }
                else
                {
                    int    firstSlaveIdx    = sortedSlaveIndices[dictIdx - 1];
                    int    secondSlaveIdx   = sortedSlaveIndices[dictIdx];
                    double firstSlaveValue  = sortedSlaveValues[dictIdx - 1];
                    double secondSlaveValue = sortedSlaveValues[dictIdx];

                    double diff = secondSlaveValue - firstSlaveValue;

                    if (diff == 0)
                    {
                        result[masterIdx] = firstSlaveIdx;
                        continue;
                    }
                    else
                    {
                        result[masterIdx] = firstSlaveIdx + (secondSlaveIdx - firstSlaveIdx) * (masterValue - firstSlaveValue) / diff;
                        continue;
                    }
                }
            }

            return(result);
        }
 /// <summary>
 /// This returns a read-only vector of a <see cref="INumericColumn" /> for selected rows.
 /// </summary>
 /// <param name="col">The column to wrap as a IVector.</param>
 /// <param name="selectedRows">The rows of the source column that are part of the vector.</param>
 /// <returns>An IROVector wrapping the <see cref="INumericColumn" />.</returns>
 public static IROVector ToROVector(INumericColumn col, IAscendingIntegerCollection selectedRows)
 {
     return(new NumericColumnSelectedRowsToROVectorWrapper(col, (IAscendingIntegerCollection)selectedRows.Clone()));
 }