A Course on Bioequivalence: Unit 1 - What is a Bioequivalence study?

Authors

Yoni Nazarathy

Andreas Noack

This is the first unit, Unit 1, of a complete bioequivalence analysis course using Pumas. There are 15 units in the course in total.

Other units of this course dive into the various bioequivalence designs and study paradigms, focusing on statistical issues, and also studying regulatory considerations. In particular the course takes an in-depth view at FDA regulatory guidelines.

For the course we use both Pumas (command line), and PumasCP. These are modern tools that support a variety of pharmacometric tasks and in particular bioequivalence analysis.

Nevertheless, if at the moment you use other commercial or open sourced tools and you are interested in understanding bioequivalence, this course may still be very suitable for you. The statistical bioequivalence concepts are universal and can in principle be carried out on any platform. It is just that Pumas provides the most up to date, streamlined, and easy to use approach for bioequivalence.

1 Unit overview

In this unit we introduce the concept of bioequivalence by looking at a simple case using Pumas software. In particular we use bioequivalence trial data from the PharmaDatasets package. This is the only unit of the course where we also discuss basics of non-compartmental analysis (NCA) to obtain a bioequivalence dataset.

You can reproduce the outcomes of this unit with Pumas (command line). Head onto this YouTube playlist to see onboarding lessons for the Pumas platform. The complete Pumas Documentation may also be of use.

To reproduce the content of this unit and other units, you can use the </> download tutorial button on at the top of the page, or alternatively (recommended) copy and paste individual cells into Pumas and run them one by one. You’ll see a 📋 (copy to clipboard) icon when you hover on the top right of each code cell.

Pumas uses Julia and in particular in this unit we use the following packages, of which the first 4 are Pumas packages (available only with a Pumas installation).

using PharmaDatasets # available with Pumas products
using NCA # available with Pumas products
using NCAUtilities # available with Pumas products
using Bioequivalence # available with Pumas products
using CairoMakie
using AlgebraOfGraphics
using SummaryTables
using DataFramesMeta
using Statistics

The PharmaDatasets package provides example datasets for practice and instructive analysis such as here. The NCA package provides utilities for non-compartmental analysis. The NCAUtilities package provides additional utility functions for NCA. Finally, the Bioequivlance package is the workhorse of bioequivalence analysis in Pumas.

In terms of the other packages, CairoMakie and AlgebraOfGraphics are used for plotting; SummaryTables is used to create nice output tables; DataFramesMeta is used for data analysis on top of the DataFrames package; and Julia’s in-built Statistics package provides basic statistical functions.

2 An Example Parallel Bioequivalence Trial

Let us consider the most basic type of bioequivalence trial. Assume your team or clients are developing a generic formulation of a drug with the same active ingredient as an approved formulation. While both the approved formulation and your new generic formulation may have the same quantity (molar dose) of active ingredient, the manufacturing processes and packaging processes may be different.

In this case we want to carry out a study comparing the approved drug which we call the reference, R, with the generic drug which we call the test, T. Our goal is to make sure that both drugs behave in the same way when administered to humans. That is, ideally, the generic formulation T and the approved formulation R should be interchangeable.

A basic clinical bioequivalence trial setup is to enlist subjects to a trial and randomize them into two groups, the reference group and test group. We then administer the reference formulation to the subjects in the reference group, and the similarly we adminster the test formulation to the subjects in the test group. For each subject, we measure drug concentrations in their system over time, and thus achieve profiles of how each of the drugs is processed by the individual subjects.

What we are comparing is the bioavailability, or the rate and extent of absorption. A key point with this approach is that we focus on pharmacokinetics (PK) which is how the system absorbs the drug, and not on pharmacodynamics which deals with the efficacy of the drug and other factors. As such, a bioequivalence trial only aims to see that the new formulation T is processed by the system in the same way as R is.

A parallel design example

In many cases, enrolled subjects are administered both R and T formulations (one after the other with a washout period in between). Yet as a basic example, consider the simplest case of a one period parallel design where some subjects are only administered R and others are only administered T. In this case, each formulation is also a sequence, namely we have the R sequence and the T sequence.

