MultiLinear.java
/*
* Copyright (C) 2021 INRAE AgroClim
*
* This file is part of Indicators.
*
* Indicators is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Indicators is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Indicators. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.inrae.agroclim.indicators.model.function.normalization;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringJoiner;
import java.util.stream.Stream;
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlRootElement;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* Normalize with several Linear function applied to intervals.
*
* Last change $Date$
*
* @author $Author$
* @version $Revision$
*/
@XmlRootElement
@ToString
public final class MultiLinear extends NormalizationFunction {
/**
* UUID for Serializable.
*/
private static final long serialVersionUID = 4872847709393688047L;
/**
* Linear functions on the related intervals.
*/
@Getter
@Setter
@XmlElement(name = "interval")
private List<MultiLinearInterval> intervals = new ArrayList<>();
/**
* Constructor with no args for Serializable.
*/
public MultiLinear() {
// Do nothing
}
@Override
public MultiLinear clone() {
final MultiLinear clone = new MultiLinear();
if (intervals != null && !intervals.isEmpty()) {
clone.setIntervals(new ArrayList<>());
intervals.forEach(interval -> clone.getIntervals().add(interval.clone()));
}
return clone;
}
@Override
public String getFormulaMathML() {
final StringJoiner sj = new StringJoiner("\n");
sj.add("<mfenced open=\"{\" close=\"\">");
sj.add(" <mtable>");
final Stream<MultiLinearInterval> stream;
if (intervals != null) {
stream = intervals.stream();
} else {
final MultiLinearInterval interval = new MultiLinearInterval();
interval.setLinear(new Linear());
stream = Arrays.asList(interval).stream();
}
stream.filter(interval -> interval.getLinear() != null)
.forEach(interval -> {
sj.add(" <mtr>");
sj.add(" <mtd>");
sj.add(interval.getLinear().getFormulaMathML());
sj.add(" </mtd>");
sj.add(" <mtd>");
sj.add(" <mn>x</mn><mo>∈</mo><mn>[");
final Double iMin = interval.getMin();
final Double iMax = interval.getMax();
if (iMin != null) {
sj.add(iMin.toString());
} else {
sj.add("-∞");
}
sj.add("; ");
if (iMax != null) {
sj.add(iMax.toString() + "[;");
} else {
sj.add("+∞];");
}
sj.add("</mn>");
sj.add(" </mtd>");
sj.add(" </mtr>");
});
sj.add(" </mtable>");
sj.add("</mfenced>");
return sj.toString();
}
@Override
public double normalize(final double value) {
if (intervals == null || intervals.isEmpty()) {
return 0;
}
for (final MultiLinearInterval interval : intervals) {
if (interval.matches(value)) {
return interval.getLinear().normalize(value);
}
}
return 0;
}
}