IFunction.cpp 5.17 KB
Newer Older
1
2
3
4
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidKernel/Exception.h"
5
#include "MantidAPI/IFunction.h"
6
#include "MantidAPI/IConstraint.h"
7
#include "MantidAPI/ParameterTie.h"
8
#include "MantidDataObjects/Workspace2D.h"
9
10

#include <sstream>
11
#include <iostream>
12
13
14
15
16
17

namespace Mantid
{
namespace API
{

18
/** Base class implementation of derivative IFunction throws error. This is to check if such a function is provided
19
20
21
22
23
24
25
26
27
28
    by derivative class. In the derived classes this method must return the derivatives of the resuduals function
    (defined in void Fit1D::function(const double*, double*, const double*, const double*, const double*, const int&))
    with respect to the fit parameters. If this method is not reimplemented the derivative free simplex minimization
    algorithm is used.
* @param out Derivatives
* @param xValues X values for data points
* @param nData Number of data points
 */
void IFunction::functionDeriv(Jacobian* out, const double* xValues, const int& nData)
{
29
  throw Kernel::Exception::NotImplementedError("No derivative IFunction provided");
30
31
}

32
33
34
35
36
37
/** Initialize the function providing it the workspace
 * @param workspace The workspace to set
 * @param wi The workspace index
 * @param xMin The lower bin index
 * @param xMax The upper bin index
 */
38
void IFunction::setWorkspace(boost::shared_ptr<const DataObjects::Workspace2D> workspace,int wi,int xMin,int xMax)
39
40
{
  m_workspace = workspace;
41
  m_workspaceIndex = wi;
42
43
44
45
  m_xMinIndex = xMin;
  m_xMaxIndex = xMax;
}

46
47
/** This method calls function() and add any penalty to its output if constraints are violated.
*
48
* @param out IFunction values of for the data points
49
50
51
52
53
* @param xValues X values for data points
* @param nData Number of data points
 */
void IFunction::functionWithConstraint(double* out, const double* xValues, const int& nData)
{
54
  this->function(out, xValues, nData);
55

56
57
  // Add penalty factor if constraint is violated
/*
58
  double penalty = 0.0;
59

60
  for (unsigned i = 0; m_constraints.size(); i++)
61
  {
62
    penalty += m_constraints[i]->check(*this);
63
  }
64
65
*/

66
67
68
69
70
71
72
73
74
75
76
}


/** This method calls functionDeriv() and add any penalty to its output if constraints are violated.
*
* @param out Derivatives
* @param xValues X values for data points
* @param nData Number of data points
 */
void IFunction::functionDerivWithConstraint(Jacobian* out, const double* xValues, const int& nData)
{
77
  this->functionDeriv(out, xValues, nData);
78
79
}

80
/** Update active parameters. Ties are applied.
81
 *  @param in Pointer to an array with active parameters values. Must be at least nActive() doubles long.
82
83
84
85
86
 */
void IFunction::updateActive(const double* in)
{
  if (in)
    for(int i=0;i<nActive();i++)
87
88
89
    {
      setActiveParameter(i,in[i]);
    }
90
  applyTies();
91
92
}

93
94
/**
 * Sets active parameter i to value. Ties are not applied.
95
96
 * @param i The index of active parameter to set
 * @param value The new value for the parameter
97
 */
98
void IFunction::setActiveParameter(int i,double value)
99
{
100
101
102
103
  int j = indexOfActive(i);
  parameter(j) = value;
}

104
double IFunction::activeParameter(int i)const
105
106
107
{
  int j = indexOfActive(i);
  return parameter(j);
108
109
}

110
111
/** Create a new tie. IFunctions can have their own types of ties.
 * @param parName The parameter name for this tie
112
 */
113
ParameterTie* IFunction::createTie(const std::string& parName)
114
{
115
  return new ParameterTie(this,parName);
116
117
118
119
120
121
122
123
124
}

/**
 * Ties a parameter to other parameters
 * @param parName The name of the parameter to tie.
 * @param expr    A math expression 
 */
void IFunction::tie(const std::string& parName,const std::string& expr)
{
125
126
127
128
129
130
131
132
  ParameterTie* tie = this->createTie(parName);
  int i = parameterIndex(tie->parameter());
  if (i < 0)
  {
    delete tie;
    throw std::logic_error("Parameter "+parName+" was not found.");
  }

133
134
135
136
137
138
  if (!this->isActive(i))
  {
    delete tie;
    throw std::logic_error("Parameter "+parName+" is already tied.");
  }
  tie->set(expr);
139
  addTie(tie);
140
141
142
  this->removeActive(i);
}

143
144
145
/** Removes the tie off a parameter. The parameter becomes active
 * This method can be used when constructing and editing the IFunction in a GUI
 * @param parName The name of the paramter which ties will be removed.
146
 */
147
void IFunction::removeTie(const std::string& parName)
148
{
149
150
  int i = parameterIndex(parName);
  this->removeTie(i);
151
152
}

153
/**
154
 * Calculate the Jacobian with respect to parameters actually declared in the IFunction
155
156
157
158
159
160
161
162
 * @param out The output Jacobian
 * @param xValues The x-values
 * @param nData The number of data points (and x-values).
 */
void IFunction::calJacobianForCovariance(Jacobian* out, const double* xValues, const int& nData)
{
  this->functionDeriv(out,xValues,nData);
}
163

164
/**
165
 * Writes a string that can be used in Fit.IFunction to create a copy of this IFunction
166
167
168
169
170
171
172
173
174
175
176
177
178
 */
std::string IFunction::asString()const
{
  std::ostringstream ostr;
  ostr << "name="<<this->name();
  for(int i=0;i<nParams();i++)
    ostr<<','<<parameterName(i)<<'='<<parameter(i);
  return ostr.str();
}

/**
 * Operator <<
 * @param ostr The output stream
179
 * @param f The IFunction
180
181
182
183
184
185
186
 */
std::ostream& operator<<(std::ostream& ostr,const IFunction& f)
{
  ostr << f.asString();
  return ostr;
}

187
188
} // namespace API
} // namespace Mantid