To obtain such an example dataset in Pumas, let’s use the nca/crossover_study.csv dataset from PharmaDatasets. Note that this dataset is actually from a slightly more complex crossover study that we discuss in the sequel. Yet, we take a subset of the data so that only the first period of the study is kept and hence it can be treated as a parallel study. We then use the read_nca function from the NCA package to create a population of subjects.

raw_data = dataset("nca/crossover_study.csv")

# We only consider the first period and thus treat it as a parallel study
@subset!(raw_data, :period .== 1)
@rtransform!(raw_data, :sequence = :sequence == "RT" ? "R" : "T")

# Preprocess the data for NCA
pop = read_nca(raw_data; observations = :concentration, group = [:sequence, :period])

Here are the first 25 rows of the dataset. As you can see, the id column represents the subject. In this study each subject is measured for 72 hours from the time of being administered a formulation. You can see there are multiple measurements in the first hour, at onset 0, at 0.1, at 0.25 and so fourth. Then towards the end of the study there are measurements at 24 hours, 36 hours, 48 hours, 60 hours, and finally before the subject is released, at 71.9 hours.

The drug concentration, in a unit such as for example mmol/L is measured. You can see the end of the dataset as well, indicating that there are 20 subjects in total. Such long format datasets are common for such studies and serve as an input to the NCA analysis. Most of this tutorial series does not deal with such NCA analysis, but rather deals with bioequivalance datasets that have already been processed. Yet to see the broader picture, in this first tutorial we start with NCA.

simple_table(first(raw_data, 25))
id time concentration amt sequence period formulation route
1 0 missing 100 R 1 oral ev
1 0.1 1120 100 R 1 oral ev
1 0.25 3312 100 R 1 oral ev
1 0.5 5224 100 R 1 oral ev
1 0.75 5309 100 R 1 oral ev
1 1 6493 100 R 1 oral ev
1 2 8390 100 R 1 oral ev
1 4 6676 100 R 1 oral ev
1 8 4103 100 R 1 oral ev
1 12 1942 100 R 1 oral ev
1 16 1496 100 R 1 oral ev
1 20 976 100 R 1 oral ev
1 24 686 100 R 1 oral ev
1 36 423 100 R 1 oral ev
1 48 328 100 R 1 oral ev
1 60 250 100 R 1 oral ev
1 71.9 212 100 R 1 oral ev
2 0 missing 100 R 1 oral ev
2 0.1 1138 100 R 1 oral ev
2 0.25 1889 100 R 1 oral ev
2 0.5 4263 100 R 1 oral ev
2 0.75 7059 100 R 1 oral ev
2 1 6238 100 R 1 oral ev
2 2 8790 100 R 1 oral ev
2 4 8678 100 R 1 oral ev
simple_table(last(raw_data, 25))
id time concentration amt sequence period formulation route
19 12 1229 100 T 1 oral ev
19 16 688 100 T 1 oral ev
19 20 344 100 T 1 oral ev
19 24 284 100 T 1 oral ev
19 36 210 100 T 1 oral ev
19 48 114 100 T 1 oral ev
19 60 115 100 T 1 oral ev
19 71.9 122 100 T 1 oral ev
20 0 missing 100 T 1 oral ev
20 0.1 955 100 T 1 oral ev
20 0.25 1874 100 T 1 oral ev
20 0.5 3122 100 T 1 oral ev
20 0.75 5658 100 T 1 oral ev
20 1 6392 100 T 1 oral ev
20 2 6380 100 T 1 oral ev
20 4 7800 100 T 1 oral ev
20 8 4285 100 T 1 oral ev
20 12 3020 100 T 1 oral ev
20 16 1845 100 T 1 oral ev
20 20 1351 100 T 1 oral ev
20 24 1073 100 T 1 oral ev
20 36 567 100 T 1 oral ev
20 48 407 100 T 1 oral ev
20 60 395 100 T 1 oral ev
20 71.9 372 100 T 1 oral ev

