Ticket #9497 (assigned)

Opened 6 years ago

Last modified 5 years ago

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:2 Changed 6 years ago by Michael Wedel

  • Milestone changed from Release 3.2 to Release 3.3

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.

comment:4 Changed 6 years ago by Michael Wedel

  • Blocking 9445 removed

(In #9445) I am removing the block from #9497, because in further going tests when actually performing a fit (which is the intention in the end), this did not seem to cause problems.

comment:5 Changed 6 years ago by Nick Draper

Moved to the backlog at the code freeze of R3.3

comment:6 Changed 6 years ago by Nick Draper

  • Milestone changed from Release 3.3 to Backlog

comment:7 Changed 5 years ago by Nick Draper

  • Keywords CurveFitting removed

comment:8 Changed 5 years ago by Stuart Campbell

This ticket has been transferred to github issue 10340

Note: See TracTickets for help on using tickets.