Author Topic: How to use Utils::binary_search_for_value()  (Read 60 times)

William

  • Member
  • Posts: 21
How to use Utils::binary_search_for_value()
« on: 17. March 2021, 12:00:16 »
I'm trying to use the Utils::binary_search_for_value() function to find the x for which tau(x) = 1, but I can't get it to work properly. The first input argument is supposed to be a spline function, right? When I try something like Utils::binary_search_for_value(tau_of_x_spline, 1) I get the following error:
Code: [Select]
error: binding reference of type 'Spline' to value of type 'const Spline' drops 'const' qualifier
  double x_decoupling = Utils::binary_search_for_value(tau_of_x_spline, 1);

winther

  • Global Moderator
  • Member
  • Posts: 66
    • Website
Re: How to use Utils::binary_search_for_value()
« Reply #1 on: 17. March 2021, 12:11:46 »
This seems to tell us that your spline tau_of_x_spline is declared constant. How is your spline declared, i.e. is it declared as
Code: [Select]
Spline tau_of_x_spline{"tau"};in the header file?

Here is a simple test code to check that it works:
Code: [Select]
// Make xarray = 0.0, ...., 1.0
Vector xarray = Utils::linspace(0.0,1.0,100);
// Make the function y = e^x
Vector yarray = exp(xarray);
// Spline it
Spline f(xarray,yarray);
// Try to find the value where e^x = e^0.5
double value = Utils::binary_search_for_value(f,std::exp(0.5));
std::cout << "exp(x) = exp(0.5) when x = " << value << "\n";
If this works then there is something with how your spline is declared.

If something is declared const, but needs to be used in a non-const way then one can cheat and remove the const-ness of it, e.g. in the example above
Code: [Select]
...
const Spline f(xarray,yarray);
...
double value = Utils::binary_search_for_value( const_cast<Spline&>(f), std::exp(0.5));
« Last Edit: 17. March 2021, 12:14:44 by winther »

William

  • Member
  • Posts: 21
Re: How to use Utils::binary_search_for_value()
« Reply #2 on: 17. March 2021, 12:18:54 »
The test code worked for me, but I have declared the spline as in the header file
Code: [Select]
Spline tau_of_x_spline{"tau"};

William

  • Member
  • Posts: 21
Re: How to use Utils::binary_search_for_value()
« Reply #3 on: 17. March 2021, 12:21:10 »
I tried the cheat though, and it worked!

winther

  • Global Moderator
  • Member
  • Posts: 66
    • Website
Re: How to use Utils::binary_search_for_value()
« Reply #4 on: 17. March 2021, 12:25:52 »
Ok good. But its weird that it happens then. You are not declaring any variables with the same name tau_of_x_spline right?
And in what function are you running this (what is the signature of that function, is it declare const?)

William

  • Member
  • Posts: 21
Re: How to use Utils::binary_search_for_value()
« Reply #5 on: 17. March 2021, 12:29:37 »
No, it's only the tau_of_x_spline declared in the header file. I'm running it in RecombinationHistory::output(), so it shouldn't be a problem, right?

winther

  • Global Moderator
  • Member
  • Posts: 66
    • Website
Re: How to use Utils::binary_search_for_value()
« Reply #6 on: 17. March 2021, 12:36:24 »
Ahh, now its clear. You found a minor bug in the template. The function output() is declared const so no class variables are allowed to change in this function. However when you call binary_search_for_value then you pass a reference to a spline. That function might *potentially* change the spline (it doesn't, but the compier doesn't know that) so that's why you get an error.

The bug is that the binary_search_for_value function should take in a const spline (as it just uses the spline, not change anything about it). Thus the signature of this method should be fixed. The fix is just to add const to the function definition in Utils.h and Utils.cpp

Code: [Select]
// Both in Utils.h and Utils.cpp add const
double binary_search_for_value(
      const Spline &y,
      ...

I will update the template as one should be able to do this in the output method without getting an error.