Here is an observations vs time plot of the measured profiles per subject. This is for the 10 subjects in the reference formulation. As is common, immediately after dosing, the concentration rises, until reaching a peak, and then it dissipates.

observations_vs_time(
    pop[1:10];
    legend = (; show = false),
    figure = (; title = "Reference Formulation - subject ids 1-10"),
)

Similarly here are profiles for the test formulation.

observations_vs_time(
    pop[11:20];
    legend = (; show = false),
    figure = (; title = "Test Formulation - subject ids 11-20"),
)

With such data, the key bioequivalence question is then:

Are the test formulation and the reference formulation identical or not?

For example, even though the molar dosages are exactly the same, it is possible that the packaging or manufacturing processes yield different absorption profiles between the two formulations. Hence the bioavailibity may differ. Thus, the act of carrying out a bioequivalence trial is the act of attempting to compare the profiles of T and R, and making a statistical conclusion about their sameness or not.

Just to explore this point further, here is another display of all of the data, separating the reference and test according to color.

plt = data(raw_data) * mapping(:time, :concentration, color = :sequence) * visual(Lines)
draw(
    plt,
    scales(Color = (; palette = ["R" => :green, "T" => :red]));
    axis = (
        xlabel = "Time",
        ylabel = "Concentration",
        title = "Concentration-Time Profiles",
    ),
)

Now let’s synthetically modify the data so that the test formulation, from time \(6\) has a lower concentration than what it has in the original data.

raw_data
modified_raw_data = @rtransform(
    raw_data,
    :concentration =
        ifelse(:time  6 && :sequence == "T", :concentration / 2, :concentration)
)
plt =
    data(modified_raw_data) *
    mapping(:time, :concentration, color = :sequence) *
    visual(Lines)
draw(
    plt,
    scales(Color = (; palette = [:red, :green]));
    axis = (
        xlabel = "Time",
        ylabel = "Concentration",
        title = "Concentration-Time Profiles",
        limits = ((0, 30), nothing),
    ),
)

In this case, we would probably want to conclude that T and R are not bioequivalent.

Comparing endpoints instead of full profiles

To date, bioequivalence analysis is done by considering pharmacometric endpoints of the profiles. Here the idea is to summarize the drug concentration over time plot with a few key numbers. This then allows us to use (quite) classical statistical methodology to compare R and T. That is, instead of considering the whole profile as a function, we just compute certain values that attempt to capture the main characteristics of the profiles.

The most common endpoints for bioequivalence are:

  • AUC - The total “area under the curve” of the concentration profile, capturing the total “substance effect” that the drug had on the subject.
  • Cmax - The maximal concentration reached.
  • Tmax - The time at which Cmax is attained.

Note that there are a few variations of these endpoints, and in particular for AUC. We touch these subtle points in the sequel.

At this point it can already be clear that there is only limited information available through endpoints. For example, with the synthetic transformation we carried out to the test formulation above, the AUC endpoint is modified but the Cmax endpoint is generally not.

We now use the run_nca function to calculate Cmax and AUC. We then present the endpoints for each subject of R and T.

nca_result = run_nca(pop; parameters = [:cmax, :aucinf_obs])
be_analysis_data = nca_result.reportdf;
rename!(be_analysis_data, :aucinf_obs => :AUC)

Here are the endpoints for the subjects that received the reference formulation:

simple_table(be_analysis_data[1:10, :])
id sequence period cmax AUC
1 R 1 8390 103775
2 R 1 8790 106139
3 R 1 6495 81593
4 R 1 5288 68455
5 R 1 8814 86616
6 R 1 6672 60543
7 R 1 9337 108778
8 R 1 5928 69962
9 R 1 12401 140016
10 R 1 7495 67214

Here are the endpoints for the subjects that received the test formulation:

