Пример #1
0
        /// <summary>
        /// Copies the current parameters for the fit element with the provided index into the provided array.
        /// </summary>
        /// <param name="idxFitEle">Index of the fit element.</param>
        /// <param name="parameters">Provided array to copy the current parameters to. Must have same size as NumberOfParameters for the given fit element.</param>
        public void GetParameters(int idxFitEle, double[] parameters)
        {
            CachedFitElementInfo info = _cachedFitElementInfo[idxFitEle];

            // copy of the parameter to the temporary array
            for (int i = 0; i < info.Parameters.Length; i++)
            {
                int idx = info.ParameterMapping[i];
                parameters[i] = idx >= 0 ? _cachedVaryingParameters[idx] : _constantParameters[-1 - idx];
            }
        }
Пример #2
0
        /// <summary>
        /// Calculates the jacobian values, i.e. the derivatives of the fitting values with respect to the parameters.
        /// </summary>
        /// <param name="parameter">The parameter used to calculate the values.</param>
        /// <param name="outputValues">You must provide an array to hold the calculated values. Size of the array must be
        /// at least <see cref="NumberOfData" />*<see cref="FitElement.NumberOfParameters" />.</param>
        /// <param name="adata">Currently ignored.</param>
        /// <remarks>The values of the fit elements are stored in the order from element_0 to element_n*m. If there is more
        /// than one used dependent variable per fit element, the output values are stored in interleaved order. The derivatives
        /// on one fitting value  are stored in successive order.
        /// </remarks>
        public void EvaluateFitJacobian(double[] parameter, double[] outputValues, object adata)
        {
            outputValues.Initialize(); // make sure every element contains zero

            int outputValuesPointer = 0;

            for (int ele = 0; ele < _cachedFitElementInfo.Length; ele++)
            {
                CachedFitElementInfo info   = _cachedFitElementInfo[ele];
                FitElement           fitEle = _fitEnsemble[ele];


                // make sure, that the dimension of the DYs is ok
                if (info.DYs == null || info.DYs.Length != fitEle.NumberOfDependentVariables || info.DYs[0].Length != fitEle.NumberOfParameters)
                {
                    info.DYs = LinearAlgebra.JaggedArrayMath.GetMatrixArray(fitEle.NumberOfDependentVariables, fitEle.NumberOfParameters);
                }

                // copy of the parameter to the temporary array
                for (int i = 0; i < info.Parameters.Length; i++)
                {
                    int idx = info.ParameterMapping[i];
                    info.Parameters[i] = idx >= 0 ? parameter[idx] : _constantParameters[-1 - idx];
                }


                IAscendingIntegerCollection validRows = info.ValidRows;
                int numValidRows = validRows.Count;
                // Evaluate the function for all points
                for (int i = 0; i < numValidRows; ++i)
                {
                    for (int k = info.Xs.Length - 1; k >= 0; k--)
                    {
                        info.Xs[k] = fitEle.IndependentVariables(k)[validRows[i]];
                    }

                    ((IFitFunctionWithGradient)fitEle.FitFunction).EvaluateGradient(info.Xs, info.Parameters, info.DYs);

                    // copy the evaluation result to the output array (interleaved)
                    for (int k = 0; k < info.DependentVariablesInUse.Length; ++k)
                    {
                        for (int l = 0; l < info.Parameters.Length; ++l)
                        {
                            int idx = info.ParameterMapping[l];
                            if (idx >= 0)
                            {
                                outputValues[outputValuesPointer + idx] += info.DYs[info.DependentVariablesInUse[k]][l];
                            }
                        }
                        outputValuesPointer += parameter.Length; // increase output pointer only by the varying (!) number of parameters
                    }
                }
            }
        }
