The modified Federov algorithm implemented here starts with a random design candidate and systematically swaps out rows of the design candidate to iteratively find better designs. The algorithm has the following steps and restrictions.

```
federov(
design_object,
model,
efficiency_criteria,
utility,
prior_values,
dudx,
candidate_set,
rows,
control
)
```

- design_object
A list of class 'spdesign' created within the

`generate_design`

function- model
A character string indicating the model to optimize the design for. Currently the only model programmed is the 'mnl' model and this is also set as the default.

- efficiency_criteria
A character string giving the efficiency criteria to optimize for. One of 'a-error', 'c-error', 'd-error' or 's-error'. No default is set and argument must be specified. Optimizing for multiple criteria is not yet implemented and will result in an error.

- utility
A named list of utility functions. See the examples and the vignette for examples of how to define these correctly for different types of experimental designs.

- prior_values
A list of priors

- dudx
A character string giving the name of the parameter in the denominator. Must be specified when optimizing for 'c-error'

- candidate_set
A matrix or data frame in the "wide" format containing all permitted combinations of attributes. The default is NULL. If no candidate set is provided, then the full factorial subject to specified exclusions will be used.

- rows
An integer giving the number of rows in the final design

- control
A list of control options

A list of class 'spdesign'

1) Create a random initial design and evaluate it. 2) Swap the first row of the design candidate with the first row of the candidate set. 3) If no better candidate is found, try the second row of the candidate set. Keep trying new rows of the candidate set until an improvement is found. 4) If a better candidate is found, then we try to swap out the next row in the design candidate with the first row of the candidate set. Keep repeating the previous step. 5) When all rows of the design candidate has been swapped once, reset the counter and work through the design candidate and candidate set again. 6) The algorithm terminates after a pre-determined number of iterations or when a pre-determined efficiency threshold has been found.

NOTE: I have not yet implemented a duplicate check! That is, I do not check whether the "same" choice rows are included but with the order of alternatives swapped. This can be achieved by further restricting the candidate set prior to searching for designs. That said, "identical" choice rows will not provide much additional information and should be excluded by default in the search process.