simple_table(be_analysis_data[11:20, :])
id sequence period cmax AUC
11 T 1 7103 89156
12 T 1 5877 88563
13 T 1 9401 135210
14 T 1 8203 66406
15 T 1 5719 65806
16 T 1 12288 87459
17 T 1 8042 116926
18 T 1 6346 63073
19 T 1 7239 66300
20 T 1 7800 207104

3 A crude attempt at bioequivalence

Before we use the Bioequivalence.jl package, let us try and explore the data ourselves.

It is common to carry out a log transformation to the endpoints. There are several statistical and empirical reasons for that, and we’ll discuss these in further units. After we carry out a log transformation we can consider the (arithmetic) mean and standard deviation.

function summarize_endpoint(data, endpoint_symbol)
    data_R = round.(log.(data[1:10, endpoint_symbol]), digits = 3)
    data_T = round.(log.(data[11:20, endpoint_symbol]), digits = 3)
    m_R, s_R = mean(data_R), std(data_R)
    m_T, s_T = mean(data_T), std(data_T)
    println("\n=====================")
    println("Summary for endpoint $endpoint_symbol:")
    println("R (log transformed):\n", data_R)
    println("mean = $(round(m_R, digits = 4)), std = $(round(s_R, digits = 4))")
    println("\nT (log transformed):\n", data_T)
    println("mean = $(round(m_T, digits = 4)), std = $(round(s_T, digits = 4))")
end
summarize_endpoint(be_analysis_data, :AUC)
summarize_endpoint(be_analysis_data, :cmax)

=====================
Summary for endpoint AUC:
R (log transformed):
[11.55, 11.573, 11.31, 11.134, 11.369, 11.011, 11.597, 11.156, 11.85, 11.116]
mean = 11.3666, std = 0.2695

T (log transformed):
[11.398, 11.391, 11.815, 11.104, 11.094, 11.379, 11.669, 11.052, 11.102, 12.241]
mean = 11.4245, std = 0.3855

=====================
Summary for endpoint cmax:
R (log transformed):
[9.035, 9.081, 8.779, 8.573, 9.084, 8.806, 9.142, 8.687, 9.426, 8.922]
mean = 8.9535, std = 0.2512

T (log transformed):
[8.868, 8.679, 9.149, 9.012, 8.651, 9.416, 8.992, 8.756, 8.887, 8.962]
mean = 8.9372, std = 0.229

We can also create a scatter plot of the endpoints.

auc_R = log.(be_analysis_data[1:10, :AUC])
cmax_R = log.(be_analysis_data[1:10, :cmax])
auc_T = log.(be_analysis_data[11:20, :AUC])
cmax_T = log.(be_analysis_data[11:20, :cmax])

fig = Figure()
ax = Axis(fig[1, 1], aspect = AxisAspect(1), xlabel = "log(AUC)", ylabel = "log(Cmax)")
scatter!(ax, auc_R, cmax_R; markersize = 10, color = :blue, label = "R")
scatter!(ax, auc_T, cmax_T; markersize = 10, color = :red, label = "T")
xlims!(ax, 10, 13)
ylims!(ax, 8, 10)
axislegend(ax)
fig

As is evident above, there does not seem to be any noticeable difference between R and T.

This type of plotting analysis is not used to make a statistical conclusion about bioequivalence, but rather helps us as a guide to understand if the analysis is on the right track. For example, in an exploratory developmental study, such analysis can be very useful.

For example, here is the same data with the AUC test endpoint synthetically increased by 0.3 (across all test observations) and the CMAX endpoint synthetically decreased by 0.2 (across all test observations). This may potentially happen if the test formulation is slower to release (potentially lower cmax) in the system and as a consequence may also release more (higher auc) of the active drug into the system.

When we carry out a bioequivalence trial, the regulatory body (e.g. FDA) is typically interested to see summaries of both endpoints as part of our submission. In terms of a statistical comparison, we sometimes compare only one endpoint and sometimes carry out several comparisons. The specification of which endpoint to compare is specified before the trial takes place. Let us now see such an inferential statistical comparison.

4 A simple use of pumas_be