Пример #3
0
        /// <summary>
        /// Calculates the fitting values.
        /// </summary>
        /// <param name="parameter">The parameter used to calculate the values.</param>
        /// <param name="outputValues">You must provide an array to hold the calculated values. Size of the array must be
        /// at least <see cref="NumberOfData" />.</param>
        /// <param name="calculateUnusedDependentVariablesAlso">If <c>true</c>, the unused dependent variables are also calculated (and plotted).</param>
        /// <remarks>The values of the fit elements are stored in the order from element_0 to element_n. If there is more
        /// than one used dependent variable per fit element, the output values are stored in interleaved order.
        /// </remarks>
        public void EvaluateFitValues(double[] parameter, double[] outputValues, bool calculateUnusedDependentVariablesAlso)
        {
            int outputValuesPointer = 0;

            for (int ele = 0; ele < _cachedFitElementInfo.Length; ele++)
            {
                CachedFitElementInfo info   = _cachedFitElementInfo[ele];
                FitElement           fitEle = _fitEnsemble[ele];

                // copy of the parameter to the temporary array
                for (int i = 0; i < info.Parameters.Length; i++)
                {
                    int idx = info.ParameterMapping[i];
                    info.Parameters[i] = idx >= 0 ? parameter[idx] : _constantParameters[-1 - idx];
                }

                IAscendingIntegerCollection validRows = info.ValidRows;
                int numValidRows = validRows.Count;
                // Evaluate the function for all points
                for (int i = 0; i < numValidRows; ++i)
                {
                    for (int k = info.Xs.Length - 1; k >= 0; k--)
                    {
                        info.Xs[k] = fitEle.IndependentVariables(k)[validRows[i]];
                    }

                    fitEle.FitFunction.Evaluate(info.Xs, info.Parameters, info.Ys);

                    if (calculateUnusedDependentVariablesAlso)
                    {
                        // copy the evaluation result to the output array (interleaved)
                        for (int k = 0; k < fitEle.NumberOfDependentVariables; ++k)
                        {
                            outputValues[outputValuesPointer++] = info.Ys[k];
                        }
                    }
                    else
                    {
                        // copy the evaluation result to the output array (interleaved)
                        for (int k = 0; k < info.DependentVariablesInUse.Length; ++k)
                        {
                            outputValues[outputValuesPointer++] = info.Ys[info.DependentVariablesInUse[k]];
                        }
                    }
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Stores the dependent values of all elements in an array. The data
        /// are stored from FitElement_0 to FitElement_n. For FitElements with more than one dependent
        /// variable in use, the data are stored interleaved.
        /// </summary>
        /// <param name="values">The array used to store the values.</param>
        public void GetDependentValues(double[] values)
        {
            int outputValuesPointer = 0;

            for (int ele = 0; ele < _cachedFitElementInfo.Length; ele++)
            {
                CachedFitElementInfo info   = _cachedFitElementInfo[ele];
                FitElement           fitEle = _fitEnsemble[ele];

                IAscendingIntegerCollection validRows = info.ValidRows;
                int numValidRows = validRows.Count;
                // Evaluate the function for all points
                for (int i = 0; i < numValidRows; ++i)
                {
                    for (int j = 0; j < info.DependentVariablesInUse.Length; ++j)
                    {
                        values[outputValuesPointer++] = fitEle.DependentVariables(info.DependentVariablesInUse[j])[validRows[i]];
                    }
                }
            }
        }
Пример #5
0
		/// <summary>
		/// Internal function to set up the cached data for the fitting procedure.
		/// </summary>
		/// <param name="paraSet">The set of parameters (the information which parameters are fixed is mainly used here).</param>
		private void CalculateCachedData(ParameterSet paraSet)
		{
			// Preparation: Store the parameter names by name and index, and store
			// all parameter values in _constantParameters
			System.Collections.Hashtable paraNames = new System.Collections.Hashtable();
			System.Collections.Hashtable varyingParaNames = new System.Collections.Hashtable();

			_constantParameters = new double[paraSet.Count];
			int numberOfVaryingParameters = 0;
			for (int i = 0; i < paraSet.Count; ++i)
			{
				paraNames.Add(paraSet[i].Name, i);
				_constantParameters[i] = paraSet[i].Parameter;
				if (paraSet[i].Vary)
					++numberOfVaryingParameters;
			}
			_cachedVaryingParameters = new double[numberOfVaryingParameters];
			for (int i = 0, k = 0; i < paraSet.Count; ++i)
			{
				if (paraSet[i].Vary)
				{
					varyingParaNames.Add(paraSet[i].Name, k);
					_cachedVaryingParameters[k++] = paraSet[i].Parameter;
				}
			}

			_cachedNumberOfData = 0;
			_cachedFitElementInfo = new CachedFitElementInfo[_fitEnsemble.Count];
			for (int i = 0; i < _fitEnsemble.Count; i++)
			{
				CachedFitElementInfo info = new CachedFitElementInfo();
				_cachedFitElementInfo[i] = info;
				FitElement fitEle = _fitEnsemble[i];

				info.ValidRows = fitEle.CalculateValidNumericRows();

				info.Xs = new double[fitEle.NumberOfIndependentVariables];
				info.Parameters = new double[fitEle.NumberOfParameters];
				info.Ys = new double[fitEle.NumberOfDependentVariables];

				// Calculate the number of used variables
				int numVariablesUsed = 0;
				for (int j = 0; j < fitEle.NumberOfDependentVariables; ++j)
				{
					if (fitEle.DependentVariables(j) != null)
						++numVariablesUsed;
				}
				info.DependentVariablesInUse = new int[numVariablesUsed];
				for (int j = 0, used = 0; j < fitEle.NumberOfDependentVariables; ++j)
				{
					if (fitEle.DependentVariables(j) != null)
						info.DependentVariablesInUse[used++] = j;
				}

				// calculate the total number of data points
				_cachedNumberOfData += numVariablesUsed * info.ValidRows.Count;

				// now create the parameter mapping
				info.ParameterMapping = new int[fitEle.NumberOfParameters];

				for (int j = 0; j < info.ParameterMapping.Length; ++j)
				{
					if (!paraNames.Contains(fitEle.ParameterName(j)))
						throw new ArgumentException(string.Format("ParameterSet does not contain parameter {0}, which is used by function[{1}]", fitEle.ParameterName(j), i));

					int idx = (int)paraNames[fitEle.ParameterName(j)];
					if (paraSet[idx].Vary)
					{
						info.ParameterMapping[j] = (int)varyingParaNames[fitEle.ParameterName(j)];
					}
					else
					{
						info.ParameterMapping[j] = -idx - 1;
					}
				}
			}

			_cachedDependentValues = new double[_cachedNumberOfData];
			GetDependentValues(_cachedDependentValues);

			if (this.HasToUseWeights())
			{
				_cachedWeights = new double[_cachedNumberOfData];
				GetWeights(_cachedWeights);
			}
			else
				_cachedWeights = null;
		}
Пример #6
0
        /// <summary>
        /// Internal function to set up the cached data for the fitting procedure.
        /// </summary>
        /// <param name="paraSet">The set of parameters (the information which parameters are fixed is mainly used here).</param>
        private void CalculateCachedData(ParameterSet paraSet)
        {
            // Preparation: Store the parameter names by name and index, and store
            // all parameter values in _constantParameters
            var paraNames        = new System.Collections.Hashtable();
            var varyingParaNames = new System.Collections.Hashtable();

            _constantParameters = new double[paraSet.Count];
            int numberOfVaryingParameters = 0;

            for (int i = 0; i < paraSet.Count; ++i)
            {
                paraNames.Add(paraSet[i].Name, i);
                _constantParameters[i] = paraSet[i].Parameter;
                if (paraSet[i].Vary)
                {
                    ++numberOfVaryingParameters;
                }
            }
            _cachedVaryingParameters = new double[numberOfVaryingParameters];
            for (int i = 0, k = 0; i < paraSet.Count; ++i)
            {
                if (paraSet[i].Vary)
                {
                    varyingParaNames.Add(paraSet[i].Name, k);
                    _cachedVaryingParameters[k++] = paraSet[i].Parameter;
                }
            }

            _cachedNumberOfData   = 0;
            _cachedFitElementInfo = new CachedFitElementInfo[_fitEnsemble.Count];
            for (int i = 0; i < _fitEnsemble.Count; i++)
            {
                var info = new CachedFitElementInfo();
                _cachedFitElementInfo[i] = info;
                FitElement fitEle = _fitEnsemble[i];

                info.ValidRows = fitEle.CalculateValidNumericRows();

                info.Xs         = new double[fitEle.NumberOfIndependentVariables];
                info.Parameters = new double[fitEle.NumberOfParameters];
                info.Ys         = new double[fitEle.NumberOfDependentVariables];

                // Calculate the number of used variables
                int numVariablesUsed = 0;
                for (int j = 0; j < fitEle.NumberOfDependentVariables; ++j)
                {
                    if (fitEle.DependentVariables(j) != null)
                    {
                        ++numVariablesUsed;
                    }
                }
                info.DependentVariablesInUse = new int[numVariablesUsed];
                for (int j = 0, used = 0; j < fitEle.NumberOfDependentVariables; ++j)
                {
                    if (fitEle.DependentVariables(j) != null)
                    {
                        info.DependentVariablesInUse[used++] = j;
                    }
                }

                // calculate the total number of data points
                _cachedNumberOfData += numVariablesUsed * info.ValidRows.Count;

                // now create the parameter mapping
                info.ParameterMapping = new int[fitEle.NumberOfParameters];

                for (int j = 0; j < info.ParameterMapping.Length; ++j)
                {
                    if (!paraNames.Contains(fitEle.ParameterName(j)))
                    {
                        throw new ArgumentException(string.Format("ParameterSet does not contain parameter {0}, which is used by function[{1}]", fitEle.ParameterName(j), i));
                    }

                    int idx = (int)paraNames[fitEle.ParameterName(j)];
                    if (paraSet[idx].Vary)
                    {
                        info.ParameterMapping[j] = (int)varyingParaNames[fitEle.ParameterName(j)];
                    }
                    else
                    {
                        info.ParameterMapping[j] = -idx - 1;
                    }
                }
            }

            _cachedDependentValues = new double[_cachedNumberOfData];
            GetDependentValues(_cachedDependentValues);

            if (HasToUseWeights())
            {
                _cachedWeights = new double[_cachedNumberOfData];
                GetWeights(_cachedWeights);
            }
            else
            {
                _cachedWeights = null;
            }
        }