Преобразуйте кусочную функцию в файл CSV, используя Java
Я пытаюсь создать функцию Java, которая будет преобразовывать строку, содержащую кусочную функцию, в файл CSV, который можно использовать для построения графиков. Например это выражение:
if (time < 60) then (0.1) else ( if (time > 66.0115) then (0.1) else 1)
будет преобразован в:
File pwl.csv
time , output
0 , 0.1
59.9, 0.1
60, 1
66.0115, 1
66.11149999999999, 0.1
132.023, 0.1
End File
Преобразователь должен уметь выполнять множество кусочных функций, в том числе:
if (t > 0.5) then (2) else 3
if (t >= 0.5) then (2) else 3
if (t < 0.5) then (2) else 3
if (t <= 0.5) then (2) else 3
if ((t >= 3600) & (t <= 3660)) then (25) else 0
Мне удалось написать код, который преобразовал первый пример, но он действительно работает только для этой конкретной функции, и я ищу более общее решение. Есть мысли по поводу проблемы?
Эти кусочные функции изначально пришли из файла MathML, поэтому любые предложения по прямому преобразованию из MathML в CSV также приветствуются.
1 ответ
Решение
Это похоже на работу - вроде. В любом случае, это было бы хорошим началом.
public class CSVFun {
// Where to start the scan of the function.
static final double Start = 0.0;
// End of scan.
static final double End = 10000.0;
// Fine enough to detect a change in the function.
static final double BigStep = 0.1;
// Finest resolution.
static final double SmallStep = 0.000000001;
// Work out some csv for a function.
private static void csv(F f) {
System.out.println("Function: " + f);
// Start at 0.
double t = Start;
double ft = f.f(t);
System.out.println(t + "," + ft);
while (t < End) {
// Walk to the end.
double step = BigStep;
// Find a break point.
while (t < End && f.f(t) == ft) {
t += step;
}
if (t < End) {
// Back one.
t -= step;
// Zoom in on the transition point.
while (step > SmallStep) {
// Go smaller.
step /= 10;
// Walk forward.
while (t < End && f.f(t) == ft) {
t += step;
}
// Back one.
t -= step;
}
// Before
System.out.println(t + "," + ft);
// One more forward.
t += step;
}
// Print.
if (f.f(t) != ft) {
ft = f.f(t);
System.out.println(t + "," + ft);
}
}
}
// Tests the process with the sample functions below.
public static void main(String[] args) {
try {
for (F f : F.values()) {
csv(f);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
// The sample functions - Encoded in Java
enum F {
A {
@Override
double f(double t) {
if (t < 60) {
return (0.1);
}
if (t > 66.0115) {
return (0.1);
}
return 1;
}
},
B {
@Override
double f(double t) {
if (t > 0.5) {
return 2;
}
return 3;
}
},
C {
@Override
double f(double t) {
if (t >= 0.5) {
return 2;
}
return 3;
}
},
D {
@Override
double f(double t) {
if (t < 0.5) {
return 2;
}
return 3;
}
},
E {
@Override
double f(double t) {
if (t <= 0.5) {
return 2;
}
return 3;
}
},
F {
@Override
double f(double t) {
if ((t >= 3600) & (t <= 3660)) {
return 25;
}
return 0;
}
},;
abstract double f(double t);
}
}
Выход:
Function: A
0.0,0.1
59.999999999000565,0.1
60.00000000000056,1.0
66.01149999900045,1.0
66.01150000000045,0.1
Function: B
0.0,3.0
0.49999999999999994,3.0
0.500000001,2.0
Function: C
0.0,3.0
0.49999999999999983,3.0
0.5000000009999999,2.0
Function: D
0.0,2.0
0.49999999999999983,2.0
0.5000000009999999,3.0
Function: E
0.0,2.0
0.49999999999999994,2.0
0.500000001,3.0
Function: F
0.0,0.0
3599.9999999998213,0.0
3600.0000000008213,25.0
3659.999999999771,25.0
3660.000000000771,0.0
Что близко, я думаю.