If we are in charge of carrying out the bioequivalence comparison, we may sometimes be presented directly with the endpoint data. In fact, in almost all of the units in this tutorial we assume that is the case. Thus, using the same data processed via NCA above, the data which we start with is:

simple_table(be_analysis_data)
id sequence period cmax AUC
1 R 1 8390 103775
2 R 1 8790 106139
3 R 1 6495 81593
4 R 1 5288 68455
5 R 1 8814 86616
6 R 1 6672 60543
7 R 1 9337 108778
8 R 1 5928 69962
9 R 1 12401 140016
10 R 1 7495 67214
11 T 1 7103 89156
12 T 1 5877 88563
13 T 1 9401 135210
14 T 1 8203 66406
15 T 1 5719 65806
16 T 1 12288 87459
17 T 1 8042 116926
18 T 1 6346 63073
19 T 1 7239 66300
20 T 1 7800 207104

Now with Pumas, when the data is structured in such a way or similar, carrying out bioequivalence analysis is as easy as invoking the pumas_be function. Say that our endpoint of interest is cmax. Then, all that is needed is:

pumas_be(be_analysis_data, endpoint = :cmax)
Observation Counts
Sequence ╲ Period 1
R 10
T 10
Paradigm: Parallel design
Model: T test (equal variance)
Criteria: Standard ABE
Endpoint: cmax
Formulations: Reference(R), Test(T)
Results(cmax) Assessment Criteria
R Geometric Naive Mean 7735
T Geometric Naive Mean 7610
Geometric Mean T/R Ratio (%) 98.39
Degrees of Freedom 18
90% Confidence Interval (%) [81.66, 118.6] Pass CI ⊆ [80, 125]
Variability CV (%) | σ̂ 23.73 | 0.234

Here the pumas_be function identified that this is a parallel design, this is evident with the output header Paradigm: Parallel design. The statistical model used was a rather simple t-test with an equal variance assumption among groups. In fact with our interpretation of the results it is a two one sided t-test (TOST). More on that in the sequel.

Note also that by default, pumas assume the data is untransformed and thus carries out a log transformation. However, the results are presented in terms of geometric means and the geometric mean ratio of the original quantities. More on that is in the sequel as well.

In our case, the geometric mean of R, set at 7735 was compared with the geometric mean of T (7610), and a 90% confidence interval for the ratio was produced at [81.66%, 118.6%].

The key bioequivalence conclusion is then to see if the interval is contained within [80%, 125%]. In case it is, then we have a Pass and this implies that, at least from the point of view of this endpoint, we can conclude that the two formulations are bioequivalent. This would then be the key result as part of our submission to a regulatory agency. All these details and many more are discussed in the follow up units.

5 A non passing case

In the case above, anlaysing cmax it appears that we pass the bioequivalence trial and we can then apply with the regulatory body to approve the generic drug. Yet to understand the fragility of bioequivalence trials, assume that we were required to use the AUC endpoint instead. In fact, the most common endpoint to use is AUC.

In such a case, for running pumas_be for AUC, if our data has an AUC column, we do not even need to specify the endpoint to pumas_be since it searches for AUC as default. Here is the analysis:

pumas_be(be_analysis_data)
Observation Counts
Sequence ╲ Period 1
R 10
T 10
Paradigm: Parallel design
Model: T test (equal variance)
Criteria: Standard ABE
Endpoint: AUC
Formulations: Reference(R), Test(T)
Results(AUC) Assessment Criteria
R Geometric Naive Mean 86372
T Geometric Naive Mean 91541
Geometric Mean T/R Ratio (%) 106
Degrees of Freedom 18
90% Confidence Interval (%) [81.89, 137.2] Fail CI ⊆ [80, 125]
Variability CV (%) | σ̂ 33.39 | 0.3251

We see that in this case, the 90% confidence interval is [81.89%, 137.2%] and hence we Fail! This is because the interval was not contained in the 80–125 bounds and it indicates that there is significant likelihood of the geometric mean ratio differing by more than 20% (this 20% values is related to the 80%, 125%). More on this interpretation is in the sequel.

