# Example from Section 5.3
read "../ComputeIdentifiableFunctions.mpl";

#------------------------------------------------------------------------------
# Auxiliary function for counting nonconstant coefficients

CountNonNumeric := proc(p, var)
    local result, c:
    result := 0:
    for c in coeffs(p, var) do
        if not type(c, numeric) then
            result := result + 1:
        end if:
    end do:
    return result:
end proc:

#------------------------------------------------------------------------------

model_original := [
    diff(x1(t), t) = (a * x1(t) - b * x1(t) * x2(t)),
    diff(x2(t), t) = (-c * x2(t) + d * x1(t) * x2(t)),
    diff(f(t), t) = 0,
    y1(t) = (e * x1(t) + f(t) * x2(t)),
    y2(t) = f(t)
]:

printf("We are interested in computing ME-identifiable functions and the bound for ME-identifiablility\n"):
ME_identifiable_functions := MultiExperimentIdentifiableFunctions(model_original, no_bound=true, simplified_generators=true)[3]:
printf("The field of multi-experiment identifiable functions is generated by %a\n", ME_identifiable_functions):

printf("To find a good bound for the number of experiments we consider the following model (as described in Section 5.3)\n"):
model := [
    diff(x1(t), t) = (a * x1(t) - b * x1(t) * x2(t)),
    diff(x2(t), t) = (-c * x2(t) + d * x1(t) * x2(t)),
    y(t) = (e * x1(t) + f * x2(t))
]:
print(model):

printf("First we compute the bound and IO-equations considering f just as a parameter\n"):
result := MultiExperimentIdentifiableFunctions(model, simplified_generators=true):
printf("If we consider a different system with f being an unknown parameter with the same value for different experiments, the bound from the theorem will be %a\n", result[1]):
# In the notation of Section 5.3
io_eq_coeffs := [expand(denom(result[2][1])), op(map(p -> expand(simplify(p * denom(result[2][1]))), result[2]))]:
print(io_eq_coeffs):
ns := sort(map(p -> CountNonNumeric(p, f), io_eq_coeffs)):
n := ns[1]:
printf("The number of non-numeric coefficients with respect to f (in the notation of Section 5.3: n, n1, n2, ...) in the coefficients of the only input-output equation are: %a\n", ns):
printf("Section 5.3 implies that the number of experiments for the case when f is a known parameter different in different experiments is %a\n", max(n + min(ns[2...]), max(ns[2..]))):

