Ticket #9497 (assigned)
IFunction::clone alters parameter values in some cases
Reported by: | Michael Wedel | Owned by: | Roman Tolchenov |
---|---|---|---|
Priority: | major | Milestone: | Backlog |
Component: | Framework | Keywords: | |
Cc: | roman.tolchenov@… | Blocked By: | |
Blocking: | Tester: |
Description
The way IFunction::clone is currently implemented (create a string-representation of "this" and pass this to FunctionFactory::createInitialized) depends on the precision which is used to transform the double values to strings (it seems to be 6 significant digits), so the following test fails:
IFunction_sptr function(new CurveFitting::Gaussian()); function->initialize(); function->setParameter(0, 1.23456); function->setParameter(1, 1.234567); function->setParameter(2, 0.01234567); IFunction_sptr clone = function->clone(); // passes, Parameter 0 has less than 7 significant digits TS_ASSERT_EQUALS(function->getParameter(0), clone->getParameter(0)); // fails, Parameter 1 has more than 6 significant digits TS_ASSERT_EQUALS(function->getParameter(1), clone->getParameter(1)); // fails, Parameter 2 has more than 6 significant digits TS_ASSERT_EQUALS(function->getParameter(2), clone->getParameter(2));
Consequently, this affects all places where a function is constructed from a string representation (I came across this in MultiDomainFunction::createEquivalentFunctions in the form of FunctionFactory::Instance().createInitialized( function->asString() ), but there could be other places affected as well).
The error it introduces may be small in many cases, but I think it's not optimal that the parameter values are altered at all by this operation.
In earlier tests I was cloning an IFunction-object many times and due to the string conversions back and forth it turned out to be an expensive operation.
I think having a non-string-based clone method would solve the precision-problem and improve performance for this operation at the same time.
Change History
comment:1 Changed 6 years ago by Nick Draper
- Status changed from new to assigned
- Owner set to Roman Tolchenov
comment:3 Changed 6 years ago by Michael Wedel
Maybe this issue could be solved temporarily by using std::setprecision:
IFunction.cpp, IFunction::asString:
std::string IFunction::asString()const { std::ostringstream ostr; ostr << std::setprecision(std::numeric_limits<double>::digits10 + 2) ostr << "name="<<this->name(); ...
I found this in a stackoverflow discussion on the topic:
http://stackoverflow.com/questions/554063/
What I don't know is if it impacts other parts of Mantid that use this. It may look strange if the output is presented to the user.