If this is the result of our trial, it may imply that we need to “get back to the drawing board”, re-analyze the test formulation, make changes if needed, and then plan another bioequivalence trial. Importantly, if scientifically we believe that there should not be a difference between R and T, then we should use the newly observed estimate of the variability to refine our power analysis planning. More on that in the sequel. Needless to say, any further mistakes (or bad luck) may be costly and pose ethical risk.

As a hypothetical situation, let us say that in this revised trial, the observations for T were exactly those of R. Let us simulate what this output would look like:

be_analysis_data_2 = copy(be_analysis_data)

#Make T observations exactly those of R
be_analysis_data_2[11:20, :AUC] = be_analysis_data_2[1:10, :AUC]

pumas_be(be_analysis_data_2)
Observation Counts
Sequence ╲ Period 1
R 10
T 10
Paradigm: Parallel design
Model: T test (equal variance)
Criteria: Standard ABE
Endpoint: AUC
Formulations: Reference(R), Test(T)
Results(AUC) Assessment Criteria
R Geometric Naive Mean 86372
T Geometric Naive Mean 86372
Geometric Mean T/R Ratio (%) 100
Degrees of Freedom 18
90% Confidence Interval (%) [81.14, 123.3] Pass CI ⊆ [80, 125]
Variability CV (%) | σ̂ 26.69 | 0.2623

As you can see, in this case we have that the point estimate for the geometric mean ratio is exactly at 100% implying that the means of both formulations were exactly equal. Still, there is inherent variability in the sample and the confidence interval is of positive width. Yet in this case it happens to be contained in [80, 125] and hence we Pass.

As a final extreme assume that the variation across subjects and samples does not exist.

be_analysis_data_3 = copy(be_analysis_data)

#Replicate :AUC of first subject across all observations
be_analysis_data_3[:, :AUC] = fill(be_analysis_data_3[1, :AUC], 20)

pumas_be(be_analysis_data_3)
Observation Counts
Sequence ╲ Period 1
R 10
T 10
Paradigm: Parallel design
Model: T test (equal variance)
Criteria: Standard ABE
Endpoint: AUC
Formulations: Reference(R), Test(T)
Results(AUC) Assessment Criteria
R Geometric Naive Mean 103775
T Geometric Naive Mean 103775
Geometric Mean T/R Ratio (%) 100
Degrees of Freedom 18
90% Confidence Interval (%) [99.99, 100.1] Pass CI ⊆ [80, 125]
Variability CV (%) | σ̂ 0.0 | 0.0

In this case, we obtain a confidence interval which is essentially of zero-width. Notice also that the variability estimate is at 0.0. Such situations never occur in practice, yet it is instructive to consider for pedagogical purposes.

Warning

Manipulation as data as carried out above is only for pedagogical reasons. You would never carry out such modifications of sampled experimental clinical trial data, unless specific manipulation is specified in the study protocol.

6 What complications to expect

So if carrying out bioequivalence analysis is so simple, why should we study more? Well first, as analysts carrying out bioequivalence analysis it is important to understand the principles and inner workings of the statistical methodology. This enables us to not only interpret and process the results correctly, but also to plan bioequivalence trials geared towards success. Further, while some of the statistical models are often quite elementary (as in the case of the use of the two one sided t-test here), in other cases they are more involved.

Further, there are a few dimensions at play in a bioequivalence trial, and it is important we understand how they interplay. These are some of the key dimensions:

  • Designs
  • Statistical models
  • Endpoints
  • Regulatory guidelines
  • Highly variable drugs
  • Narrow therapeutic index drugs
  • Other special cases
  • Planning, sample size, and power
  • Validating assumptions

7 Guidances

