Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Understand sharp ridge function #2277

Open
yedidyakfir opened this issue Apr 24, 2024 · 4 comments
Open

Understand sharp ridge function #2277

yedidyakfir opened this issue Apr 24, 2024 · 4 comments

Comments

@yedidyakfir
Copy link

Hi, I am using the Coco dataset for my research. I am trying to reverse-engineer some of the functions.
I went over the c code for the sharp ridge function.
It seems the function equation is sqrt(sum(x_i ** 2)) + sum(x_i ** 2), but I cant find out the rotation and other manipulation you do for each instance of the function.
Can you help me with that?

Thanks

@FMGS666
Copy link

FMGS666 commented Apr 24, 2024

Hello,

the transformations are done in the f_sharp_ridge_bbob_problem_allocate function.
If you want to find where these transformations are done you need to look at the f_sharp_ridge_bbob_problem_allocate function in the f_sharp_ridge.c file. You can see that all the transformations of the instance of the function are done in lines 82-106.

In general, the code of each test function follows pretty much the following structure:

f_<function-name>_raw which Implements the raw and unaltered function ($f:\Omega \rightarrow \mathbb{R}$ WITHOUT any random transformation) without connections to any COCO structures. It takes as input the decision vector $x\in\Omega$ and simply returns the scalar value $f(x)$

f_<function-name>_evaluate Which evaluates the solution on a given instance of coco_problem_t (passed as first input to the function) by wrapping around the f_<function-name>_raw function

f_<function-name>_bbob_problem_allocate which handles the actual allocation of the coco_problem_t instance and also computes all the random transformations.

I hope this could help

@yedidyakfir
Copy link
Author

the instance of the function are done

Can you explain a bit more?
I see there is a calculation of 2 rotation matrices there, but where do we apply them to the data?
Or make any use of them?
In other words, how do this lines affect the evaluate method?

@brockho
Copy link
Contributor

brockho commented Apr 24, 2024

FYI, the mathematical definitions of the bbob functions can be found here: https://numbbo.github.io/gforge/downloads/download16.00/bbobdocfunctions.pdf

@FMGS666
Copy link

FMGS666 commented Apr 24, 2024

Let us only consider the transformation that shifts vertically the objective function.

For a given function $f: \mathbb{R}^d \rightarrow \mathbb{R}$ and a solution $x \in \mathbb{R}^d$, this transformation is simply given by $f(x) + f_{opt}$ where $f_{opt} \in \mathbb{R}$ is determined in a pseudo random fashion

Let's ignore now how to determine the value of $f_{opt} $ and let's imagine that we have computed it and we have it stored in a double variable named fopt (You can see that it is computed by using the bbob2009_compute_fopt function)

Each transformation is defined as a wrapper around the coco_problem_t instance that implements the target transformation by nesting coco_problem_t inside each other (using coco_problem_t -> data and coco_problem_transformed_data_t -> inner_problem) and wrapping around the coco_problem_t->evaluate_function member function to apply the desired transformation at each nesting level.

In the f_sharp_ridge_bbob_problem_allocate function, still at the beginning, we read the declaration of a NULL pointer to a coco_problem_t:

  coco_problem_t *problem = NULL;

Now the problem is initialized by means of the f_sharp_ridge_allocate that allocates the coco_problem_t for the sharp ridge function with the following line

  problem = f_sharp_ridge_allocate(dimension);

The next line reads:

  problem = transform_obj_shift(problem, fopt);

This function returns the wrapped problem that applies the transformation as I mentioned before.

You can think of this new problem as a wrapper around the initial inner problem (i.e.: the one that we have allocated with the f_sharp_ridge_allocate function), whose evaluate_function member function calls the evaluate_function of the inner problem (in our case f_sharp_ridge_evaluate) and adds fopt to its result.

after this line the new problem variable will be the transformed version of the problem, while the original problem will end up in problem->data->inner_problem, if I am not wrong.

When we call the problem->evaluate_function member function, we call it on the new "external" problem and what will actually happen (in a stylized synthesis) is that we will be first calling problem->data->inner_problem and then applying the transformation, so that we will be returning the wanted (transformed) value.

I hope this was clearer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants