main.io.github.moonlightsuite.moonlight.offline.signal.SpatialTemporalSignal Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of moonlight-engine Show documentation
Show all versions of moonlight-engine Show documentation
MoonLight is a light-weight Java-tool for monitoring temporal, spatial and spatio-temporal properties of distributed complex systems, such as Cyber-Physical Systems and Collective Adaptive Systems.
The newest version!
/*
* MoonLight: a light-weight framework for runtime monitoring
* Copyright (C) 2018-2021
*
* See the NOTICE file distributed with this work for additional information
* regarding copyright ownership.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.moonlightsuite.moonlight.offline.signal;
import io.github.moonlightsuite.moonlight.offline.algorithms.BooleanOp;
import io.github.moonlightsuite.moonlight.offline.signal.mfr.MfrSignal;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.function.ToDoubleFunction;
import java.util.stream.IntStream;
/**
* Offline spatio-temporal signal
*
* @author loreti
*/
public class SpatialTemporalSignal extends MfrSignal {
/**
* Builds an `empty` spatio-temporal signal
*
* @param size number of locations of the signal
*/
public SpatialTemporalSignal(int size) {
this(size, i -> new Signal<>());
}
/**
* Requires f
to be defined for all i < size
*
* @param size number of locations of the signal
* @param f mapping from locations to temporal signals
*/
public SpatialTemporalSignal(int size, IntFunction> f) {
super(size, f);
}
public SpatialTemporalSignal apply(BiFunction f,
SpatialTemporalSignal s) {
BooleanOp op = new BooleanOp<>();
return generate(s, i -> op.applyBinary(
getSignalAtLocation(i),
f,
s.getSignalAtLocation(i)));
}
private SpatialTemporalSignal generate(SpatialTemporalSignal s,
IntFunction> f) {
checkSize(s.getNumberOfLocations());
return new SpatialTemporalSignal<>(getNumberOfLocations(), f);
}
@Override
public Signal getSignalAtLocation(int location) {
return getSignals().get(location);
}
public SpatialTemporalSignal applyToSignal(
SpatialTemporalSignal s,
BiFunction, Signal, Signal> f) {
return generate(s, i -> f.apply(
getSignalAtLocation(i),
s.getSignalAtLocation(i)));
}
public void add(double t, T[] values) {
checkSize(values.length);
add(t, (i -> values[i]));
}
public void add(double t, IntFunction f) {
for (int i = 0; i < getNumberOfLocations(); i++) {
getSignalAtLocation(i).add(t, f.apply(i));
}
}
public void add(double time, List values) {
checkSize(values.size());
add(time, values::get);
}
@Override
public SpatialTemporalSignal apply(Function f) {
BooleanOp booleanOp = new BooleanOp<>();
return new SpatialTemporalSignal<>(getNumberOfLocations(),
i -> booleanOp.applyUnary(getSignalAtLocation(i), f));
}
public MfrSignal selectApply(Function f, int[] filter) {
BooleanOp booleanOp = new BooleanOp<>();
IntFunction> timeSignal =
i -> booleanOp.applyUnary(getSignals().get(i), f);
return new MfrSignal<>(getNumberOfLocations(), timeSignal, filter);
}
public List valuesAtT(double t) {
List values = new ArrayList<>(getNumberOfLocations());
getSignals().forEach(s -> values.add(s.getValueAt(t)));
return values;
}
public SpatialTemporalSignal applyToSignal(Function,
Signal> f) {
return new SpatialTemporalSignal<>(getNumberOfLocations(),
(i -> f.apply(getSignalAtLocation(i))));
}
@Override
public ParallelSignalCursor getSignalCursor(boolean forward) {
return new ParallelSignalCursor<>(getNumberOfLocations(),
(i -> getSignalAtLocation(i).getIterator(forward)));
}
public double start() {
double start = Double.NEGATIVE_INFINITY;
for (Signal signal : getSignals()) {
start = Math.max(start, signal.getStart());
}
return start;
}
public double end() {
double end = Double.POSITIVE_INFINITY;
for (Signal signal : getSignals()) {
end = Math.min(end, signal.getEnd());
}
return end;
}
/**
* Returns a 3d-array from a conversion-to-double function
*
* @param f function to transform the type of the array T to Double
* @return a 3d-double-array of [locations][time point][value]
*/
public double[][][] toArray(ToDoubleFunction f) {
int locs = getNumberOfLocations();
double[] timePoints = getTimeArray();
double[][][] toReturn = new double[locs][][];
IntStream.range(0, locs)
.forEach(i ->
toReturn[i] = getSignalAtLocation(i).arrayOf(timePoints, f));
return toReturn;
}
public double[] getTimeArray() {
Set timeSet = new HashSet<>();
getSignals().forEach(s -> timeSet.addAll(s.getTimeSet()));
return timeSet.stream().sorted()
.distinct()
.mapToDouble(d -> d).toArray();
}
public void fill(double[] timePoints, R[][] data, Function f) {
for (int i = 0; i < getNumberOfLocations(); i++) {
getSignalAtLocation(i).fill(timePoints, data[i], f);
}
}
}