Guidance documents released by the FDA, EMA, ICH, and other regulatory bodies describe the rules for carrying out bioequivalence analysis. Pumas software is built to follow the statistical guidelines in these documents. Nevertheless, those carrying out bioequivalence analysis need to be well informed on the guidelines. This course visits bioequivalence guidelines in various forms (with a focus on FDA). Here are key documents:

  • FDA’s latest official guidance: FDA (2021)
  • FDA’s latest (draft) statistical approaches official guidance: FDA (2022)
  • FDA’s earlier statistical approaches official guidance: FDA (2001)
  • Specific guidances for reference scaling (FDA): FDA (2011), FDA (2012)
  • FDA’s website for Product-Specific Guidances for Generic Drug Development: FDA (2025)
  • EMA has a few guidances. This is the 2010 guidance: EMA (2010). This Question&Answers document is useful: EMA (2015)
  • ICH’s M13A document: International council for harmonisation of technical requirements for pharmaceuticals for human use (2024)

8 Conclusion

The tutorial introduces the concept of bioequivalence studies, which are clinical trials designed to compare a generic drug formulation (Test) with an approved reference drug formulation (Reference) to determine if they behave similarly in the human body.

This first unit of a 15-unit course demonstrates how to use Pumas software to analyze bioequivalence data, focusing on a simple parallel design study where subjects receive either the test or reference formulation. The tutorial explains that bioequivalence analysis typically focuses on pharmacokinetic endpoints such as AUC (area under the curve) and Cmax (maximum concentration), rather than comparing complete concentration-time profiles. Using the pumas_be function, we statistically compare these endpoints and interpret the results based on whether the 90% confidence interval for the geometric mean ratio falls within the regulatory acceptance range of 80-125% or not.

9 Unit exercises

  1. Run the code of this unit in Pumas.
  2. Carry out bioequivalence analysis for be_analysis_data_3 using endpoint = :cmax. Why is the result the same as that when we ran pumas_be(be_analysis_data, endpoint = :cmax)?
  3. Consider the regulatory documents listed. Browse the documents and in each document find up to 5 terms that you did not know of prior, and attempt to define them.

References

EMA. 2010. “Guideline on the Investigation of Bioequivalence.” 2010. https://www.ema.europa.eu/en/documents/scientific-guideline/guideline-investigation-bioequivalence-rev1_en.pdf.
———. 2015. “Questions & Answers: Positions on Specific Questions Addressed to the Pharmacokinetics Working Party (PKWP). November 2015.” 2015. https://www.ema.europa.eu/en/documents/scientific-guideline/questions-and-answers-positions-specific-questions-addressed-pharmacokinetics-working-party_en.pdf.
FDA. 2001. “Statistical Approaches to Establishing Bioequivalence. Guidance for Industry.” 2001. https://www.fda.gov/media/70958/download.
———. 2011. “FDA, Draft Guidance on Progesterone. Recommended Apr 2010; Revised Feb 2011.” 2011. https://www.accessdata.fda.gov/drugsatfda_docs/psg/Progesterone_caps_19781_RC02-11.pdf.
———. 2012. “FDA, Draft Guidance on Warfarin Sodium. Recommended Dec 2012.” 2012. https://www.accessdata.fda.gov/drugsatfda_docs/psg/Warfarin_Sodium_tab_09218_RC12-12.pdf.
———. 2021. “FDA Bioequivalence Studies with Pharmacokinetic Endpoints for Drugs Submitted Under an ANDA Guidance for Industry. Recommended Aug 2021.” 2021. https://www.fda.gov/media/87219/download.
———. 2022. “Statistical Approaches to Establishing Bioequivalence. Guidance for Industry.” 2022. https://www.fda.gov/media/163638/download.
———. 2025. “FDA Product-Specific Guidances for Generic Drug Development.” 2025. https://www.accessdata.fda.gov/scripts/cder/psg/index.cfm.
International council for harmonisation of technical requirements for pharmaceuticals for human use, ICH -. 2024. “Bioequivalence for Immediate Release Solid Oral Dosage Forms - M13A - July 2024.” 2024. https://database.ich.org/sites/default/files/ICH_M13A_Step4_Final_Guideline_2024_0723.pdf.

Reuse