Code cleanup

This commit is contained in:
Andrea Cavalli 2018-09-28 11:39:28 +02:00
parent 0e83ad6ee6
commit 60cb012f83
94 changed files with 2337 additions and 1457 deletions

View File

@ -45,9 +45,9 @@ public class Engine {
public static void start(final Platform platform, final Screen screen, final HardwareDisplay disp, public static void start(final Platform platform, final Screen screen, final HardwareDisplay disp,
final HardwareTouchDevice touchdevice, final HUD hud, final StartupArguments args) final HardwareTouchDevice touchdevice, final HUD hud, final StartupArguments args)
throws InterruptedException, IOException { throws InterruptedException, IOException {
if (Engine.running) if (Engine.running) {
throw new RuntimeException("Already running!"); throw new RuntimeException("Already running!");
else { } else {
Engine.running = true; Engine.running = true;
Engine.INSTANCE.startInstance(platform, screen, disp, touchdevice, hud, args); Engine.INSTANCE.startInstance(platform, screen, disp, touchdevice, hud, args);
} }
@ -84,8 +84,9 @@ public class Engine {
ClassUtils.classLoader = this.getClass(); ClassUtils.classLoader = this.getClass();
StaticVars.startupArguments = args; StaticVars.startupArguments = args;
StaticVars.debugWindow2x = args.isZoomed(); StaticVars.debugWindow2x = args.isZoomed();
if (args.isVerboseLoggingEnabled() || args.isDebugEnabled()) if (args.isVerboseLoggingEnabled() || args.isDebugEnabled()) {
StaticVars.outputLevel = ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE; StaticVars.outputLevel = ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE;
}
Engine.platform.getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN, args); Engine.platform.getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN, args);
checkDeviceType(); checkDeviceType();
if (Engine.getPlatform().isRunningOnRaspberry() && args.isRaspberryModeAllowed()) { if (Engine.getPlatform().isRunningOnRaspberry() && args.isRaspberryModeAllowed()) {

View File

@ -17,10 +17,11 @@ public class StaticVars {
public static boolean debugWindow2x = false; public static boolean debugWindow2x = false;
public static BehaviorSubject<Float> windowZoom = BehaviorSubject.create(2F); public static BehaviorSubject<Float> windowZoom = BehaviorSubject.create(2F);
public static Function<Float, Float> windowZoomFunction = (val) -> { public static Function<Float, Float> windowZoomFunction = (val) -> {
if (StaticVars.debugWindow2x) if (StaticVars.debugWindow2x) {
return val + 1; return val + 1;
else } else {
return val; return val;
}
}; };
public static Observable<Float> windowZoom$ = StaticVars.windowZoom.map(StaticVars.windowZoomFunction); public static Observable<Float> windowZoom$ = StaticVars.windowZoom.map(StaticVars.windowZoomFunction);
public static StartupArguments startupArguments; public static StartupArguments startupArguments;

View File

@ -5,15 +5,17 @@ public class TestDrivers {
System.out.println("Test started."); System.out.println("Test started.");
String className; String className;
className = "jogamp.newt.driver.bcm.vc.iv.DisplayDriver"; className = "jogamp.newt.driver.bcm.vc.iv.DisplayDriver";
if (TestDrivers.exists(className)) if (TestDrivers.exists(className)) {
System.out.println("[FOUND] " + className); System.out.println("[FOUND] " + className);
else } else {
System.out.println("[NOT FOUND] " + className); System.out.println("[NOT FOUND] " + className);
}
className = ".bcm.vc.iv.DisplayDriver"; className = ".bcm.vc.iv.DisplayDriver";
if (TestDrivers.exists(className)) if (TestDrivers.exists(className)) {
System.out.println("[FOUND] " + className); System.out.println("[FOUND] " + className);
else } else {
System.out.println("[NOT FOUND] " + className); System.out.println("[NOT FOUND] " + className);
}
System.out.println("Test finished."); System.out.println("Test finished.");
} }

View File

@ -85,11 +85,11 @@ public class StartupArgumentsImpl implements StartupArguments {
void setZoomed(final boolean isZoomed) { void setZoomed(final boolean isZoomed) {
this.isZoomed = isZoomed; this.isZoomed = isZoomed;
} }
void setCPUEngineForced(final boolean isCPUEngineForced) { void setCPUEngineForced(final boolean isCPUEngineForced) {
this.isCPUEngineForced = isCPUEngineForced; this.isCPUEngineForced = isCPUEngineForced;
} }
void setGPUEngineForced(final boolean isGPUEngineForced) { void setGPUEngineForced(final boolean isGPUEngineForced) {
this.isGPUEngineForced = isGPUEngineForced; this.isGPUEngineForced = isGPUEngineForced;
} }
@ -124,12 +124,7 @@ public class StartupArgumentsImpl implements StartupArguments {
@Override @Override
public String toString() { public String toString() {
return "StartupArgumentsImpl [isRaspberryModeAllowed=" + isRaspberryModeAllowed + ", isZoomed=" + isZoomed return "StartupArgumentsImpl [isRaspberryModeAllowed=" + isRaspberryModeAllowed + ", isZoomed=" + isZoomed + ", isCPUEngineForced=" + isCPUEngineForced + ", isGPUEngineForced=" + isGPUEngineForced + ", isFrameBufferEngineForced=" + isFrameBufferEngineForced + ", isNoGUIEngineForced=" + isNoGUIEngineForced + ", isHTMLEngineForced=" + isHTMLEngineForced + ", isMSDOSModeEnabled=" + isMSDOSModeEnabled + ", isVerboseLoggingEnabled=" + isVerboseLoggingEnabled + ", isDebugEnabled=" + isDebugEnabled + ", isUncached=" + isUncached + "]";
+ ", isCPUEngineForced=" + isCPUEngineForced + ", isGPUEngineForced=" + isGPUEngineForced
+ ", isFrameBufferEngineForced=" + isFrameBufferEngineForced + ", isNoGUIEngineForced="
+ isNoGUIEngineForced + ", isHTMLEngineForced=" + isHTMLEngineForced + ", isMSDOSModeEnabled="
+ isMSDOSModeEnabled + ", isVerboseLoggingEnabled=" + isVerboseLoggingEnabled + ", isDebugEnabled="
+ isDebugEnabled + ", isUncached=" + isUncached + "]";
} }
} }

View File

@ -18,9 +18,9 @@ public class CacheFile {
private FileInputStream lastFIS; private FileInputStream lastFIS;
public CacheFile() { public CacheFile() {
do do {
path = UUID.randomUUID().toString() + ".ser"; path = UUID.randomUUID().toString() + ".ser";
while (new File(path).exists()); } while (new File(path).exists());
try { try {
File.createTempFile(Engine.getPlatform().getSettings().getCalculatorNameLowercase(), ""); File.createTempFile(Engine.getPlatform().getSettings().getCalculatorNameLowercase(), "");
} catch (final IOException e) { } catch (final IOException e) {
@ -29,26 +29,28 @@ public class CacheFile {
} }
public ObjectOutputStream getObjectOutputStram() { public ObjectOutputStream getObjectOutputStram() {
if (lastOOS == null) if (lastOOS == null) {
try { try {
return new ObjectOutputStream(new FileOutputStream(path)); return new ObjectOutputStream(new FileOutputStream(path));
} catch (final IOException e) { } catch (final IOException e) {
e.printStackTrace(); e.printStackTrace();
return lastOOS; return lastOOS;
} }
else } else {
return lastOOS; return lastOOS;
}
} }
public ObjectInputStream getObjectInputStram() { public ObjectInputStream getObjectInputStram() {
if (lastOIS == null) if (lastOIS == null) {
try { try {
return new ObjectInputStream(new FileInputStream(path)); return new ObjectInputStream(new FileInputStream(path));
} catch (final IOException e) { } catch (final IOException e) {
return lastOIS; return lastOIS;
} }
else } else {
return lastOIS; return lastOIS;
}
} }
public void closeStreams() { public void closeStreams() {

View File

@ -41,7 +41,7 @@ public class Keyboard {
public synchronized void startKeyboard() { public synchronized void startKeyboard() {
final Thread kt = new Thread(() -> { final Thread kt = new Thread(() -> {
if (Engine.getPlatform().getSettings().isDebugEnabled()) if (Engine.getPlatform().getSettings().isDebugEnabled()) {
try { try {
while (true) { while (true) {
if (Keyboard.debugKeyCode != -1) { if (Keyboard.debugKeyCode != -1) {
@ -55,7 +55,7 @@ public class Keyboard {
Thread.sleep(50); Thread.sleep(50);
} }
} catch (final InterruptedException e) {} } catch (final InterruptedException e) {}
else { } else {
Engine.getPlatform().getGpio().pinMode(Keyboard.CLK_INH_pin, Engine.getPlatform().getGpio().valueOutput()); Engine.getPlatform().getGpio().pinMode(Keyboard.CLK_INH_pin, Engine.getPlatform().getGpio().valueOutput());
Engine.getPlatform().getGpio().pinMode(Keyboard.RCK_pin, Engine.getPlatform().getGpio().valueOutput()); Engine.getPlatform().getGpio().pinMode(Keyboard.RCK_pin, Engine.getPlatform().getGpio().valueOutput());
Engine.getPlatform().getGpio().pinMode(Keyboard.SER_pin, Engine.getPlatform().getGpio().valueOutput()); Engine.getPlatform().getGpio().pinMode(Keyboard.SER_pin, Engine.getPlatform().getGpio().valueOutput());
@ -85,12 +85,13 @@ public class Keyboard {
// KeyboardDebugScreen.ks[col] = data; // KeyboardDebugScreen.ks[col] = data;
for (int row = 0; row < 8; row++) { for (int row = 0; row < 8; row++) {
if (data[row] == true && Keyboard.precedentStates[row][col] == false) if (data[row] == true && Keyboard.precedentStates[row][col] == false) {
// System.out.println("Pressed button at " + (row + 1) + ", " + (col + 1)); // System.out.println("Pressed button at " + (row + 1) + ", " + (col + 1));
// KeyboardDebugScreen.log("Pressed button at " + (row + 1) + ", " + (col + 1)); // KeyboardDebugScreen.log("Pressed button at " + (row + 1) + ", " + (col + 1));
Keyboard.keyPressedRaw(row, col); Keyboard.keyPressedRaw(row, col);
else if (data[row] == false && Keyboard.precedentStates[row][col] == true) } else if (data[row] == false && Keyboard.precedentStates[row][col] == true) {
Keyboard.keyReleasedRaw(row, col); Keyboard.keyReleasedRaw(row, col);
}
// KeyboardDebugScreen.log("Released button at " + (row + 1) + ", " + (col + 1)); // KeyboardDebugScreen.log("Released button at " + (row + 1) + ", " + (col + 1));
Keyboard.precedentStates[row][col] = data[row]; Keyboard.precedentStates[row][col] = data[row];
} }
@ -110,223 +111,253 @@ public class Keyboard {
Keyboard.keyPressed(Key.POWEROFF); Keyboard.keyPressed(Key.POWEROFF);
break; break;
case KeyEvent.VK_S: case KeyEvent.VK_S:
if (Keyboard.shift) if (Keyboard.shift) {
Keyboard.keyPressed(Key.ARCSINE); Keyboard.keyPressed(Key.ARCSINE);
else if (Keyboard.alpha) } else if (Keyboard.alpha) {
Keyboard.keyPressed(Key.LETTER_S); Keyboard.keyPressed(Key.LETTER_S);
else } else {
Keyboard.keyPressed(Key.SINE); Keyboard.keyPressed(Key.SINE);
}
break; break;
case KeyEvent.VK_C: case KeyEvent.VK_C:
if (Keyboard.shift) if (Keyboard.shift) {
Keyboard.keyPressed(Key.ARCCOSINE); Keyboard.keyPressed(Key.ARCCOSINE);
else if (Keyboard.alpha) } else if (Keyboard.alpha) {
Keyboard.keyPressed(Key.LETTER_C); Keyboard.keyPressed(Key.LETTER_C);
else } else {
Keyboard.keyPressed(Key.COSINE); Keyboard.keyPressed(Key.COSINE);
}
break; break;
case KeyEvent.VK_T: case KeyEvent.VK_T:
if (Keyboard.shift) if (Keyboard.shift) {
Keyboard.keyPressed(Key.ARCTANGENT); Keyboard.keyPressed(Key.ARCTANGENT);
else if (Keyboard.alpha) } else if (Keyboard.alpha) {
Keyboard.keyPressed(Key.LETTER_T); Keyboard.keyPressed(Key.LETTER_T);
else } else {
Keyboard.keyPressed(Key.TANGENT); Keyboard.keyPressed(Key.TANGENT);
}
break; break;
case KeyEvent.VK_D: case KeyEvent.VK_D:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.debug_DEG); Keyboard.keyPressed(Key.debug_DEG);
else if (Keyboard.alpha) } else if (Keyboard.alpha) {
Keyboard.keyPressed(Key.LETTER_D); Keyboard.keyPressed(Key.LETTER_D);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_R: case KeyEvent.VK_R:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.debug_RAD); Keyboard.keyPressed(Key.debug_RAD);
else if (Keyboard.alpha) } else if (Keyboard.alpha) {
Keyboard.keyPressed(Key.LETTER_R); Keyboard.keyPressed(Key.LETTER_R);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_G: case KeyEvent.VK_G:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.debug_GRA); Keyboard.keyPressed(Key.debug_GRA);
else if (Keyboard.alpha) } else if (Keyboard.alpha) {
Keyboard.keyPressed(Key.LETTER_G); Keyboard.keyPressed(Key.LETTER_G);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_X: case KeyEvent.VK_X:
if (Keyboard.alpha) if (Keyboard.alpha) {
Keyboard.keyPressed(Key.LETTER_X); Keyboard.keyPressed(Key.LETTER_X);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_P: case KeyEvent.VK_P:
if (Keyboard.shift) if (Keyboard.shift) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else if (Keyboard.alpha) } else if (Keyboard.alpha) {
Keyboard.keyPressed(Key.LETTER_P); Keyboard.keyPressed(Key.LETTER_P);
else } else {
Keyboard.keyPressed(Key.PI); Keyboard.keyPressed(Key.PI);
}
break; break;
case KeyEvent.VK_E: case KeyEvent.VK_E:
if (Keyboard.shift) if (Keyboard.shift) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else if (Keyboard.alpha) } else if (Keyboard.alpha) {
Keyboard.keyPressed(Key.LETTER_E); Keyboard.keyPressed(Key.LETTER_E);
else } else {
Keyboard.keyPressed(Key.EULER_NUMBER); Keyboard.keyPressed(Key.EULER_NUMBER);
}
break; break;
case KeyEvent.VK_Y: case KeyEvent.VK_Y:
if (Keyboard.alpha) if (Keyboard.alpha) {
Keyboard.keyPressed(Key.LETTER_Y); Keyboard.keyPressed(Key.LETTER_Y);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_B: case KeyEvent.VK_B:
if (Keyboard.shift) if (Keyboard.shift) {
Keyboard.keyPressed(Key.BRIGHTNESS_CYCLE_REVERSE); Keyboard.keyPressed(Key.BRIGHTNESS_CYCLE_REVERSE);
else if (!Keyboard.shift && !Keyboard.alpha) } else if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.BRIGHTNESS_CYCLE); Keyboard.keyPressed(Key.BRIGHTNESS_CYCLE);
else } else {
Keyboard.keyPressed(Key.LETTER_B); Keyboard.keyPressed(Key.LETTER_B);
}
break; break;
case KeyEvent.VK_L: case KeyEvent.VK_L:
if (Keyboard.shift) if (Keyboard.shift) {
Keyboard.keyPressed(Key.LOGARITHM); Keyboard.keyPressed(Key.LOGARITHM);
else if (Keyboard.alpha) } else if (Keyboard.alpha) {
Keyboard.keyPressed(Key.LETTER_L); Keyboard.keyPressed(Key.LETTER_L);
else } else {
Keyboard.keyPressed(Key.LOGARITHM); Keyboard.keyPressed(Key.LOGARITHM);
}
break; break;
case KeyboardJogampValues.VK_ENTER: case KeyboardJogampValues.VK_ENTER:
case KeyEvent.VK_ENTER: case KeyEvent.VK_ENTER:
if (Keyboard.shift) if (Keyboard.shift) {
Keyboard.keyPressed(Key.STEP); Keyboard.keyPressed(Key.STEP);
else if (!Keyboard.shift && !Keyboard.alpha) } else if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.SIMPLIFY); Keyboard.keyPressed(Key.SIMPLIFY);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
int row = 2; int row = 2;
int col = 1; int col = 1;
Keyboard.debugKeysDown[row - 1][col - 1] = true; Keyboard.debugKeysDown[row - 1][col - 1] = true;
break; break;
case KeyEvent.VK_1: case KeyEvent.VK_1:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NUM1); Keyboard.keyPressed(Key.NUM1);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_2: case KeyEvent.VK_2:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NUM2); Keyboard.keyPressed(Key.NUM2);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_3: case KeyEvent.VK_3:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NUM3); Keyboard.keyPressed(Key.NUM3);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_4: case KeyEvent.VK_4:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NUM4); Keyboard.keyPressed(Key.NUM4);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_5: case KeyEvent.VK_5:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NUM5); Keyboard.keyPressed(Key.NUM5);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_6: case KeyEvent.VK_6:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NUM6); Keyboard.keyPressed(Key.NUM6);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_7: case KeyEvent.VK_7:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NUM7); Keyboard.keyPressed(Key.NUM7);
else if (Keyboard.shift) } else if (Keyboard.shift) {
if (Engine.getPlatform().getSettings().isDebugEnabled()) if (Engine.getPlatform().getSettings().isDebugEnabled()) {
Keyboard.keyPressed(Key.DIVIDE); Keyboard.keyPressed(Key.DIVIDE);
}
}
break; break;
case KeyEvent.VK_8: case KeyEvent.VK_8:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NUM8); Keyboard.keyPressed(Key.NUM8);
else if (Keyboard.shift) } else if (Keyboard.shift) {
Keyboard.keyPressed(Key.PARENTHESIS_OPEN); Keyboard.keyPressed(Key.PARENTHESIS_OPEN);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_9: case KeyEvent.VK_9:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NUM9); Keyboard.keyPressed(Key.NUM9);
else if (Keyboard.shift) } else if (Keyboard.shift) {
Keyboard.keyPressed(Key.PARENTHESIS_CLOSE); Keyboard.keyPressed(Key.PARENTHESIS_CLOSE);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_0: case KeyEvent.VK_0:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NUM0); Keyboard.keyPressed(Key.NUM0);
else if (Keyboard.shift) } else if (Keyboard.shift) {
Keyboard.keyPressed(Key.EQUAL); Keyboard.keyPressed(Key.EQUAL);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_M: case KeyEvent.VK_M:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.SURD_MODE); Keyboard.keyPressed(Key.SURD_MODE);
else if (Keyboard.shift) } else if (Keyboard.shift) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else } else {
Keyboard.keyPressed(Key.LETTER_M); Keyboard.keyPressed(Key.LETTER_M);
}
break; break;
case KeyboardJogampValues.VK_ADD: case KeyboardJogampValues.VK_ADD:
case KeyEvent.VK_ADD: case KeyEvent.VK_ADD:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.PLUS); Keyboard.keyPressed(Key.PLUS);
else if (Keyboard.shift) } else if (Keyboard.shift) {
Keyboard.keyPressed(Key.PLUS_MINUS); Keyboard.keyPressed(Key.PLUS_MINUS);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyboardJogampValues.VK_SUBTRACT: case KeyboardJogampValues.VK_SUBTRACT:
case KeyEvent.VK_SUBTRACT: case KeyEvent.VK_SUBTRACT:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.MINUS); Keyboard.keyPressed(Key.MINUS);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyboardJogampValues.VK_MULTIPLY: case KeyboardJogampValues.VK_MULTIPLY:
case KeyEvent.VK_MULTIPLY: case KeyEvent.VK_MULTIPLY:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.MULTIPLY); Keyboard.keyPressed(Key.MULTIPLY);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyboardJogampValues.VK_DIVIDE: case KeyboardJogampValues.VK_DIVIDE:
case KeyEvent.VK_DIVIDE: case KeyEvent.VK_DIVIDE:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.DIVIDE); Keyboard.keyPressed(Key.DIVIDE);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_BACK_SPACE: case KeyEvent.VK_BACK_SPACE:
Keyboard.keyPressed(Key.DELETE); Keyboard.keyPressed(Key.DELETE);
break; break;
case KeyboardJogampValues.VK_DELETE: case KeyboardJogampValues.VK_DELETE:
case KeyEvent.VK_DELETE: case KeyEvent.VK_DELETE:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.RESET); Keyboard.keyPressed(Key.RESET);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyboardJogampValues.VK_LEFT: case KeyboardJogampValues.VK_LEFT:
case KeyEvent.VK_LEFT: case KeyEvent.VK_LEFT:
@ -334,10 +365,11 @@ public class Keyboard {
row = 2; row = 2;
col = 3; col = 3;
Keyboard.debugKeysDown[row - 1][col - 1] = true; Keyboard.debugKeysDown[row - 1][col - 1] = true;
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.LEFT); Keyboard.keyPressed(Key.LEFT);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyboardJogampValues.VK_RIGHT: case KeyboardJogampValues.VK_RIGHT:
case KeyEvent.VK_RIGHT: case KeyEvent.VK_RIGHT:
@ -345,10 +377,11 @@ public class Keyboard {
row = 2; row = 2;
col = 5; col = 5;
Keyboard.debugKeysDown[row - 1][col - 1] = true; Keyboard.debugKeysDown[row - 1][col - 1] = true;
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.RIGHT); Keyboard.keyPressed(Key.RIGHT);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyboardJogampValues.VK_UP: case KeyboardJogampValues.VK_UP:
case KeyEvent.VK_UP: case KeyEvent.VK_UP:
@ -356,10 +389,11 @@ public class Keyboard {
row = 1; row = 1;
col = 4; col = 4;
Keyboard.debugKeysDown[row - 1][col - 1] = true; Keyboard.debugKeysDown[row - 1][col - 1] = true;
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.UP); Keyboard.keyPressed(Key.UP);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyboardJogampValues.VK_DOWN: case KeyboardJogampValues.VK_DOWN:
case KeyEvent.VK_DOWN: case KeyEvent.VK_DOWN:
@ -367,170 +401,188 @@ public class Keyboard {
row = 3; row = 3;
col = 4; col = 4;
Keyboard.debugKeysDown[row - 1][col - 1] = true; Keyboard.debugKeysDown[row - 1][col - 1] = true;
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.DOWN); Keyboard.keyPressed(Key.DOWN);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case (short) 12: case (short) 12:
//DOWN //DOWN
row = 2; row = 2;
col = 4; col = 4;
Keyboard.debugKeysDown[row - 1][col - 1] = true; Keyboard.debugKeysDown[row - 1][col - 1] = true;
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.OK); Keyboard.keyPressed(Key.OK);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyboardJogampValues.VK_NUMPAD4: case KeyboardJogampValues.VK_NUMPAD4:
case KeyEvent.VK_NUMPAD4: case KeyEvent.VK_NUMPAD4:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.HISTORY_BACK); Keyboard.keyPressed(Key.HISTORY_BACK);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyboardJogampValues.VK_NUMPAD6: case KeyboardJogampValues.VK_NUMPAD6:
case KeyEvent.VK_NUMPAD6: case KeyEvent.VK_NUMPAD6:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.HISTORY_FORWARD); Keyboard.keyPressed(Key.HISTORY_FORWARD);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_PERIOD: case KeyEvent.VK_PERIOD:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.DOT); Keyboard.keyPressed(Key.DOT);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_A: case KeyEvent.VK_A:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else if (Keyboard.alpha && !Keyboard.shift) } else if (Keyboard.alpha && !Keyboard.shift) {
Keyboard.keyPressed(Key.LETTER_A); Keyboard.keyPressed(Key.LETTER_A);
else if (Keyboard.shift && !Keyboard.alpha) } else if (Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_F: case KeyEvent.VK_F:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else if (Keyboard.alpha && !Keyboard.shift) } else if (Keyboard.alpha && !Keyboard.shift) {
Keyboard.keyPressed(Key.LETTER_F); Keyboard.keyPressed(Key.LETTER_F);
else if (Keyboard.shift && !Keyboard.alpha) } else if (Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_H: case KeyEvent.VK_H:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else if (Keyboard.alpha && !Keyboard.shift) } else if (Keyboard.alpha && !Keyboard.shift) {
Keyboard.keyPressed(Key.LETTER_H); Keyboard.keyPressed(Key.LETTER_H);
else if (Keyboard.shift && !Keyboard.alpha) } else if (Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_I: case KeyEvent.VK_I:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else if (Keyboard.alpha && !Keyboard.shift) } else if (Keyboard.alpha && !Keyboard.shift) {
Keyboard.keyPressed(Key.LETTER_I); Keyboard.keyPressed(Key.LETTER_I);
else if (Keyboard.shift && !Keyboard.alpha) } else if (Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_J: case KeyEvent.VK_J:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else if (Keyboard.alpha && !Keyboard.shift) } else if (Keyboard.alpha && !Keyboard.shift) {
Keyboard.keyPressed(Key.LETTER_J); Keyboard.keyPressed(Key.LETTER_J);
else if (Keyboard.shift && !Keyboard.alpha) } else if (Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_K: case KeyEvent.VK_K:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else if (Keyboard.alpha && !Keyboard.shift) } else if (Keyboard.alpha && !Keyboard.shift) {
Keyboard.keyPressed(Key.LETTER_K); Keyboard.keyPressed(Key.LETTER_K);
else if (Keyboard.shift && !Keyboard.alpha) } else if (Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_N: case KeyEvent.VK_N:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else if (Keyboard.alpha && !Keyboard.shift) } else if (Keyboard.alpha && !Keyboard.shift) {
Keyboard.keyPressed(Key.LETTER_N); Keyboard.keyPressed(Key.LETTER_N);
else if (Keyboard.shift && !Keyboard.alpha) } else if (Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_O: case KeyEvent.VK_O:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else if (Keyboard.alpha && !Keyboard.shift) } else if (Keyboard.alpha && !Keyboard.shift) {
Keyboard.keyPressed(Key.LETTER_O); Keyboard.keyPressed(Key.LETTER_O);
else if (Keyboard.shift && !Keyboard.alpha) } else if (Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_Q: case KeyEvent.VK_Q:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else if (Keyboard.alpha && !Keyboard.shift) } else if (Keyboard.alpha && !Keyboard.shift) {
Keyboard.keyPressed(Key.LETTER_Q); Keyboard.keyPressed(Key.LETTER_Q);
else if (Keyboard.shift && !Keyboard.alpha) } else if (Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_U: case KeyEvent.VK_U:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else if (Keyboard.alpha && !Keyboard.shift) } else if (Keyboard.alpha && !Keyboard.shift) {
Keyboard.keyPressed(Key.LETTER_U); Keyboard.keyPressed(Key.LETTER_U);
else if (Keyboard.shift && !Keyboard.alpha) } else if (Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_V: case KeyEvent.VK_V:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else if (Keyboard.alpha && !Keyboard.shift) } else if (Keyboard.alpha && !Keyboard.shift) {
Keyboard.keyPressed(Key.LETTER_V); Keyboard.keyPressed(Key.LETTER_V);
else if (Keyboard.shift && !Keyboard.alpha) } else if (Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_W: case KeyEvent.VK_W:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else if (Keyboard.alpha && !Keyboard.shift) } else if (Keyboard.alpha && !Keyboard.shift) {
Keyboard.keyPressed(Key.LETTER_W); Keyboard.keyPressed(Key.LETTER_W);
else if (Keyboard.shift && !Keyboard.alpha) } else if (Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyEvent.VK_Z: case KeyEvent.VK_Z:
if (!Keyboard.shift && !Keyboard.alpha) if (!Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
else if (Keyboard.alpha && !Keyboard.shift) } else if (Keyboard.alpha && !Keyboard.shift) {
Keyboard.keyPressed(Key.LETTER_Z); Keyboard.keyPressed(Key.LETTER_Z);
else if (Keyboard.shift && !Keyboard.alpha) } else if (Keyboard.shift && !Keyboard.alpha) {
Keyboard.keyPressed(Key.ZOOM_MODE); Keyboard.keyPressed(Key.ZOOM_MODE);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
break; break;
case KeyboardJogampValues.VK_SHIFT: case KeyboardJogampValues.VK_SHIFT:
case KeyEvent.VK_SHIFT: case KeyEvent.VK_SHIFT:
@ -604,10 +656,11 @@ public class Keyboard {
} }
public static boolean isKeyDown(final int row, final int col) { public static boolean isKeyDown(final int row, final int col) {
if (Engine.getPlatform().getSettings().isDebugEnabled() == false) if (Engine.getPlatform().getSettings().isDebugEnabled() == false) {
return Keyboard.precedentStates[row - 1][col - 1]; return Keyboard.precedentStates[row - 1][col - 1];
else } else {
return Keyboard.debugKeysDown[row - 1][col - 1]; return Keyboard.debugKeysDown[row - 1][col - 1];
}
} }
public synchronized static void keyReleasedRaw(final int row, final int col) { public synchronized static void keyReleasedRaw(final int row, final int col) {
@ -775,32 +828,37 @@ public class Keyboard {
public static String getKeyName(final int row, final int col, final boolean shift, final boolean alpha) { public static String getKeyName(final int row, final int col, final boolean shift, final boolean alpha) {
final String[] keyValues = Keyboard.KeyLabelsMap[row][col]; final String[] keyValues = Keyboard.KeyLabelsMap[row][col];
if (shift) { if (shift) {
if (keyValues[1] != null) if (keyValues[1] != null) {
return keyValues[1]; return keyValues[1];
} else if (alpha) }
if (keyValues[2] != null) } else if (alpha) {
if (keyValues[2] != null) {
return keyValues[2]; return keyValues[2];
}
}
return keyValues[0]; return keyValues[0];
} }
public static boolean hasKeyName(final int row, final int col) { public static boolean hasKeyName(final int row, final int col) {
final String[] keyValues = Keyboard.KeyLabelsMap[row][col]; final String[] keyValues = Keyboard.KeyLabelsMap[row][col];
if (Keyboard.shift) if (Keyboard.shift) {
return keyValues[1] != null; return keyValues[1] != null;
else if (Keyboard.alpha) } else if (Keyboard.alpha) {
return keyValues[2] != null; return keyValues[2] != null;
else } else {
return true; return true;
}
} }
public static synchronized void keyPressedRaw(final int row, final int col) { public static synchronized void keyPressedRaw(final int row, final int col) {
// KeyboardDebugScreen.keyX = row; // KeyboardDebugScreen.keyX = row;
// KeyboardDebugScreen.keyY = col; // KeyboardDebugScreen.keyY = col;
final Key k = Keyboard.keyMap[row][col][Keyboard.shift ? 1 : Keyboard.alpha ? 2 : 0]; final Key k = Keyboard.keyMap[row][col][Keyboard.shift ? 1 : Keyboard.alpha ? 2 : 0];
if (k != null) if (k != null) {
Keyboard.keyPressed(k); Keyboard.keyPressed(k);
else } else {
Keyboard.keyPressed(Key.NONE); Keyboard.keyPressed(Key.NONE);
}
} }
public static void stopKeyboard() { public static void stopKeyboard() {
@ -816,12 +874,13 @@ public class Keyboard {
public synchronized static void keyPressed(final Key k) { public synchronized static void keyPressed(final Key k) {
boolean done = false; boolean done = false;
if (Keyboard.additionalListener != null) if (Keyboard.additionalListener != null) {
try { try {
done = Keyboard.additionalListener.onKeyPressed(new KeyPressedEvent(k)); done = Keyboard.additionalListener.onKeyPressed(new KeyPressedEvent(k));
} catch (final Exception ex) { } catch (final Exception ex) {
new GUIErrorMessage(ex); new GUIErrorMessage(ex);
} }
}
if (Engine.INSTANCE.getHardwareDevice().getDisplayManager() != null) { if (Engine.INSTANCE.getHardwareDevice().getDisplayManager() != null) {
final Screen scr = Engine.INSTANCE.getHardwareDevice().getDisplayManager().getScreen(); final Screen scr = Engine.INSTANCE.getHardwareDevice().getDisplayManager().getScreen();
boolean refresh = false; boolean refresh = false;
@ -831,9 +890,9 @@ public class Keyboard {
} catch (final Exception ex) { } catch (final Exception ex) {
new GUIErrorMessage(ex); new GUIErrorMessage(ex);
} }
if (scr != null && scr.initialized && scrdone) if (scr != null && scr.initialized && scrdone) {
refresh = true; refresh = true;
else } else {
switch (k) { switch (k) {
case POWEROFF: case POWEROFF:
Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.destroy(); Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.destroy();
@ -866,54 +925,65 @@ public class Keyboard {
default: default:
break; break;
} }
}
switch (k) { switch (k) {
case SHIFT: case SHIFT:
if (Keyboard.alpha) if (Keyboard.alpha) {
Engine.getPlatform().alphaChanged(Keyboard.alpha = false); Engine.getPlatform().alphaChanged(Keyboard.alpha = false);
}
Engine.getPlatform().shiftChanged(Keyboard.shift = !Keyboard.shift); Engine.getPlatform().shiftChanged(Keyboard.shift = !Keyboard.shift);
refresh = true; refresh = true;
break; break;
case ALPHA: case ALPHA:
if (Keyboard.shift) if (Keyboard.shift) {
Engine.getPlatform().shiftChanged(Keyboard.shift = false); Engine.getPlatform().shiftChanged(Keyboard.shift = false);
}
Engine.getPlatform().alphaChanged(Keyboard.alpha = !Keyboard.alpha); Engine.getPlatform().alphaChanged(Keyboard.alpha = !Keyboard.alpha);
refresh = true; refresh = true;
break; break;
default: default:
if (k != Key.NONE) { if (k != Key.NONE) {
if (Keyboard.shift) if (Keyboard.shift) {
Engine.getPlatform().shiftChanged(Keyboard.shift = false); Engine.getPlatform().shiftChanged(Keyboard.shift = false);
if (Keyboard.alpha) }
if (Keyboard.alpha) {
Engine.getPlatform().alphaChanged(Keyboard.alpha = false); Engine.getPlatform().alphaChanged(Keyboard.alpha = false);
}
} }
break; break;
} }
if (refresh) if (refresh) {
Keyboard.refreshRequest = true; Keyboard.refreshRequest = true;
} else if (!done) }
} else if (!done) {
Engine.getPlatform().getConsoleUtils().out().println(1, "Key " + k.toString() + " ignored."); Engine.getPlatform().getConsoleUtils().out().println(1, "Key " + k.toString() + " ignored.");
}
} }
public synchronized static void keyReleased(final Key k) { public synchronized static void keyReleased(final Key k) {
boolean done = false; boolean done = false;
if (Keyboard.additionalListener != null) if (Keyboard.additionalListener != null) {
done = Keyboard.additionalListener.onKeyReleased(new KeyReleasedEvent(k)); done = Keyboard.additionalListener.onKeyReleased(new KeyReleasedEvent(k));
}
boolean refresh = false; boolean refresh = false;
if (Engine.INSTANCE.getHardwareDevice().getDisplayManager() != null) { if (Engine.INSTANCE.getHardwareDevice().getDisplayManager() != null) {
final Screen scr = Engine.INSTANCE.getHardwareDevice().getDisplayManager().getScreen(); final Screen scr = Engine.INSTANCE.getHardwareDevice().getDisplayManager().getScreen();
if (scr != null && scr.initialized && scr.onKeyReleased(new KeyReleasedEvent(k))) if (scr != null && scr.initialized && scr.onKeyReleased(new KeyReleasedEvent(k))) {
refresh = true; refresh = true;
else } else {
switch (k) { switch (k) {
case NONE: case NONE:
break; break;
default: default:
break; break;
} }
if (refresh) }
if (refresh) {
Keyboard.refreshRequest = true; Keyboard.refreshRequest = true;
} else if (!done) }
} else if (!done) {
Engine.getPlatform().getConsoleUtils().out().println(1, "Key " + k.toString() + " ignored."); Engine.getPlatform().getConsoleUtils().out().println(1, "Key " + k.toString() + " ignored.");
}
} }
public void setAdditionalKeyboardListener(final KeyboardEventListener l) { public void setAdditionalKeyboardListener(final KeyboardEventListener l) {

View File

@ -13,11 +13,12 @@ public class PIHardwareDisplay implements HardwareDisplay {
@Override @Override
public void setBrightness(final double value) { public void setBrightness(final double value) {
if (Engine.getPlatform().getSettings().isDebugEnabled() == false) if (Engine.getPlatform().getSettings().isDebugEnabled() == false) {
Engine.getPlatform().getGpio().pwmWrite(12, (int) Math.ceil(value * 1024f)); Engine.getPlatform().getGpio().pwmWrite(12, (int) Math.ceil(value * 1024f));
// SoftPwm.softPwmWrite(12, (int)(Math.ceil(brightness*10))); // SoftPwm.softPwmWrite(12, (int)(Math.ceil(brightness*10)));
else } else {
Engine.getPlatform().getConsoleUtils().out().println(1, "Brightness: " + value); Engine.getPlatform().getConsoleUtils().out().println(1, "Brightness: " + value);
}
} }
} }

View File

@ -22,13 +22,14 @@ public class PIHardwareTouchDevice implements HardwareTouchDevice {
public boolean onTouchStart(final TouchStartEvent e) { public boolean onTouchStart(final TouchStartEvent e) {
final Screen scr = Engine.INSTANCE.getHardwareDevice().getDisplayManager().getScreen(); final Screen scr = Engine.INSTANCE.getHardwareDevice().getDisplayManager().getScreen();
boolean refresh = false; boolean refresh = false;
if (scr != null && scr.initialized && scr.onTouchStart(e)) if (scr != null && scr.initialized && scr.onTouchStart(e)) {
refresh = true; refresh = true;
else { } else {
//Default behavior //Default behavior
} }
if (refresh) if (refresh) {
Engine.INSTANCE.getHardwareDevice().getDisplayManager().forceRefresh = true; Engine.INSTANCE.getHardwareDevice().getDisplayManager().forceRefresh = true;
}
return true; return true;
} }
@ -36,13 +37,14 @@ public class PIHardwareTouchDevice implements HardwareTouchDevice {
public boolean onTouchEnd(final TouchEndEvent e) { public boolean onTouchEnd(final TouchEndEvent e) {
final Screen scr = Engine.INSTANCE.getHardwareDevice().getDisplayManager().getScreen(); final Screen scr = Engine.INSTANCE.getHardwareDevice().getDisplayManager().getScreen();
boolean refresh = false; boolean refresh = false;
if (scr != null && scr.initialized && scr.onTouchEnd(e)) if (scr != null && scr.initialized && scr.onTouchEnd(e)) {
refresh = true; refresh = true;
else { } else {
//Default behavior //Default behavior
} }
if (refresh) if (refresh) {
Engine.INSTANCE.getHardwareDevice().getDisplayManager().forceRefresh = true; Engine.INSTANCE.getHardwareDevice().getDisplayManager().forceRefresh = true;
}
return true; return true;
} }
@ -50,13 +52,14 @@ public class PIHardwareTouchDevice implements HardwareTouchDevice {
public boolean onTouchCancel(final TouchCancelEvent e) { public boolean onTouchCancel(final TouchCancelEvent e) {
final Screen scr = Engine.INSTANCE.getHardwareDevice().getDisplayManager().getScreen(); final Screen scr = Engine.INSTANCE.getHardwareDevice().getDisplayManager().getScreen();
boolean refresh = false; boolean refresh = false;
if (scr != null && scr.initialized && scr.onTouchCancel(e)) if (scr != null && scr.initialized && scr.onTouchCancel(e)) {
refresh = true; refresh = true;
else { } else {
//Default behavior //Default behavior
} }
if (refresh) if (refresh) {
Engine.INSTANCE.getHardwareDevice().getDisplayManager().forceRefresh = true; Engine.INSTANCE.getHardwareDevice().getDisplayManager().forceRefresh = true;
}
return true; return true;
} }
@ -64,13 +67,14 @@ public class PIHardwareTouchDevice implements HardwareTouchDevice {
public boolean onTouchMove(final TouchMoveEvent e) { public boolean onTouchMove(final TouchMoveEvent e) {
final Screen scr = Engine.INSTANCE.getHardwareDevice().getDisplayManager().getScreen(); final Screen scr = Engine.INSTANCE.getHardwareDevice().getDisplayManager().getScreen();
boolean refresh = false; boolean refresh = false;
if (scr != null && scr.initialized && scr.onTouchMove(e)) if (scr != null && scr.initialized && scr.onTouchMove(e)) {
refresh = true; refresh = true;
else { } else {
//Default behavior //Default behavior
} }
if (refresh) if (refresh) {
Engine.INSTANCE.getHardwareDevice().getDisplayManager().forceRefresh = true; Engine.INSTANCE.getHardwareDevice().getDisplayManager().forceRefresh = true;
}
return true; return true;
} }
@ -98,10 +102,12 @@ public class PIHardwareTouchDevice implements HardwareTouchDevice {
x = (float) (oldY * screenWidth / screenHeight); x = (float) (oldY * screenWidth / screenHeight);
y = (float) (oldX * screenHeight / screenWidth); y = (float) (oldX * screenHeight / screenWidth);
} }
if (getInvertedX()) if (getInvertedX()) {
x = screenWidth - x; x = screenWidth - x;
if (getInvertedY()) }
if (getInvertedY()) {
y = screenHeight - y; y = screenHeight - y;
}
return new TouchPoint(id, x, y, radiusX, radiusY, force, rotationAngle); return new TouchPoint(id, x, y, radiusX, radiusY, force, rotationAngle);
} }
} }

View File

@ -14,9 +14,9 @@ public class SerialToParallel {
} }
public void write(final boolean[] data) { public void write(final boolean[] data) {
if (data.length != 8) if (data.length != 8) {
return; return;
else { } else {
Engine.getPlatform().getGpio().digitalWrite(RCK, Engine.getPlatform().getGpio().valueLow()); Engine.getPlatform().getGpio().digitalWrite(RCK, Engine.getPlatform().getGpio().valueLow());
for (int i = 7; i >= 0; i--) { for (int i = 7; i >= 0; i--) {

View File

@ -69,8 +69,9 @@ public class RAWFont {
Object obj = new Object(); Object obj = new Object();
final WeakReference<Object> ref = new WeakReference<>(obj); final WeakReference<Object> ref = new WeakReference<>(obj);
obj = null; obj = null;
while (ref.get() != null) while (ref.get() != null) {
System.gc(); System.gc();
}
} }
private void loadFont(final String string) throws IOException { private void loadFont(final String string) throws IOException {
@ -85,25 +86,29 @@ public class RAWFont {
charIntCount = (int) Math.ceil((double) charS / (double) RAWFont.intBits); charIntCount = (int) Math.ceil((double) charS / (double) RAWFont.intBits);
minBound = file[0x9] << 24 | file[0xA] << 16 | file[0xB] << 8 | file[0xC]; minBound = file[0x9] << 24 | file[0xA] << 16 | file[0xB] << 8 | file[0xC];
maxBound = file[0xE] << 24 | file[0xF] << 16 | file[0x10] << 8 | file[0x11]; maxBound = file[0xE] << 24 | file[0xF] << 16 | file[0x10] << 8 | file[0x11];
if (maxBound <= minBound) if (maxBound <= minBound) {
maxBound = 10000; //TODO remove it: temp fix maxBound = 10000; //TODO remove it: temp fix
}
rawchars = new boolean[maxBound - minBound][]; rawchars = new boolean[maxBound - minBound][];
int index = 0x12; int index = 0x12;
while (index < filelength) while (index < filelength) {
try { try {
final int charIndex = file[index] << 8 | file[index + 1]; final int charIndex = file[index] << 8 | file[index + 1];
final boolean[] rawchar = new boolean[charS]; final boolean[] rawchar = new boolean[charS];
int charbytescount = 0; int charbytescount = 0;
while (charbytescount * 8 < charS) while (charbytescount * 8 < charS) {
charbytescount += 1; charbytescount += 1;
}
int currentBit = 0; int currentBit = 0;
for (int i = 0; i <= charbytescount; i++) for (int i = 0; i <= charbytescount; i++) {
for (int bit = 0; bit < 8; bit++) { for (int bit = 0; bit < 8; bit++) {
if (currentBit >= charS) if (currentBit >= charS) {
break; break;
}
rawchar[currentBit] = (file[index + 2 + i] >> 8 - 1 - bit & 0x1) == 1 ? true : false; rawchar[currentBit] = (file[index + 2 + i] >> 8 - 1 - bit & 0x1) == 1 ? true : false;
currentBit++; currentBit++;
} }
}
rawchars[charIndex - minBound] = rawchar; rawchars[charIndex - minBound] = rawchar;
index += 2 + charbytescount; index += 2 + charbytescount;
} catch (final Exception ex) { } catch (final Exception ex) {
@ -111,18 +116,22 @@ public class RAWFont {
System.out.println(string); System.out.println(string);
Engine.getPlatform().exit(-1); Engine.getPlatform().exit(-1);
} }
} else }
} else {
throw new IOException(); throw new IOException();
} else }
} else {
throw new IOException(); throw new IOException();
}
} }
public int[] getCharIndexes(final String txt) { public int[] getCharIndexes(final String txt) {
final int l = txt.length(); final int l = txt.length();
final int[] indexes = new int[l]; final int[] indexes = new int[l];
final char[] chars = txt.toCharArray(); final char[] chars = txt.toCharArray();
for (int i = 0; i < l; i++) for (int i = 0; i < l; i++) {
indexes[i] = (chars[i] & 0xFFFF) - minBound; indexes[i] = (chars[i] & 0xFFFF) - minBound;
}
return indexes; return indexes;
} }
@ -152,7 +161,7 @@ public class RAWFont {
for (int i = 0; i < l; i++) { for (int i = 0; i < l; i++) {
cpos = i * (charW + 1); cpos = i * (charW + 1);
final int charIndex = text[i]; final int charIndex = text[i];
for (int dy = 0; dy < charH; dy++) for (int dy = 0; dy < charH; dy++) {
for (int dx = 0; dx < charW; dx++) { for (int dx = 0; dx < charW; dx++) {
j = x + cpos + dx; j = x + cpos + dx;
if (j > 0 & j < screenSize[0]) { if (j > 0 & j < screenSize[0]) {
@ -161,10 +170,12 @@ public class RAWFont {
currentIntBitPosition = bit - currentInt * RAWFont.intBits; currentIntBitPosition = bit - currentInt * RAWFont.intBits;
bitData = chars32[charIndex * charIntCount + currentInt] >> currentIntBitPosition & 1; bitData = chars32[charIndex * charIntCount + currentInt] >> currentIntBitPosition & 1;
screenPos = x + cpos + dx + (y + dy) * screenSize[0]; screenPos = x + cpos + dx + (y + dy) * screenSize[0];
if (bitData == 1 & screenLength > screenPos) if (bitData == 1 & screenLength > screenPos) {
screen[screenPos] = color; screen[screenPos] = color;
}
} }
} }
}
} }
} }
} }

View File

@ -34,23 +34,30 @@ public class TouchCancelEvent implements TouchEvent {
@Override @Override
public boolean equals(final Object obj) { public boolean equals(final Object obj) {
if (this == obj) if (this == obj) {
return true; return true;
if (obj == null) }
if (obj == null) {
return false; return false;
if (getClass() != obj.getClass()) }
if (getClass() != obj.getClass()) {
return false; return false;
}
final TouchCancelEvent other = (TouchCancelEvent) obj; final TouchCancelEvent other = (TouchCancelEvent) obj;
if (changedTouches == null) { if (changedTouches == null) {
if (other.changedTouches != null) if (other.changedTouches != null) {
return false; return false;
} else if (!changedTouches.equals(other.changedTouches)) }
} else if (!changedTouches.equals(other.changedTouches)) {
return false; return false;
}
if (touches == null) { if (touches == null) {
if (other.touches != null) if (other.touches != null) {
return false; return false;
} else if (!touches.equals(other.touches)) }
} else if (!touches.equals(other.touches)) {
return false; return false;
}
return true; return true;
} }

View File

@ -34,23 +34,30 @@ public class TouchEndEvent implements TouchEvent {
@Override @Override
public boolean equals(final Object obj) { public boolean equals(final Object obj) {
if (this == obj) if (this == obj) {
return true; return true;
if (obj == null) }
if (obj == null) {
return false; return false;
if (getClass() != obj.getClass()) }
if (getClass() != obj.getClass()) {
return false; return false;
}
final TouchEndEvent other = (TouchEndEvent) obj; final TouchEndEvent other = (TouchEndEvent) obj;
if (changedTouches == null) { if (changedTouches == null) {
if (other.changedTouches != null) if (other.changedTouches != null) {
return false; return false;
} else if (!changedTouches.equals(other.changedTouches)) }
} else if (!changedTouches.equals(other.changedTouches)) {
return false; return false;
}
if (touches == null) { if (touches == null) {
if (other.touches != null) if (other.touches != null) {
return false; return false;
} else if (!touches.equals(other.touches)) }
} else if (!touches.equals(other.touches)) {
return false; return false;
}
return true; return true;
} }

View File

@ -34,23 +34,30 @@ public class TouchMoveEvent implements TouchEvent {
@Override @Override
public boolean equals(final Object obj) { public boolean equals(final Object obj) {
if (this == obj) if (this == obj) {
return true; return true;
if (obj == null) }
if (obj == null) {
return false; return false;
if (getClass() != obj.getClass()) }
if (getClass() != obj.getClass()) {
return false; return false;
}
final TouchMoveEvent other = (TouchMoveEvent) obj; final TouchMoveEvent other = (TouchMoveEvent) obj;
if (changedTouches == null) { if (changedTouches == null) {
if (other.changedTouches != null) if (other.changedTouches != null) {
return false; return false;
} else if (!changedTouches.equals(other.changedTouches)) }
} else if (!changedTouches.equals(other.changedTouches)) {
return false; return false;
}
if (touches == null) { if (touches == null) {
if (other.touches != null) if (other.touches != null) {
return false; return false;
} else if (!touches.equals(other.touches)) }
} else if (!touches.equals(other.touches)) {
return false; return false;
}
return true; return true;
} }

View File

@ -64,27 +64,37 @@ public class TouchPoint {
@Override @Override
public boolean equals(final Object obj) { public boolean equals(final Object obj) {
if (this == obj) if (this == obj) {
return true; return true;
if (obj == null) }
if (obj == null) {
return false; return false;
if (getClass() != obj.getClass()) }
if (getClass() != obj.getClass()) {
return false; return false;
}
final TouchPoint other = (TouchPoint) obj; final TouchPoint other = (TouchPoint) obj;
if (Float.floatToIntBits(force) != Float.floatToIntBits(other.force)) if (Float.floatToIntBits(force) != Float.floatToIntBits(other.force)) {
return false; return false;
if (id != other.id) }
if (id != other.id) {
return false; return false;
if (Float.floatToIntBits(radiusX) != Float.floatToIntBits(other.radiusX)) }
if (Float.floatToIntBits(radiusX) != Float.floatToIntBits(other.radiusX)) {
return false; return false;
if (Float.floatToIntBits(radiusY) != Float.floatToIntBits(other.radiusY)) }
if (Float.floatToIntBits(radiusY) != Float.floatToIntBits(other.radiusY)) {
return false; return false;
if (Float.floatToIntBits(rotationAngle) != Float.floatToIntBits(other.rotationAngle)) }
if (Float.floatToIntBits(rotationAngle) != Float.floatToIntBits(other.rotationAngle)) {
return false; return false;
if (Float.floatToIntBits(x) != Float.floatToIntBits(other.x)) }
if (Float.floatToIntBits(x) != Float.floatToIntBits(other.x)) {
return false; return false;
if (Float.floatToIntBits(y) != Float.floatToIntBits(other.y)) }
if (Float.floatToIntBits(y) != Float.floatToIntBits(other.y)) {
return false; return false;
}
return true; return true;
} }

View File

@ -34,23 +34,30 @@ public class TouchStartEvent implements TouchEvent {
@Override @Override
public boolean equals(final Object obj) { public boolean equals(final Object obj) {
if (this == obj) if (this == obj) {
return true; return true;
if (obj == null) }
if (obj == null) {
return false; return false;
if (getClass() != obj.getClass()) }
if (getClass() != obj.getClass()) {
return false; return false;
}
final TouchStartEvent other = (TouchStartEvent) obj; final TouchStartEvent other = (TouchStartEvent) obj;
if (changedTouches == null) { if (changedTouches == null) {
if (other.changedTouches != null) if (other.changedTouches != null) {
return false; return false;
} else if (!changedTouches.equals(other.changedTouches)) }
} else if (!changedTouches.equals(other.changedTouches)) {
return false; return false;
}
if (touches == null) { if (touches == null) {
if (other.touches != null) if (other.touches != null) {
return false; return false;
} else if (!touches.equals(other.touches)) }
} else if (!touches.equals(other.touches)) {
return false; return false;
}
return true; return true;
} }

View File

@ -61,8 +61,9 @@ public class MarioEntity {
public double computeFutureDY(final double dt) { public double computeFutureDY(final double dt) {
final double forceY = this.forceY; final double forceY = this.forceY;
double y = this.y; double y = this.y;
if (!collisionDown) if (!collisionDown) {
y += dt * forceY; y += dt * forceY;
}
return y - this.y; return y - this.y;
} }
@ -74,10 +75,11 @@ public class MarioEntity {
public double computeFutureForceDY(final double dt) { public double computeFutureForceDY(final double dt) {
double forceY = this.forceY; double forceY = this.forceY;
if (subjectToGravity && !collisionDown) if (subjectToGravity && !collisionDown) {
forceY -= dt * 1569.6 / 16f; forceY -= dt * 1569.6 / 16f;
else } else {
forceY *= 0.75; forceY *= 0.75;
}
return forceY - this.forceY; return forceY - this.forceY;
} }
} }

View File

@ -56,8 +56,9 @@ public class MarioGame {
checkCollisionTop(getPlayer(), dt); checkCollisionTop(getPlayer(), dt);
checkCollisionLeft(getPlayer(), dt); checkCollisionLeft(getPlayer(), dt);
checkCollisionRight(getPlayer(), dt); checkCollisionRight(getPlayer(), dt);
if (canMove) if (canMove) {
move(dt, (rightPressed ? 1 : 0) - (leftPressed ? 1 : 0), jumpPressed ? 1 : 0); move(dt, (rightPressed ? 1 : 0) - (leftPressed ? 1 : 0), jumpPressed ? 1 : 0);
}
getPlayer().gameTick(dt); getPlayer().gameTick(dt);
final MarioWorld w = getCurrentWorld(); final MarioWorld w = getCurrentWorld();
@ -74,10 +75,11 @@ public class MarioGame {
private int nearest(final double val, final int a, final int b) { private int nearest(final double val, final int a, final int b) {
final double aa = Math.abs(val - a); final double aa = Math.abs(val - a);
final double ab = Math.abs(val - b); final double ab = Math.abs(val - b);
if (aa < ab) if (aa < ab) {
return (int) aa; return (int) aa;
else } else {
return (int) ab; return (int) ab;
}
} }
private void checkOnGround(final MarioEntity e, final float dt) { private void checkOnGround(final MarioEntity e, final float dt) {
@ -87,8 +89,8 @@ public class MarioGame {
final int y0 = (int) Math.ceil(e.getY()); final int y0 = (int) Math.ceil(e.getY());
final int y1 = (int) Math.ceil(e.getY() + e.computeFutureDY(dt)); final int y1 = (int) Math.ceil(e.getY() + e.computeFutureDY(dt));
boolean onGround = false; boolean onGround = false;
if (y1 < y0) if (y1 < y0) {
for (int y = y0; y >= y1; y--) for (int y = y0; y >= y1; y--) {
for (int x = xA; x <= xB; x++) { for (int x = xA; x <= xB; x++) {
final byte b = getCurrentWorld().getBlockIdAt(x, y - 1); final byte b = getCurrentWorld().getBlockIdAt(x, y - 1);
if (MarioBlock.isSolid(b)) { if (MarioBlock.isSolid(b)) {
@ -101,7 +103,8 @@ public class MarioGame {
break; break;
} }
} }
else }
} else {
for (int x = xA; x <= xB; x++) { for (int x = xA; x <= xB; x++) {
final byte b = getCurrentWorld().getBlockIdAt(x, y0 - 1); final byte b = getCurrentWorld().getBlockIdAt(x, y0 - 1);
if (MarioBlock.isSolid(b)) { if (MarioBlock.isSolid(b)) {
@ -113,8 +116,10 @@ public class MarioGame {
} }
} }
} }
if (!onGround) }
if (!onGround) {
e.setOnGround(false); e.setOnGround(false);
}
} }
} }
@ -125,8 +130,8 @@ public class MarioGame {
final int y0 = (int) Math.ceil(e.getY()); final int y0 = (int) Math.ceil(e.getY());
final int y1 = (int) Math.ceil(e.getY() + e.computeFutureDY(dt)); final int y1 = (int) Math.ceil(e.getY() + e.computeFutureDY(dt));
boolean collisionUp = false; boolean collisionUp = false;
if (y1 > y0) if (y1 > y0) {
for (int y = y0; y <= y1; y++) for (int y = y0; y <= y1; y++) {
for (int x = xA; x <= xB; x++) { for (int x = xA; x <= xB; x++) {
final byte b = getCurrentWorld().getBlockIdAt(x, y + 1); final byte b = getCurrentWorld().getBlockIdAt(x, y + 1);
if (MarioBlock.isSolid(b)) { if (MarioBlock.isSolid(b)) {
@ -139,7 +144,8 @@ public class MarioGame {
break; break;
} }
} }
else }
} else {
for (int x = xA; x <= xB; x++) { for (int x = xA; x <= xB; x++) {
final byte b = getCurrentWorld().getBlockIdAt(x, y0 + 1); final byte b = getCurrentWorld().getBlockIdAt(x, y0 + 1);
if (MarioBlock.isSolid(b)) { if (MarioBlock.isSolid(b)) {
@ -151,8 +157,10 @@ public class MarioGame {
} }
} }
} }
if (!collisionUp) }
if (!collisionUp) {
e.collisionUp = false; e.collisionUp = false;
}
} }
} }
@ -164,8 +172,8 @@ public class MarioGame {
final double x1double = e.getX() + e.computeFutureDX(dt); final double x1double = e.getX() + e.computeFutureDX(dt);
final int x1 = (int) Math.floor(x1double); final int x1 = (int) Math.floor(x1double);
boolean collisionRight = false; boolean collisionRight = false;
if (x1 > x0) if (x1 > x0) {
for (int x = x0; x <= x1; x++) for (int x = x0; x <= x1; x++) {
for (int y = yA; y <= yB; y++) { for (int y = yA; y <= yB; y++) {
final byte b = getCurrentWorld().getBlockIdAt(x + 1, y); final byte b = getCurrentWorld().getBlockIdAt(x + 1, y);
if (MarioBlock.isSolid(b)) { if (MarioBlock.isSolid(b)) {
@ -178,7 +186,8 @@ public class MarioGame {
break; break;
} }
} }
else }
} else {
for (int y = yA; y <= yB; y++) { for (int y = yA; y <= yB; y++) {
final byte b = getCurrentWorld().getBlockIdAt(x0 + 1, y); final byte b = getCurrentWorld().getBlockIdAt(x0 + 1, y);
if (MarioBlock.isSolid(b)) { if (MarioBlock.isSolid(b)) {
@ -190,8 +199,10 @@ public class MarioGame {
} }
} }
} }
if (!collisionRight) }
if (!collisionRight) {
e.collisionRight = false; e.collisionRight = false;
}
} }
} }
@ -209,8 +220,8 @@ public class MarioGame {
e.setPosition(0, e.getY()); e.setPosition(0, e.getY());
} }
e.collisionLeft = true; e.collisionLeft = true;
} else if (x1 < x0) } else if (x1 < x0) {
for (int x = x0; x >= x1; x--) for (int x = x0; x >= x1; x--) {
for (int y = yA; y <= yB; y++) { for (int y = yA; y <= yB; y++) {
final byte b = getCurrentWorld().getBlockIdAt(x - 1, y); final byte b = getCurrentWorld().getBlockIdAt(x - 1, y);
if (MarioBlock.isSolid(b)) { if (MarioBlock.isSolid(b)) {
@ -223,7 +234,8 @@ public class MarioGame {
break; break;
} }
} }
else }
} else {
for (int y = yA; y <= yB; y++) { for (int y = yA; y <= yB; y++) {
final byte b = getCurrentWorld().getBlockIdAt(x0 - 1, y); final byte b = getCurrentWorld().getBlockIdAt(x0 - 1, y);
if (MarioBlock.isSolid(b)) { if (MarioBlock.isSolid(b)) {
@ -235,8 +247,10 @@ public class MarioGame {
} }
} }
} }
if (!collisionLeft) }
if (!collisionLeft) {
e.collisionLeft = false; e.collisionLeft = false;
}
} }
} }

View File

@ -28,11 +28,13 @@ public class MarioWorld {
public byte getBlockIdAt(final int x, final int y) { public byte getBlockIdAt(final int x, final int y) {
final int idy = height - 1 - y; final int idy = height - 1 - y;
if (idy < 0 || idy >= data.length) if (idy < 0 || idy >= data.length) {
return 0b0; return 0b0;
}
final int idx = x; final int idx = x;
if (idx < 0 || idx >= data[0].length) if (idx < 0 || idx >= data[0].length) {
return 0b0; return 0b0;
}
return data[idy][idx]; return data[idy][idx];
} }

View File

@ -48,33 +48,35 @@ public class PlayerEntity extends MarioEntity {
if (jumptime <= 0.5f && !jumping && collisionDown) { if (jumptime <= 0.5f && !jumping && collisionDown) {
jumping = true; jumping = true;
collisionDown = false; collisionDown = false;
} else if (jumptime <= 0.5f) {} else } else if (jumptime <= 0.5f) {} else {
jumping = false; jumping = false;
}
} else { } else {
jumping = false; jumping = false;
if (collisionDown) if (collisionDown) {
jumptime = 0; jumptime = 0;
else } else {
jumptime = Float.MAX_VALUE; jumptime = Float.MAX_VALUE;
}
} }
if (!walking & !running & !jumping) { if (!walking & !running & !jumping) {
marioSkinPos[0] = 0; marioSkinPos[0] = 0;
marioSkinPos[1] = 0; marioSkinPos[1] = 0;
} else if (collisionDown & walking & !running & !jumping && walkAnimation >= 0.08) } else if (collisionDown & walking & !running & !jumping && walkAnimation >= 0.08) {
while (walkAnimation > 0.08) { while (walkAnimation > 0.08) {
walkAnimation -= 0.08; walkAnimation -= 0.08;
if (marioSkinPos[0] == 1 & marioSkinPos[1] == 0) if (marioSkinPos[0] == 1 & marioSkinPos[1] == 0) {
marioSkinPos[0] += 2; marioSkinPos[0] += 2;
else if (marioSkinPos[0] == 3 & marioSkinPos[1] == 0) } else if (marioSkinPos[0] == 3 & marioSkinPos[1] == 0) {
marioSkinPos[0] -= 1; marioSkinPos[0] -= 1;
else if (marioSkinPos[0] == 2 & marioSkinPos[1] == 0) } else if (marioSkinPos[0] == 2 & marioSkinPos[1] == 0) {
marioSkinPos[0] -= 1; marioSkinPos[0] -= 1;
else { } else {
marioSkinPos[0] = 1; marioSkinPos[0] = 1;
marioSkinPos[1] = 0; marioSkinPos[1] = 0;
} }
} }
else if (jumping) { } else if (jumping) {
marioSkinPos[0] = 5; marioSkinPos[0] = 5;
marioSkinPos[1] = 1; marioSkinPos[1] = 1;
} }
@ -93,12 +95,16 @@ public class PlayerEntity extends MarioEntity {
public double computeFutureForceDX(final double dt) { public double computeFutureForceDX(final double dt) {
double forceX = this.forceX; double forceX = this.forceX;
if (controllerDX == 0) {} else { if (controllerDX == 0) {} else {
if (controllerDX > 0) if (controllerDX > 0) {
if (forceX < 500f / 16f) if (forceX < 500f / 16f) {
forceX += dt * 500f / 16f; forceX += dt * 500f / 16f;
if (controllerDX < 0) }
if (forceX > -500f / 16f) }
if (controllerDX < 0) {
if (forceX > -500f / 16f) {
forceX -= dt * 500f / 16f; forceX -= dt * 500f / 16f;
}
}
} }
return forceX + super.computeFutureForceDX(dt) - this.forceX; return forceX + super.computeFutureForceDX(dt) - this.forceX;
@ -109,13 +115,15 @@ public class PlayerEntity extends MarioEntity {
float jumptime = this.jumptime; float jumptime = this.jumptime;
double forceY = this.forceY; double forceY = this.forceY;
if (controllerDY > 0) { //JUMP if (controllerDY > 0) { //JUMP
if (collisionUp) if (collisionUp) {
jumptime = Float.MAX_VALUE; jumptime = Float.MAX_VALUE;
}
jumptime += dt; jumptime += dt;
if (jumptime <= 0.5f && !jumping && collisionDown) if (jumptime <= 0.5f && !jumping && collisionDown) {
forceY = dt * (4 * 1569.6f) / 16f; forceY = dt * (4 * 1569.6f) / 16f;
else if (jumptime <= 0.5f) } else if (jumptime <= 0.5f) {
forceY = dt * (4 * 1569.6f) / 16f; forceY = dt * (4 * 1569.6f) / 16f;
}
} }
return forceY + super.computeFutureForceDY(dt) - this.forceY; return forceY + super.computeFutureForceDY(dt) - this.forceY;
} }

View File

@ -48,22 +48,25 @@ public class CalculatorHUD extends HUD {
renderer.glDrawLine(0, 20, engine.getWidth() - 1, 20); renderer.glDrawLine(0, 20, engine.getWidth() - 1, 20);
renderer.glColor3i(255, 255, 255); renderer.glColor3i(255, 255, 255);
guiSkin.use(engine); guiSkin.use(engine);
if (Keyboard.shift) if (Keyboard.shift) {
renderer.glFillRect(2 + 18 * 0, 2, 16, 16, 16 * 2, 16 * 0, 16, 16); renderer.glFillRect(2 + 18 * 0, 2, 16, 16, 16 * 2, 16 * 0, 16, 16);
else } else {
renderer.glFillRect(2 + 18 * 0, 2, 16, 16, 16 * 3, 16 * 0, 16, 16); renderer.glFillRect(2 + 18 * 0, 2, 16, 16, 16 * 3, 16 * 0, 16, 16);
if (Keyboard.alpha) }
if (Keyboard.alpha) {
renderer.glFillRect(2 + 18 * 1, 2, 16, 16, 16 * 0, 16 * 0, 16, 16); renderer.glFillRect(2 + 18 * 1, 2, 16, 16, 16 * 0, 16 * 0, 16, 16);
else } else {
renderer.glFillRect(2 + 18 * 1, 2, 16, 16, 16 * 1, 16 * 0, 16, 16); renderer.glFillRect(2 + 18 * 1, 2, 16, 16, 16 * 1, 16 * 0, 16, 16);
}
int padding = 2; int padding = 2;
final int brightness = (int) Math.ceil(Engine.INSTANCE.getHardwareDevice().getDisplayManager().getBrightness() * 9); final int brightness = (int) Math.ceil(Engine.INSTANCE.getHardwareDevice().getDisplayManager().getBrightness() * 9);
if (brightness <= 10) if (brightness <= 10) {
renderer.glFillRect(StaticVars.screenSize[0] - (padding + 16), 2, 16, 16, 16 * brightness, 16 * 1, 16, 16); renderer.glFillRect(StaticVars.screenSize[0] - (padding + 16), 2, 16, 16, 16 * brightness, 16 * 1, 16, 16);
else } else {
Engine.getPlatform().getConsoleUtils().out().println(1, "Brightness error"); Engine.getPlatform().getConsoleUtils().out().println(1, "Brightness error");
}
padding += 18 + 6; padding += 18 + 6;
@ -75,14 +78,15 @@ public class CalculatorHUD extends HUD {
padding += 18 + 6; padding += 18 + 6;
} }
if (canGoBack && canGoForward) if (canGoBack && canGoForward) {
renderer.glFillRect(StaticVars.screenSize[0] - (padding + 16), 2, 16, 16, 16 * 14, 16 * 0, 16, 16); renderer.glFillRect(StaticVars.screenSize[0] - (padding + 16), 2, 16, 16, 16 * 14, 16 * 0, 16, 16);
else if (canGoBack) } else if (canGoBack) {
renderer.glFillRect(StaticVars.screenSize[0] - (padding + 16), 2, 16, 16, 16 * 15, 16 * 0, 16, 16); renderer.glFillRect(StaticVars.screenSize[0] - (padding + 16), 2, 16, 16, 16 * 15, 16 * 0, 16, 16);
else if (canGoForward) } else if (canGoForward) {
renderer.glFillRect(StaticVars.screenSize[0] - (padding + 16), 2, 16, 16, 16 * 16, 16 * 0, 16, 16); renderer.glFillRect(StaticVars.screenSize[0] - (padding + 16), 2, 16, 16, 16 * 16, 16 * 0, 16, 16);
else } else {
renderer.glFillRect(StaticVars.screenSize[0] - (padding + 16), 2, 16, 16, 16 * 17, 16 * 0, 16, 16); renderer.glFillRect(StaticVars.screenSize[0] - (padding + 16), 2, 16, 16, 16 * 17, 16 * 0, 16, 16);
}
padding += 18; padding += 18;

View File

@ -72,8 +72,9 @@ public final class DisplayManager implements RenderingLoop {
try { try {
hud.d = this; hud.d = this;
hud.create(); hud.create();
if (!hud.initialized) if (!hud.initialized) {
hud.initialize(); hud.initialize();
}
} catch (final Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
Engine.getPlatform().exit(0); Engine.getPlatform().exit(0);
@ -165,25 +166,29 @@ public final class DisplayManager implements RenderingLoop {
} }
public void setScreen(final Screen screen) { public void setScreen(final Screen screen) {
if (screen.initialized == false) if (screen.initialized == false) {
if (screen.canBeInHistory) { if (screen.canBeInHistory) {
if (currentSession > 0) { if (currentSession > 0) {
final int sl = sessions.length + 5; //TODO: I don't know why if i don't add +5 or more some items disappear final int sl = sessions.length + 5; //TODO: I don't know why if i don't add +5 or more some items disappear
sessions = Arrays.copyOfRange(sessions, currentSession, sl); sessions = Arrays.copyOfRange(sessions, currentSession, sl);
} }
currentSession = 0; currentSession = 0;
for (int i = sessions.length - 1; i >= 1; i--) for (int i = sessions.length - 1; i >= 1; i--) {
sessions[i] = sessions[i - 1]; sessions[i] = sessions[i - 1];
}
sessions[0] = screen; sessions[0] = screen;
} else } else {
currentSession = -1; currentSession = -1;
}
}
screen.d = this; screen.d = this;
try { try {
screen.create(); screen.create();
this.screen = screen; this.screen = screen;
screenChange.release(); screenChange.release();
if (screen.initialized == false) if (screen.initialized == false) {
screen.initialize(); screen.initialize();
}
} catch (final Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
Engine.getPlatform().exit(0); Engine.getPlatform().exit(0);
@ -191,21 +196,24 @@ public final class DisplayManager implements RenderingLoop {
} }
public void replaceScreen(final Screen screen) { public void replaceScreen(final Screen screen) {
if (screen.initialized == false) if (screen.initialized == false) {
if (screen.canBeInHistory) if (screen.canBeInHistory) {
sessions[currentSession] = screen; sessions[currentSession] = screen;
else { } else {
currentSession = -1; currentSession = -1;
for (int i = 0; i < sessions.length - 2; i++) for (int i = 0; i < sessions.length - 2; i++) {
sessions[i] = sessions[i + 1]; sessions[i] = sessions[i + 1];
}
} }
}
screen.d = this; screen.d = this;
try { try {
screen.create(); screen.create();
this.screen = screen; this.screen = screen;
screenChange.release(); screenChange.release();
if (screen.initialized == false) if (screen.initialized == false) {
screen.initialize(); screen.initialize();
}
} catch (final Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
Engine.getPlatform().exit(0); Engine.getPlatform().exit(0);
@ -213,45 +221,54 @@ public final class DisplayManager implements RenderingLoop {
} }
public boolean canGoBack() { public boolean canGoBack() {
if (currentSession == -1) if (currentSession == -1) {
return sessions[0] != null; return sessions[0] != null;
}
if (screen != sessions[currentSession]) { if (screen != sessions[currentSession]) {
} else if (currentSession + 1 < sessions.length) { } else if (currentSession + 1 < sessions.length) {
if (sessions[currentSession + 1] != null) { if (sessions[currentSession + 1] != null) {
} else } else {
return false; return false;
} else }
} else {
return false; return false;
if (sessions[currentSession] != null) }
if (sessions[currentSession] != null) {
return true; return true;
}
return false; return false;
} }
public void goBack() { public void goBack() {
if (canGoBack()) { if (canGoBack()) {
if (currentSession >= 0 && screen != sessions[currentSession]) {} else if (currentSession >= 0 && screen != sessions[currentSession]) {} else {
currentSession += 1; currentSession += 1;
}
screen = sessions[currentSession]; screen = sessions[currentSession];
screenChange.release(); screenChange.release();
} }
} }
public boolean canGoForward() { public boolean canGoForward() {
if (currentSession <= 0) if (currentSession <= 0) {
return false; return false;
}
if (screen != sessions[currentSession]) { if (screen != sessions[currentSession]) {
} else if (currentSession > 0) { } else if (currentSession > 0) {
if (sessions[currentSession - 1] != null) { if (sessions[currentSession - 1] != null) {
} else } else {
return false; return false;
} else }
} else {
return false; return false;
if (sessions[currentSession] != null) }
if (sessions[currentSession] != null) {
return true; return true;
}
return false; return false;
} }
@ -259,8 +276,9 @@ public final class DisplayManager implements RenderingLoop {
if (canGoForward()) { if (canGoForward()) {
if (screen != sessions[currentSession]) { if (screen != sessions[currentSession]) {
} else } else {
currentSession -= 1; currentSession -= 1;
}
screen = sessions[currentSession]; screen = sessions[currentSession];
screenChange.release(); screenChange.release();
} }
@ -291,9 +309,11 @@ public final class DisplayManager implements RenderingLoop {
private void draw_init() { private void draw_init() {
if (engine.supportsFontRegistering()) { if (engine.supportsFontRegistering()) {
final List<BinaryFont> fontsIterator = engine.getRegisteredFonts(); final List<BinaryFont> fontsIterator = engine.getRegisteredFonts();
for (final BinaryFont f : fontsIterator) for (final BinaryFont f : fontsIterator) {
if (!f.isInitialized()) if (!f.isInitialized()) {
f.initialize(engine); f.initialize(engine);
}
}
} }
renderer.glClear(engine.getWidth(), engine.getHeight()); renderer.glClear(engine.getWidth(), engine.getHeight());
} }
@ -303,8 +323,9 @@ public final class DisplayManager implements RenderingLoop {
if (error != null) { if (error != null) {
final BinaryFont fnt = Utils.getFont(false, false); final BinaryFont fnt = Utils.getFont(false, false);
if (fnt != null && fnt != engine.getRenderer().getCurrentFont()) if (fnt != null && fnt != engine.getRenderer().getCurrentFont()) {
fnt.use(engine); fnt.use(engine);
}
renderer.glColor3i(129, 28, 22); renderer.glColor3i(129, 28, 22);
renderer.glDrawStringRight(StaticVars.screenSize[0] - 2, StaticVars.screenSize[1] - (fnt.getCharacterHeight() + 2), Engine.getPlatform().getSettings().getCalculatorNameUppercase() + " CALCULATOR"); renderer.glDrawStringRight(StaticVars.screenSize[0] - 2, StaticVars.screenSize[1] - (fnt.getCharacterHeight() + 2), Engine.getPlatform().getSettings().getCalculatorNameUppercase() + " CALCULATOR");
renderer.glColor3i(149, 32, 26); renderer.glColor3i(149, 32, 26);
@ -315,13 +336,15 @@ public final class DisplayManager implements RenderingLoop {
renderer.glDrawStringLeft(2, 22 + i, stackPart); renderer.glDrawStringLeft(2, 22 + i, stackPart);
i += 11; i += 11;
} }
if (fonts[0] != null && fonts[0] != engine.getRenderer().getCurrentFont()) if (fonts[0] != null && fonts[0] != engine.getRenderer().getCurrentFont()) {
fonts[0].use(engine); fonts[0].use(engine);
}
renderer.glColor3i(129, 28, 22); renderer.glColor3i(129, 28, 22);
renderer.glDrawStringCenter(StaticVars.screenSize[0] / 2, 11, "UNEXPECTED EXCEPTION"); renderer.glDrawStringCenter(StaticVars.screenSize[0] / 2, 11, "UNEXPECTED EXCEPTION");
} else { } else {
if (fonts[0] != null && fonts[0] != engine.getRenderer().getCurrentFont()) if (fonts[0] != null && fonts[0] != engine.getRenderer().getCurrentFont()) {
fonts[0].use(engine); fonts[0].use(engine);
}
hud.renderBackground(); hud.renderBackground();
screen.render(); screen.render();
hud.render(); hud.render();
@ -367,18 +390,20 @@ public final class DisplayManager implements RenderingLoop {
final Observable<Integer[]> onResizeObservable = engine.onResize(); final Observable<Integer[]> onResizeObservable = engine.onResize();
Observable<Pair<Long, Integer[]>> refreshObservable; Observable<Pair<Long, Integer[]>> refreshObservable;
if (onResizeObservable == null) if (onResizeObservable == null) {
refreshObservable = workTimer.map((l) -> Pair.of(l, null)); refreshObservable = workTimer.map((l) -> Pair.of(l, null));
else } else {
refreshObservable = Observable.combineChanged(workTimer, engine.onResize()); refreshObservable = Observable.combineChanged(workTimer, engine.onResize());
}
refreshObservable.subscribe((pair) -> { refreshObservable.subscribe((pair) -> {
double dt = 0; double dt = 0;
final long newtime = System.nanoTime(); final long newtime = System.nanoTime();
if (precTime == -1) if (precTime == -1) {
dt = DisplayManager.tickDuration; dt = DisplayManager.tickDuration;
else } else {
dt = (newtime - precTime) / 1000d / 1000d; dt = (newtime - precTime) / 1000d / 1000d;
}
precTime = newtime; precTime = newtime;
if (pair.getRight() != null) { if (pair.getRight() != null) {
@ -409,12 +434,13 @@ public final class DisplayManager implements RenderingLoop {
public void cycleBrightness(final boolean reverse) { public void cycleBrightness(final boolean reverse) {
final float step = reverse ? -0.1f : 0.1f; final float step = reverse ? -0.1f : 0.1f;
if (brightness + step > 1f) if (brightness + step > 1f) {
setBrightness(0f); setBrightness(0f);
else if (brightness + step <= 0f) } else if (brightness + step <= 0f) {
setBrightness(1.0f); setBrightness(1.0f);
else } else {
changeBrightness(step); changeBrightness(step);
}
} }
public float getBrightness() { public float getBrightness() {

View File

@ -37,15 +37,17 @@ public class Caret {
} }
public void flipState() { public void flipState() {
if (state == CaretState.VISIBLE_ON) if (state == CaretState.VISIBLE_ON) {
state = CaretState.VISIBLE_OFF; state = CaretState.VISIBLE_OFF;
else if (state == CaretState.VISIBLE_OFF) } else if (state == CaretState.VISIBLE_OFF) {
state = CaretState.VISIBLE_ON; state = CaretState.VISIBLE_ON;
}
} }
public void turnOn() { public void turnOn() {
if (state == CaretState.VISIBLE_OFF) if (state == CaretState.VISIBLE_OFF) {
state = CaretState.VISIBLE_ON; state = CaretState.VISIBLE_ON;
}
} }
public void setPosition(final int i) { public void setPosition(final int i) {

View File

@ -70,18 +70,18 @@ public abstract class Block implements TreeBlock, GraphicalElement {
} }
public abstract Feature toFeature(MathContext context) throws Error; public abstract Feature toFeature(MathContext context) throws Error;
@Override @Override
public TreeContainer getParentContainer() { public TreeContainer getParentContainer() {
return parent; return parent;
} }
@Override @Override
public boolean hasParent() { public boolean hasParent() {
return parent != null; return parent != null;
} }
public void setParent(TreeContainer parent) { public void setParent(final TreeContainer parent) {
this.parent = parent; this.parent = parent;
} }
} }

View File

@ -28,46 +28,48 @@ public class BlockContainer implements TreeContainer, GraphicalElement {
private int line; private int line;
public final boolean withBorder; public final boolean withBorder;
private boolean autoMinimums; private boolean autoMinimums;
private TreeBlock parent; private final TreeBlock parent;
public BlockContainer(TreeBlock parent) { public BlockContainer(final TreeBlock parent) {
this(parent, false, BlockContainer.getDefaultCharWidth(false), BlockContainer.getDefaultCharHeight(false), true); this(parent, false, BlockContainer.getDefaultCharWidth(false), BlockContainer.getDefaultCharHeight(false), true);
autoMinimums = true; autoMinimums = true;
} }
public BlockContainer(TreeBlock parent, final boolean small) { public BlockContainer(final TreeBlock parent, final boolean small) {
this(parent, small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), true); this(parent, small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), true);
autoMinimums = true; autoMinimums = true;
} }
public BlockContainer(TreeBlock parent, final boolean small, final ObjectArrayList<Block> content) { public BlockContainer(final TreeBlock parent, final boolean small, final ObjectArrayList<Block> content) {
this(parent, small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), content, true); this(parent, small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), content, true);
autoMinimums = true; autoMinimums = true;
} }
public BlockContainer(TreeBlock parent, final boolean small, final boolean withBorder) { public BlockContainer(final TreeBlock parent, final boolean small, final boolean withBorder) {
this(parent, small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), withBorder); this(parent, small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), withBorder);
autoMinimums = true; autoMinimums = true;
} }
public BlockContainer(TreeBlock parent, final boolean small, final int minWidth, final int minHeight, final boolean withBorder) { public BlockContainer(final TreeBlock parent, final boolean small, final int minWidth, final int minHeight, final boolean withBorder) {
this(parent, small, minWidth, minHeight, new ObjectArrayList<>(), withBorder); this(parent, small, minWidth, minHeight, new ObjectArrayList<>(), withBorder);
autoMinimums = false; autoMinimums = false;
} }
public BlockContainer(TreeBlock parent, final boolean small, final int minWidth, final int minHeight, final ObjectArrayList<Block> content, final boolean withBorder) { public BlockContainer(final TreeBlock parent, final boolean small, final int minWidth, final int minHeight, final ObjectArrayList<Block> content, final boolean withBorder) {
this.parent = parent; this.parent = parent;
this.small = small; this.small = small;
this.minWidth = minWidth; this.minWidth = minWidth;
this.minHeight = minHeight; this.minHeight = minHeight;
this.withBorder = withBorder; this.withBorder = withBorder;
for (final Block b : content) for (final Block b : content) {
if (b.isSmall() != small) if (b.isSmall() != small) {
b.setSmall(small); b.setSmall(small);
}
}
this.content = content; this.content = content;
recomputeDimensions(); recomputeDimensions();
} }
@Override @Override
public TreeBlock getParentBlock() { public TreeBlock getParentBlock() {
return parent; return parent;
@ -85,12 +87,14 @@ public class BlockContainer implements TreeContainer, GraphicalElement {
public void addBlockUnsafe(final int position, final Block b) { public void addBlockUnsafe(final int position, final Block b) {
b.setParent(this); b.setParent(this);
if (b.isSmall() != small) if (b.isSmall() != small) {
b.setSmall(small); b.setSmall(small);
if (position >= content.size()) }
if (position >= content.size()) {
content.add(b); content.add(b);
else } else {
content.add(position, b); content.add(position, b);
}
} }
public void appendBlock(final Block b) { public void appendBlock(final Block b) {
@ -100,8 +104,9 @@ public class BlockContainer implements TreeContainer, GraphicalElement {
public void appendBlockUnsafe(final Block b) { public void appendBlockUnsafe(final Block b) {
b.setParent(this); b.setParent(this);
if (b.isSmall() != small) if (b.isSmall() != small) {
b.setSmall(small); b.setSmall(small);
}
content.add(b); content.add(b);
} }
@ -150,11 +155,13 @@ public class BlockContainer implements TreeContainer, GraphicalElement {
public void draw(final GraphicEngine ge, final Renderer r, final int x, final int y, final Caret caret) { public void draw(final GraphicEngine ge, final Renderer r, final int x, final int y, final Caret caret) {
int paddingX = 1; int paddingX = 1;
if (caret.getRemaining() == 0) if (caret.getRemaining() == 0) {
if (content.size() > 0) if (content.size() > 0) {
BlockContainer.drawCaret(ge, r, caret, small, x, y + line - content.get(0).line, content.get(0).height); BlockContainer.drawCaret(ge, r, caret, small, x, y + line - content.get(0).line, content.get(0).height);
else } else {
BlockContainer.drawCaret(ge, r, caret, small, x, y, height); BlockContainer.drawCaret(ge, r, caret, small, x, y, height);
}
}
if (withBorder && content.size() == 0) { if (withBorder && content.size() == 0) {
r.glColor(BlockContainer.getDefaultColor()); r.glColor(BlockContainer.getDefaultColor());
@ -162,15 +169,17 @@ public class BlockContainer implements TreeContainer, GraphicalElement {
r.glDrawLine(x + paddingX, y, x + paddingX, y + height - 1); r.glDrawLine(x + paddingX, y, x + paddingX, y + height - 1);
r.glDrawLine(x + paddingX + width - 1, y, x + paddingX + width - 1, y + height - 1); r.glDrawLine(x + paddingX + width - 1, y, x + paddingX + width - 1, y + height - 1);
r.glDrawLine(x + paddingX, y + height - 1, x + paddingX + width - 1, y + height - 1); r.glDrawLine(x + paddingX, y + height - 1, x + paddingX + width - 1, y + height - 1);
} else } else {
for (final Block b : content) { for (final Block b : content) {
caret.skip(1); caret.skip(1);
b.draw(ge, r, x + paddingX, y + line - b.line, caret); b.draw(ge, r, x + paddingX, y + line - b.line, caret);
paddingX += b.getWidth(); paddingX += b.getWidth();
if (caret.getRemaining() == 0) if (caret.getRemaining() == 0) {
BlockContainer.drawCaret(ge, r, caret, small, x + paddingX, y + line - b.line, b.height); BlockContainer.drawCaret(ge, r, caret, small, x + paddingX, y + line - b.line, b.height);
}
paddingX += 1; paddingX += 1;
} }
}
caret.skip(1); caret.skip(1);
} }
@ -193,8 +202,9 @@ public class BlockContainer implements TreeContainer, GraphicalElement {
} }
} }
caret.skip(1); caret.skip(1);
if (added) if (added) {
recomputeDimensions(); recomputeDimensions();
}
return added; return added;
} }
@ -214,8 +224,9 @@ public class BlockContainer implements TreeContainer, GraphicalElement {
} }
} }
caret.skip(1); caret.skip(1);
if (removed) if (removed) {
recomputeDimensions(); recomputeDimensions();
}
return removed; return removed;
} }
@ -229,8 +240,9 @@ public class BlockContainer implements TreeContainer, GraphicalElement {
final int deltaCaret = caret.getRemaining(); final int deltaCaret = caret.getRemaining();
block = b.getBlock(caret); block = b.getBlock(caret);
if (block != null) if (block != null) {
return block; return block;
}
if (caret.getRemaining() == 0 || deltaCaret >= 0 && caret.getRemaining() < 0) { if (caret.getRemaining() == 0 || deltaCaret >= 0 && caret.getRemaining() < 0) {
block = getBlockAt(pos - 1); block = getBlockAt(pos - 1);
return block; return block;
@ -252,25 +264,29 @@ public class BlockContainer implements TreeContainer, GraphicalElement {
final int bl = b.getLine(); final int bl = b.getLine();
final int bh = b.getHeight(); final int bh = b.getHeight();
final int bh2 = bh - bl; final int bh2 = bh - bl;
if (bl > l) if (bl > l) {
l = bl; l = bl;
if (bh2 > h2) }
if (bh2 > h2) {
h2 = bh2; h2 = bh2;
}
} }
if (content.size() > 0) if (content.size() > 0) {
w -= 1; w -= 1;
}
h = h2 + l; h = h2 + l;
line = l; line = l;
if (w > minWidth) if (w > minWidth) {
width = w; width = w;
else } else {
width = minWidth; width = minWidth;
if (h > minHeight) }
if (h > minHeight) {
height = h; height = h;
else { } else {
height = minHeight; height = minHeight;
line = height / 2; line = height / 2;
} }
@ -340,8 +356,9 @@ public class BlockContainer implements TreeContainer, GraphicalElement {
minWidth = BlockContainer.getDefaultCharWidth(small); minWidth = BlockContainer.getDefaultCharWidth(small);
minHeight = BlockContainer.getDefaultCharHeight(small); minHeight = BlockContainer.getDefaultCharHeight(small);
} }
for (final Block b : content) for (final Block b : content) {
b.setSmall(small); b.setSmall(small);
}
recomputeDimensions(); recomputeDimensions();
} }
@ -350,14 +367,16 @@ public class BlockContainer implements TreeContainer, GraphicalElement {
} }
private static void checkInitialized() { private static void checkInitialized() {
if (!BlockContainer.initialized) if (!BlockContainer.initialized) {
Engine.getPlatform().throwNewExceptionInInitializerError("Please initialize BlockContainer by running the method BlockContainer.initialize(...) first!"); Engine.getPlatform().throwNewExceptionInInitializerError("Please initialize BlockContainer by running the method BlockContainer.initialize(...) first!");
}
} }
public int computeCaretMaxBound() { public int computeCaretMaxBound() {
int maxpos = 0; int maxpos = 0;
for (final Block b : content) for (final Block b : content) {
maxpos += 1 + b.computeCaretMaxBound(); maxpos += 1 + b.computeCaretMaxBound();
}
return maxpos + 1; return maxpos + 1;
} }
@ -367,8 +386,9 @@ public class BlockContainer implements TreeContainer, GraphicalElement {
for (final Block block : blocks) { for (final Block block : blocks) {
final Feature blockFeature = block.toFeature(context); final Feature blockFeature = block.toFeature(context);
if (blockFeature == null) if (blockFeature == null) {
throw new Error(Errors.NOT_IMPLEMENTED, "The block " + block.getClass().getSimpleName() + " isn't a known Block"); throw new Error(Errors.NOT_IMPLEMENTED, "The block " + block.getClass().getSimpleName() + " isn't a known Block");
}
blockFeatures.add(blockFeature); blockFeatures.add(blockFeature);
} }

View File

@ -39,8 +39,9 @@ public class BlockDivision extends Block {
boolean added = false; boolean added = false;
added = added | containerUp.putBlock(caret, newBlock); added = added | containerUp.putBlock(caret, newBlock);
added = added | containerDown.putBlock(caret, newBlock); added = added | containerDown.putBlock(caret, newBlock);
if (added) if (added) {
recomputeDimensions(); recomputeDimensions();
}
return added; return added;
} }
@ -49,8 +50,9 @@ public class BlockDivision extends Block {
boolean removed = false; boolean removed = false;
removed = removed | containerUp.delBlock(caret); removed = removed | containerUp.delBlock(caret);
removed = removed | containerDown.delBlock(caret); removed = removed | containerDown.delBlock(caret);
if (removed) if (removed) {
recomputeDimensions(); recomputeDimensions();
}
return removed; return removed;
} }
@ -58,8 +60,9 @@ public class BlockDivision extends Block {
public BlockReference<?> getBlock(final Caret caret) { public BlockReference<?> getBlock(final Caret caret) {
BlockReference<?> bl = null; BlockReference<?> bl = null;
bl = containerUp.getBlock(caret); bl = containerUp.getBlock(caret);
if (bl != null) if (bl != null) {
return bl; return bl;
}
bl = containerDown.getBlock(caret); bl = containerDown.getBlock(caret);
return bl; return bl;
} }

View File

@ -43,8 +43,9 @@ public class BlockLogarithm extends Block implements IParenthesis {
public void draw(final GraphicEngine ge, final Renderer r, final int x, final int y, final Caret caret) { public void draw(final GraphicEngine ge, final Renderer r, final int x, final int y, final Caret caret) {
BlockContainer.getDefaultFont(small).use(ge); BlockContainer.getDefaultFont(small).use(ge);
r.glColor(BlockContainer.getDefaultColor()); r.glColor(BlockContainer.getDefaultColor());
if (prefix != null) if (prefix != null) {
r.glDrawStringLeft(x + 1, y + line - chh / 2, prefix); r.glDrawStringLeft(x + 1, y + line - chh / 2, prefix);
}
r.glDrawCharLeft(x + bw + prw, y + toph, '╭'); r.glDrawCharLeft(x + bw + prw, y + toph, '╭');
r.glDrawCharLeft(x + bw + prw, y + toph + nmbh - chh, '╰'); r.glDrawCharLeft(x + bw + prw, y + toph + nmbh - chh, '╰');
if (small) { if (small) {
@ -67,8 +68,9 @@ public class BlockLogarithm extends Block implements IParenthesis {
boolean added = false; boolean added = false;
added = added | containerBase.putBlock(caret, newBlock); added = added | containerBase.putBlock(caret, newBlock);
added = added | containerNumber.putBlock(caret, newBlock); added = added | containerNumber.putBlock(caret, newBlock);
if (added) if (added) {
recomputeDimensions(); recomputeDimensions();
}
return added; return added;
} }
@ -77,8 +79,9 @@ public class BlockLogarithm extends Block implements IParenthesis {
boolean removed = false; boolean removed = false;
removed = removed | containerBase.delBlock(caret); removed = removed | containerBase.delBlock(caret);
removed = removed | containerNumber.delBlock(caret); removed = removed | containerNumber.delBlock(caret);
if (removed) if (removed) {
recomputeDimensions(); recomputeDimensions();
}
return removed; return removed;
} }
@ -86,18 +89,20 @@ public class BlockLogarithm extends Block implements IParenthesis {
public BlockReference<?> getBlock(final Caret caret) { public BlockReference<?> getBlock(final Caret caret) {
BlockReference<?> bl = null; BlockReference<?> bl = null;
bl = containerBase.getBlock(caret); bl = containerBase.getBlock(caret);
if (bl != null) if (bl != null) {
return bl; return bl;
}
bl = containerNumber.getBlock(caret); bl = containerNumber.getBlock(caret);
return bl; return bl;
} }
@Override @Override
public void recomputeDimensions() { public void recomputeDimensions() {
if (prefix == null) if (prefix == null) {
prw = 0; prw = 0;
else } else {
prw = 1 + BlockContainer.getDefaultCharWidth(small) * prefix.length(); prw = 1 + BlockContainer.getDefaultCharWidth(small) * prefix.length();
}
bw = containerBase.getWidth(); bw = containerBase.getWidth();
bh = containerBase.getHeight(); bh = containerBase.getHeight();
bl = containerBase.getLine(); bl = containerBase.getLine();
@ -110,18 +115,20 @@ public class BlockLogarithm extends Block implements IParenthesis {
if (bl > nmbh) { if (bl > nmbh) {
toph = bl - nmbh; toph = bl - nmbh;
line = toph + nl; line = toph + nl;
if (bl + bh - bl > toph + nmbh) if (bl + bh - bl > toph + nmbh) {
height = bl + bh - bl; height = bl + bh - bl;
else } else {
height = toph + nmbh; height = toph + nmbh;
}
} else { } else {
System.out.println("b"); System.out.println("b");
toph = 0; toph = 0;
line = toph + nl; line = toph + nl;
if (nmbh + bh - bl > toph + nmbh) if (nmbh + bh - bl > toph + nmbh) {
height = nmbh + bh - bl; height = nmbh + bh - bl;
else } else {
height = toph + nmbh; height = toph + nmbh;
}
} }
} }

View File

@ -8,8 +8,7 @@ import it.cavallium.warppi.util.Error;
import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.ObjectArrayList;
public class BlockParenthesis extends BlockParenthesisAbstract { public class BlockParenthesis extends BlockParenthesisAbstract {
public BlockParenthesis() { public BlockParenthesis() {}
}
public BlockParenthesis(final ObjectArrayList<Block> blocks) { public BlockParenthesis(final ObjectArrayList<Block> blocks) {
super(blocks); super(blocks);

View File

@ -40,8 +40,9 @@ public abstract class BlockParenthesisAbstract extends Block implements IParenth
public void draw(final GraphicEngine ge, final Renderer r, final int x, final int y, final Caret caret) { public void draw(final GraphicEngine ge, final Renderer r, final int x, final int y, final Caret caret) {
BlockContainer.getDefaultFont(small).use(ge); BlockContainer.getDefaultFont(small).use(ge);
r.glColor(BlockContainer.getDefaultColor()); r.glColor(BlockContainer.getDefaultColor());
if (prefix != null) if (prefix != null) {
r.glDrawStringLeft(x + 1, y + line - chh / 2, prefix); r.glDrawStringLeft(x + 1, y + line - chh / 2, prefix);
}
r.glDrawCharLeft(x + prw, y, '╭'); r.glDrawCharLeft(x + prw, y, '╭');
r.glDrawCharLeft(x + prw, y + height - chh, '╰'); r.glDrawCharLeft(x + prw, y + height - chh, '╰');
if (small) { if (small) {
@ -60,8 +61,9 @@ public abstract class BlockParenthesisAbstract extends Block implements IParenth
public boolean putBlock(final Caret caret, final Block newBlock) { public boolean putBlock(final Caret caret, final Block newBlock) {
boolean added = false; boolean added = false;
added = added | containerNumber.putBlock(caret, newBlock); added = added | containerNumber.putBlock(caret, newBlock);
if (added) if (added) {
recomputeDimensions(); recomputeDimensions();
}
return added; return added;
} }
@ -69,8 +71,9 @@ public abstract class BlockParenthesisAbstract extends Block implements IParenth
public boolean delBlock(final Caret caret) { public boolean delBlock(final Caret caret) {
boolean removed = false; boolean removed = false;
removed = removed | containerNumber.delBlock(caret); removed = removed | containerNumber.delBlock(caret);
if (removed) if (removed) {
recomputeDimensions(); recomputeDimensions();
}
return removed; return removed;
} }
@ -81,10 +84,11 @@ public abstract class BlockParenthesisAbstract extends Block implements IParenth
@Override @Override
public void recomputeDimensions() { public void recomputeDimensions() {
if (prefix == null) if (prefix == null) {
prw = 0; prw = 0;
else } else {
prw = 1 + BlockContainer.getDefaultCharWidth(small) * prefix.length() + 2; prw = 1 + BlockContainer.getDefaultCharWidth(small) * prefix.length() + 2;
}
chw = BlockContainer.getDefaultCharWidth(small); chw = BlockContainer.getDefaultCharWidth(small);
chh = BlockContainer.getDefaultCharHeight(small); chh = BlockContainer.getDefaultCharHeight(small);
width = prw + chw + containerNumber.getWidth() + chw + 3; width = prw + chw + containerNumber.getWidth() + chw + 3;

View File

@ -29,8 +29,9 @@ public class BlockPower extends Block {
public boolean putBlock(final Caret caret, final Block newBlock) { public boolean putBlock(final Caret caret, final Block newBlock) {
boolean added = false; boolean added = false;
added = added | containerExponent.putBlock(caret, newBlock); added = added | containerExponent.putBlock(caret, newBlock);
if (added) if (added) {
recomputeDimensions(); recomputeDimensions();
}
return added; return added;
} }
@ -38,8 +39,9 @@ public class BlockPower extends Block {
public boolean delBlock(final Caret caret) { public boolean delBlock(final Caret caret) {
boolean removed = false; boolean removed = false;
removed = removed | containerExponent.delBlock(caret); removed = removed | containerExponent.delBlock(caret);
if (removed) if (removed) {
recomputeDimensions(); recomputeDimensions();
}
return removed; return removed;
} }

View File

@ -35,8 +35,9 @@ public class BlockPower2 extends Block {
public boolean putBlock(final Caret caret, final Block newBlock) { public boolean putBlock(final Caret caret, final Block newBlock) {
boolean added = false; boolean added = false;
added = added | containerExponent.putBlock(caret, newBlock); added = added | containerExponent.putBlock(caret, newBlock);
if (added) if (added) {
recomputeDimensions(); recomputeDimensions();
}
return added; return added;
} }
@ -44,8 +45,9 @@ public class BlockPower2 extends Block {
public boolean delBlock(final Caret caret) { public boolean delBlock(final Caret caret) {
boolean removed = false; boolean removed = false;
removed = removed | containerExponent.delBlock(caret); removed = removed | containerExponent.delBlock(caret);
if (removed) if (removed) {
recomputeDimensions(); recomputeDimensions();
}
return removed; return removed;
} }

View File

@ -40,8 +40,9 @@ public class BlockReference<T extends Block> {
} }
private BlockReference<?> getBlockAtSafe(final int i) { private BlockReference<?> getBlockAtSafe(final int i) {
if (isInsideBounds(i)) if (isInsideBounds(i)) {
return container.getBlockAt(i); return container.getBlockAt(i);
}
return null; return null;
} }

View File

@ -39,8 +39,9 @@ public class BlockSquareRoot extends Block {
public boolean putBlock(final Caret caret, final Block newBlock) { public boolean putBlock(final Caret caret, final Block newBlock) {
boolean added = false; boolean added = false;
added = added | containerNumber.putBlock(caret, newBlock); added = added | containerNumber.putBlock(caret, newBlock);
if (added) if (added) {
recomputeDimensions(); recomputeDimensions();
}
return added; return added;
} }
@ -48,8 +49,9 @@ public class BlockSquareRoot extends Block {
public boolean delBlock(final Caret caret) { public boolean delBlock(final Caret caret) {
boolean removed = false; boolean removed = false;
removed = removed | containerNumber.delBlock(caret); removed = removed | containerNumber.delBlock(caret);
if (removed) if (removed) {
recomputeDimensions(); recomputeDimensions();
}
return removed; return removed;
} }

View File

@ -44,11 +44,13 @@ public class BlockVariable extends Block {
private void retrieveValue() { private void retrieveValue() {
type = ic.variableTypes.get(ch); type = ic.variableTypes.get(ch);
if (type == null) if (type == null) {
type = V_TYPE.VARIABLE; type = V_TYPE.VARIABLE;
}
typeDirtyID = ic.variableTypeDirtyID; typeDirtyID = ic.variableTypeDirtyID;
if (menu != null) if (menu != null) {
menu.mustRefreshMenu = true; menu.mustRefreshMenu = true;
}
mustRefresh = true; mustRefresh = true;
System.out.println("retrieve:" + type.toString()); System.out.println("retrieve:" + type.toString());
} }
@ -67,8 +69,9 @@ public class BlockVariable extends Block {
@Override @Override
public void draw(final GraphicEngine ge, final Renderer r, final int x, final int y, final Caret caret) { public void draw(final GraphicEngine ge, final Renderer r, final int x, final int y, final Caret caret) {
if (ic.variableTypeDirtyID != typeDirtyID) if (ic.variableTypeDirtyID != typeDirtyID) {
retrieveValue(); retrieveValue();
}
if (mustRefresh) { if (mustRefresh) {
mustRefresh = false; mustRefresh = false;
switch (type) { switch (type) {
@ -222,15 +225,19 @@ public class BlockVariable extends Block {
Engine.INSTANCE.getHardwareDevice().getDisplayManager().guiSkin.use(ge); Engine.INSTANCE.getHardwareDevice().getDisplayManager().guiSkin.use(ge);
int popupX = location[0]; int popupX = location[0];
int popupY = location[1]; int popupY = location[1];
if (popupX < 0) if (popupX < 0) {
popupX = 0; popupX = 0;
if (popupY < 0) }
if (popupY < 0) {
popupY = 0; popupY = 0;
}
final int[] screenSize = ge.getSize(); final int[] screenSize = ge.getSize();
if (popupX + width >= screenSize[0]) if (popupX + width >= screenSize[0]) {
popupX = screenSize[0] - width - 1; popupX = screenSize[0] - width - 1;
if (popupY + height >= screenSize[1]) }
if (popupY + height >= screenSize[1]) {
popupY = screenSize[1] - height - 1; popupY = screenSize[1] - height - 1;
}
r.glFillRect(location[0] + width / 2 - 5, popupY + 1, 10, 5, 163, 16, 10, 5); r.glFillRect(location[0] + width / 2 - 5, popupY + 1, 10, 5, 163, 16, 10, 5);
r.glFillColor(popupX, popupY + 5, width, height); r.glFillColor(popupX, popupY + 5, width, height);
r.glFillColor(popupX + 2, popupY + 4, width - 4, height + 2); r.glFillColor(popupX + 2, popupY + 4, width - 4, height + 2);

View File

@ -1,6 +1,7 @@
package it.cavallium.warppi.gui.expression.blocks; package it.cavallium.warppi.gui.expression.blocks;
public interface TreeBlock { public interface TreeBlock {
public TreeContainer getParentContainer(); TreeContainer getParentContainer();
public boolean hasParent();
boolean hasParent();
} }

View File

@ -1,6 +1,7 @@
package it.cavallium.warppi.gui.expression.blocks; package it.cavallium.warppi.gui.expression.blocks;
public interface TreeContainer { public interface TreeContainer {
public TreeBlock getParentBlock(); TreeBlock getParentBlock();
public boolean hasParent();
boolean hasParent();
} }

View File

@ -1,15 +1,8 @@
package it.cavallium.warppi.gui.expression.containers; package it.cavallium.warppi.gui.expression.containers;
import it.cavallium.warppi.gui.expression.Caret;
import it.cavallium.warppi.gui.expression.InputContext; import it.cavallium.warppi.gui.expression.InputContext;
import it.cavallium.warppi.gui.expression.blocks.Block; import it.cavallium.warppi.gui.expression.blocks.Block;
import it.cavallium.warppi.gui.expression.blocks.BlockChar; import it.cavallium.warppi.gui.expression.blocks.BlockChar;
import it.cavallium.warppi.gui.expression.blocks.BlockReference;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
import it.cavallium.warppi.gui.graphicengine.Renderer;
import it.cavallium.warppi.math.MathContext;
import it.cavallium.warppi.math.parser.features.interfaces.Feature;
import it.cavallium.warppi.util.Error;
public class InlineInputContainer extends InputContainer { public class InlineInputContainer extends InputContainer {

View File

@ -11,8 +11,6 @@ import it.cavallium.warppi.gui.expression.InputContext;
import it.cavallium.warppi.gui.expression.blocks.Block; import it.cavallium.warppi.gui.expression.blocks.Block;
import it.cavallium.warppi.gui.expression.blocks.BlockContainer; import it.cavallium.warppi.gui.expression.blocks.BlockContainer;
import it.cavallium.warppi.gui.expression.blocks.BlockReference; import it.cavallium.warppi.gui.expression.blocks.BlockReference;
import it.cavallium.warppi.gui.expression.blocks.TreeContainer;
import it.cavallium.warppi.gui.expression.blocks.TreeBlock;
import it.cavallium.warppi.gui.expression.layouts.InputLayout; import it.cavallium.warppi.gui.expression.layouts.InputLayout;
import it.cavallium.warppi.gui.graphicengine.GraphicEngine; import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
import it.cavallium.warppi.gui.graphicengine.Renderer; import it.cavallium.warppi.gui.graphicengine.Renderer;
@ -83,8 +81,9 @@ public abstract class InputContainer implements GraphicalElement, InputLayout, S
public void del() { public void del() {
caret.resetRemaining(); caret.resetRemaining();
if (root.delBlock(caret)) if (root.delBlock(caret)) {
root.recomputeDimensions(); root.recomputeDimensions();
}
if (caret.getPosition() > 0) { if (caret.getPosition() > 0) {
caret.setPosition(caret.getPosition() - 1); caret.setPosition(caret.getPosition() - 1);
maxPosition = root.computeCaretMaxBound(); maxPosition = root.computeCaretMaxBound();
@ -100,38 +99,41 @@ public abstract class InputContainer implements GraphicalElement, InputLayout, S
return selectedBlock; return selectedBlock;
} }
public BlockReference<?> getBlockAtCaretPosition(int i) { public BlockReference<?> getBlockAtCaretPosition(final int i) {
final BlockReference<?> selectedBlock = root.getBlock(new Caret(CaretState.HIDDEN, i)); final BlockReference<?> selectedBlock = root.getBlock(new Caret(CaretState.HIDDEN, i));
return selectedBlock; return selectedBlock;
} }
public void moveLeft() { public void moveLeft() {
final int curPos = caret.getPosition(); final int curPos = caret.getPosition();
if (curPos > 0) if (curPos > 0) {
caret.setPosition(curPos - 1); caret.setPosition(curPos - 1);
else } else {
caret.setPosition(maxPosition - 1); caret.setPosition(maxPosition - 1);
}
caret.turnOn(); caret.turnOn();
caretTime = 0; caretTime = 0;
closeExtra(); closeExtra();
} }
public void moveRight(int delta) { public void moveRight(final int delta) {
final int curPos = caret.getPosition(); final int curPos = caret.getPosition();
if (curPos + delta < maxPosition) if (curPos + delta < maxPosition) {
caret.setPosition(curPos + delta); caret.setPosition(curPos + delta);
else } else {
caret.setPosition(0); caret.setPosition(0);
}
caret.turnOn(); caret.turnOn();
caretTime = 0; caretTime = 0;
closeExtra(); closeExtra();
} }
public void moveTo(int position) { public void moveTo(final int position) {
if (position < maxPosition) if (position < maxPosition) {
caret.setPosition(position); caret.setPosition(position);
else } else {
caret.setPosition(0); caret.setPosition(0);
}
caret.turnOn(); caret.turnOn();
caretTime = 0; caretTime = 0;
closeExtra(); closeExtra();
@ -170,15 +172,17 @@ public abstract class InputContainer implements GraphicalElement, InputLayout, S
public boolean beforeRender(final float delta) { public boolean beforeRender(final float delta) {
boolean somethingChanged = false; boolean somethingChanged = false;
caretTime += delta; caretTime += delta;
if (caretTime >= InputContainer.CARET_DURATION) if (caretTime >= InputContainer.CARET_DURATION) {
while (caretTime >= InputContainer.CARET_DURATION) { while (caretTime >= InputContainer.CARET_DURATION) {
caretTime -= InputContainer.CARET_DURATION; caretTime -= InputContainer.CARET_DURATION;
caret.flipState(); caret.flipState();
somethingChanged = true; somethingChanged = true;
} }
}
if (extra != null) if (extra != null) {
somethingChanged = somethingChanged | extra.beforeRender(delta, caret); somethingChanged = somethingChanged | extra.beforeRender(delta, caret);
}
return somethingChanged; return somethingChanged;
} }
@ -197,8 +201,9 @@ public abstract class InputContainer implements GraphicalElement, InputLayout, S
public void draw(final GraphicEngine ge, final Renderer r, final int x, final int y) { public void draw(final GraphicEngine ge, final Renderer r, final int x, final int y) {
caret.resetRemaining(); caret.resetRemaining();
root.draw(ge, r, x, y, caret); root.draw(ge, r, x, y, caret);
if (extra != null) if (extra != null) {
extra.draw(ge, r, caret); extra.draw(ge, r, caret);
}
} }
public void clear() { public void clear() {
@ -217,8 +222,9 @@ public abstract class InputContainer implements GraphicalElement, InputLayout, S
} }
public void setCaretPosition(final int pos) { public void setCaretPosition(final int pos) {
if (pos > 0 && pos < maxPosition) if (pos > 0 && pos < maxPosition) {
caret.setPosition(pos); caret.setPosition(pos);
}
caret.turnOn(); caret.turnOn();
caretTime = 0; caretTime = 0;
closeExtra(); closeExtra();
@ -246,8 +252,9 @@ public abstract class InputContainer implements GraphicalElement, InputLayout, S
final BlockReference<?> selectedBlock = getSelectedBlock(); final BlockReference<?> selectedBlock = getSelectedBlock();
if (selectedBlock != null) { if (selectedBlock != null) {
extra = selectedBlock.get().getExtraMenu(); extra = selectedBlock.get().getExtraMenu();
if (extra != null) if (extra != null) {
extra.open(); extra.open();
}
} }
} else { } else {
extra.close(); extra.close();

View File

@ -10,7 +10,6 @@ import it.cavallium.warppi.gui.expression.blocks.BlockDivision;
import it.cavallium.warppi.gui.expression.blocks.BlockLogarithm; import it.cavallium.warppi.gui.expression.blocks.BlockLogarithm;
import it.cavallium.warppi.gui.expression.blocks.BlockNumericChar; import it.cavallium.warppi.gui.expression.blocks.BlockNumericChar;
import it.cavallium.warppi.gui.expression.blocks.BlockParenthesis; import it.cavallium.warppi.gui.expression.blocks.BlockParenthesis;
import it.cavallium.warppi.gui.expression.blocks.BlockParenthesisAbstract;
import it.cavallium.warppi.gui.expression.blocks.BlockPower; import it.cavallium.warppi.gui.expression.blocks.BlockPower;
import it.cavallium.warppi.gui.expression.blocks.BlockPower2; import it.cavallium.warppi.gui.expression.blocks.BlockPower2;
import it.cavallium.warppi.gui.expression.blocks.BlockReference; import it.cavallium.warppi.gui.expression.blocks.BlockReference;
@ -18,8 +17,6 @@ import it.cavallium.warppi.gui.expression.blocks.BlockSine;
import it.cavallium.warppi.gui.expression.blocks.BlockSquareRoot; import it.cavallium.warppi.gui.expression.blocks.BlockSquareRoot;
import it.cavallium.warppi.gui.expression.blocks.BlockVariable; import it.cavallium.warppi.gui.expression.blocks.BlockVariable;
import it.cavallium.warppi.gui.expression.blocks.IParenthesis; import it.cavallium.warppi.gui.expression.blocks.IParenthesis;
import it.cavallium.warppi.gui.expression.blocks.TreeBlock;
import it.cavallium.warppi.gui.expression.blocks.TreeContainer;
import it.cavallium.warppi.math.MathematicalSymbols; import it.cavallium.warppi.math.MathematicalSymbols;
public class NormalInputContainer extends InputContainer { public class NormalInputContainer extends InputContainer {
@ -87,9 +84,11 @@ public class NormalInputContainer extends InputContainer {
case MathematicalSymbols.EULER_NUMBER: case MathematicalSymbols.EULER_NUMBER:
return new BlockVariable(inputContext, c, true); return new BlockVariable(inputContext, c, true);
default: default:
for (final char v : MathematicalSymbols.variables) for (final char v : MathematicalSymbols.variables) {
if (c == v) if (c == v) {
return new BlockVariable(inputContext, c); return new BlockVariable(inputContext, c);
}
}
return new BlockChar(c); return new BlockChar(c);
} }
} }
@ -99,18 +98,18 @@ public class NormalInputContainer extends InputContainer {
super.typeChar(c); super.typeChar(c);
switch (c) { switch (c) {
case MathematicalSymbols.PARENTHESIS_CLOSE: { case MathematicalSymbols.PARENTHESIS_CLOSE: {
BlockReference<?> ref = getSelectedBlock(); final BlockReference<?> ref = getSelectedBlock();
if (ref == null) { if (ref == null) {
break; break;
} else { } else {
Caret newCaret = new Caret(CaretState.HIDDEN, caret.getPosition()); final Caret newCaret = new Caret(CaretState.HIDDEN, caret.getPosition());
BlockContainer currentContainer; BlockContainer currentContainer;
BlockReference<?> newRef = ref; BlockReference<?> newRef = ref;
int safeExit = 0; int safeExit = 0;
do { do {
currentContainer = (BlockContainer) newRef.get().getParentContainer(); currentContainer = (BlockContainer) newRef.get().getParentContainer();
int initialRelativeIndex = currentContainer.getContent().indexOf(newRef.get()); final int initialRelativeIndex = currentContainer.getContent().indexOf(newRef.get());
int newIndex = newCaret.getPosition() + (currentContainer.getContent().size() - initialRelativeIndex); final int newIndex = newCaret.getPosition() + currentContainer.getContent().size() - initialRelativeIndex;
newRef = getBlockAtCaretPosition(newIndex); newRef = getBlockAtCaretPosition(newIndex);
newCaret.setPosition(newIndex); newCaret.setPosition(newIndex);
safeExit++; safeExit++;
@ -134,15 +133,18 @@ public class NormalInputContainer extends InputContainer {
int before = 0; int before = 0;
while (true) { while (true) {
currentBlock = currentBlock.getPreviousBlock(); currentBlock = currentBlock.getPreviousBlock();
if (currentBlock == null) if (currentBlock == null) {
break; break;
}
final Block b = currentBlock.get(); final Block b = currentBlock.get();
if (b instanceof BlockNumericChar || b instanceof BlockVariable) { if (b instanceof BlockNumericChar || b instanceof BlockVariable) {
if (!groupedBefore) if (!groupedBefore) {
groupedBefore = true; groupedBefore = true;
}
before++; before++;
} else } else {
break; break;
}
} }
if (groupedBefore) { if (groupedBefore) {
moveLeft(); moveLeft();
@ -154,8 +156,9 @@ public class NormalInputContainer extends InputContainer {
moveLeft(); moveLeft();
moveLeft(); moveLeft();
} }
for (int i = 0; i < before + 1; i++) for (int i = 0; i < before + 1; i++) {
moveRight(); moveRight();
}
moveRight();// Move to the divisor moveRight();// Move to the divisor
} }
break; break;

View File

@ -35,8 +35,9 @@ public abstract class OutputContainer implements GraphicalElement, OutputLayout,
public void setContentAsSingleGroup(final ObjectArrayList<Block> blocks) { public void setContentAsSingleGroup(final ObjectArrayList<Block> blocks) {
roots.clear(); roots.clear();
final BlockContainer bcnt = new BlockContainer(null); final BlockContainer bcnt = new BlockContainer(null);
for (final Block block : blocks) for (final Block block : blocks) {
bcnt.appendBlockUnsafe(block); bcnt.appendBlockUnsafe(block);
}
roots.add(bcnt); roots.add(bcnt);
recomputeDimensions(); recomputeDimensions();
} }
@ -45,8 +46,9 @@ public abstract class OutputContainer implements GraphicalElement, OutputLayout,
this.roots.clear(); this.roots.clear();
for (final ObjectArrayList<Block> blocks : roots) { for (final ObjectArrayList<Block> blocks : roots) {
final BlockContainer bcnt = new BlockContainer(null); final BlockContainer bcnt = new BlockContainer(null);
for (final Block block : blocks) for (final Block block : blocks) {
bcnt.appendBlockUnsafe(block); bcnt.appendBlockUnsafe(block);
}
this.roots.add(bcnt); this.roots.add(bcnt);
} }
recomputeDimensions(); recomputeDimensions();
@ -64,8 +66,9 @@ public abstract class OutputContainer implements GraphicalElement, OutputLayout,
@Override @Override
public void recomputeDimensions() { public void recomputeDimensions() {
for (final BlockContainer root : roots) for (final BlockContainer root : roots) {
root.recomputeDimensions(); root.recomputeDimensions();
}
} }
@Override @Override
@ -73,8 +76,9 @@ public abstract class OutputContainer implements GraphicalElement, OutputLayout,
int maxw = 0; int maxw = 0;
for (final BlockContainer root : roots) { for (final BlockContainer root : roots) {
final int w = root.getWidth(); final int w = root.getWidth();
if (w > maxw) if (w > maxw) {
maxw = w; maxw = w;
}
} }
return maxw; return maxw;
} }
@ -82,12 +86,14 @@ public abstract class OutputContainer implements GraphicalElement, OutputLayout,
@Override @Override
public int getHeight() { public int getHeight() {
int h = 0; int h = 0;
for (final BlockContainer root : roots) for (final BlockContainer root : roots) {
h += root.getHeight() + 2; h += root.getHeight() + 2;
if (h > 0) }
if (h > 0) {
return h - 2; return h - 2;
else } else {
return h; return h;
}
} }
@Override @Override
@ -132,8 +138,9 @@ public abstract class OutputContainer implements GraphicalElement, OutputLayout,
public boolean isContentEmpty() { public boolean isContentEmpty() {
for (final BlockContainer root : roots) { for (final BlockContainer root : roots) {
final ObjectArrayList<Block> cnt = root.getContent(); final ObjectArrayList<Block> cnt = root.getContent();
if (cnt != null && !cnt.isEmpty()) if (cnt != null && !cnt.isEmpty()) {
return false; return false;
}
} }
return true; return true;
} }

View File

@ -26,8 +26,9 @@ public abstract class PngSkin implements Skin {
@Override @Override
public void load(String file) throws IOException { public void load(String file) throws IOException {
if (!file.startsWith("/")) if (!file.startsWith("/")) {
file = "/" + file; file = "/" + file;
}
try { try {
if (!file.endsWith(".png")) { if (!file.endsWith(".png")) {
final File f = File.createTempFile("picalculator-png", ".png"); final File f = File.createTempFile("picalculator-png", ".png");

View File

@ -104,8 +104,9 @@ public abstract class RFTFont implements BinaryFont {
private void loadFont(String string) throws IOException { private void loadFont(String string) throws IOException {
InputStream res; InputStream res;
try { try {
if (!string.startsWith("/")) if (!string.startsWith("/")) {
string = "/" + string; string = "/" + string;
}
res = Engine.getPlatform().getStorageUtils().getResourceStream(string); res = Engine.getPlatform().getStorageUtils().getResourceStream(string);
} catch (final URISyntaxException e) { } catch (final URISyntaxException e) {
final IOException ex = new IOException(); final IOException ex = new IOException();
@ -122,25 +123,29 @@ public abstract class RFTFont implements BinaryFont {
charIntCount = (int) Math.ceil((double) charS / (double) RFTFont.intBits); charIntCount = (int) Math.ceil((double) charS / (double) RFTFont.intBits);
minBound = file[0x9] << 24 | file[0xA] << 16 | file[0xB] << 8 | file[0xC]; minBound = file[0x9] << 24 | file[0xA] << 16 | file[0xB] << 8 | file[0xC];
maxBound = file[0xE] << 24 | file[0xF] << 16 | file[0x10] << 8 | file[0x11]; maxBound = file[0xE] << 24 | file[0xF] << 16 | file[0x10] << 8 | file[0x11];
if (maxBound <= minBound) if (maxBound <= minBound) {
maxBound = 66000; //TODO remove it: temp fix maxBound = 66000; //TODO remove it: temp fix
}
rawchars = new boolean[maxBound - minBound][]; rawchars = new boolean[maxBound - minBound][];
int index = 0x12; int index = 0x12;
while (index < filelength) while (index < filelength) {
try { try {
final int charIndex = file[index] << 8 | file[index + 1]; final int charIndex = file[index] << 8 | file[index + 1];
final boolean[] rawchar = new boolean[charS]; final boolean[] rawchar = new boolean[charS];
int charbytescount = 0; int charbytescount = 0;
while (charbytescount * 8 < charS) while (charbytescount * 8 < charS) {
charbytescount += 1; charbytescount += 1;
}
int currentBit = 0; int currentBit = 0;
for (int i = 0; i <= charbytescount; i++) for (int i = 0; i <= charbytescount; i++) {
for (int bit = 0; bit < 8; bit++) { for (int bit = 0; bit < 8; bit++) {
if (currentBit >= charS) if (currentBit >= charS) {
break; break;
}
rawchar[currentBit] = (file[index + 2 + i] >> 8 - 1 - bit & 0x1) == 1 ? true : false; rawchar[currentBit] = (file[index + 2 + i] >> 8 - 1 - bit & 0x1) == 1 ? true : false;
currentBit++; currentBit++;
} }
}
rawchars[charIndex - minBound] = rawchar; rawchars[charIndex - minBound] = rawchar;
index += 2 + charbytescount; index += 2 + charbytescount;
} catch (final Exception ex) { } catch (final Exception ex) {
@ -148,10 +153,13 @@ public abstract class RFTFont implements BinaryFont {
System.out.println(string); System.out.println(string);
Engine.getPlatform().exit(-1); Engine.getPlatform().exit(-1);
} }
} else }
} else {
throw new IOException(); throw new IOException();
} else }
} else {
throw new IOException(); throw new IOException();
}
findIntervals(); findIntervals();
/*int[] screen = new int[rawchars.length * charW * charH]; /*int[] screen = new int[rawchars.length * charW * charH];
for (int i = 0; i < rawchars.length; i++) { for (int i = 0; i < rawchars.length; i++) {
@ -179,12 +187,13 @@ public abstract class RFTFont implements BinaryFont {
int intervalSize = 0; int intervalSize = 0;
@SuppressWarnings("unused") @SuppressWarnings("unused")
final int holeSize = 0; final int holeSize = 0;
for (int i = 0; i < rawchars.length; i++) for (int i = 0; i < rawchars.length; i++) {
if (rawchars[i] != null) { if (rawchars[i] != null) {
beginIndex = i; beginIndex = i;
int firstNull = 0; int firstNull = 0;
while (i + firstNull < rawchars.length && rawchars[i + firstNull] != null) while (i + firstNull < rawchars.length && rawchars[i + firstNull] != null) {
firstNull++; firstNull++;
}
endIndex = beginIndex + firstNull - 1; endIndex = beginIndex + firstNull - 1;
i = endIndex; i = endIndex;
if (endIndex >= 0) { if (endIndex >= 0) {
@ -194,6 +203,7 @@ public abstract class RFTFont implements BinaryFont {
} }
beginIndex = -1; beginIndex = -1;
} }
}
int lastIndex = 0; int lastIndex = 0;
final boolean[][] newrawchars = new boolean[intervalsTotalSize][]; final boolean[][] newrawchars = new boolean[intervalsTotalSize][];
for (final int[] interval : intervals) { for (final int[] interval : intervals) {
@ -250,14 +260,16 @@ public abstract class RFTFont implements BinaryFont {
protected int compressIndex(final int originalIndex) { protected int compressIndex(final int originalIndex) {
int compressedIndex = 0; int compressedIndex = 0;
for (int i = 0; i < intervals.length; i += 3) for (int i = 0; i < intervals.length; i += 3) {
if (intervals[i] > originalIndex) if (intervals[i] > originalIndex) {
break; break;
else if (originalIndex <= intervals[i + 1]) { } else if (originalIndex <= intervals[i + 1]) {
compressedIndex += originalIndex - intervals[i]; compressedIndex += originalIndex - intervals[i];
break; break;
} else } else {
compressedIndex += intervals[i + 2]; compressedIndex += intervals[i + 2];
}
}
return compressedIndex; return compressedIndex;
} }
@ -267,10 +279,11 @@ public abstract class RFTFont implements BinaryFont {
int i = 0; int i = 0;
for (int intvl = 0; intvl < intervals.length; intvl += 3) { for (int intvl = 0; intvl < intervals.length; intvl += 3) {
i += intervals[intvl + 2]; i += intervals[intvl + 2];
if (i == compressedIndex) if (i == compressedIndex) {
return intervals[intvl + 1]; return intervals[intvl + 1];
else if (i > compressedIndex) } else if (i > compressedIndex) {
return intervals[intvl + 1] - (i - compressedIndex); return intervals[intvl + 1] - (i - compressedIndex);
}
} }
return originalIndex; return originalIndex;
} }
@ -281,10 +294,11 @@ public abstract class RFTFont implements BinaryFont {
@Override @Override
public int getStringWidth(final String text) { public int getStringWidth(final String text) {
final int w = charW * text.length(); final int w = charW * text.length();
if (text.length() > 0 && w > 0) if (text.length() > 0 && w > 0) {
return w; return w;
else } else {
return 0; return 0;
}
} }
@Override @Override

View File

@ -38,8 +38,9 @@ public class NoGuiEngine implements GraphicEngine {
@Override @Override
public void create(final Runnable onInitialized) { public void create(final Runnable onInitialized) {
initialized = true; initialized = true;
if (onInitialized != null) if (onInitialized != null) {
onInitialized.run(); onInitialized.run();
}
} }
@Override @Override

View File

@ -42,9 +42,11 @@ public class KeyboardDebugScreen extends Screen {
} }
Engine.INSTANCE.getHardwareDevice().getDisplayManager().fonts[3].use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine); Engine.INSTANCE.getHardwareDevice().getDisplayManager().fonts[3].use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine);
renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f); renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++) {
if (KeyboardDebugScreen.log[i] != null) if (KeyboardDebugScreen.log[i] != null) {
renderer.glDrawStringLeft(10, 230 + 15 * (i + 1), KeyboardDebugScreen.log[i].toUpperCase()); renderer.glDrawStringLeft(10, 230 + 15 * (i + 1), KeyboardDebugScreen.log[i].toUpperCase());
}
}
//FROM SERIAL //FROM SERIAL
renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f); renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
@ -56,36 +58,39 @@ public class KeyboardDebugScreen extends Screen {
Engine.INSTANCE.getHardwareDevice().getDisplayManager().fonts[3].use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine); Engine.INSTANCE.getHardwareDevice().getDisplayManager().fonts[3].use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine);
renderer.glColor4f(0.0f, 0.0f, 1.0f, 1.0f); renderer.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
if (KeyboardDebugScreen.pinsA[i] == 1) if (KeyboardDebugScreen.pinsA[i] == 1) {
renderer.glColor4f(0.0f, 1.0f, 0.0f, 1.0f); renderer.glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
else if (KeyboardDebugScreen.pinsA[i] == 2) } else if (KeyboardDebugScreen.pinsA[i] == 2) {
renderer.glColor4f(0.5f, 0.5f, 1.0f, 1.0f); renderer.glColor4f(0.5f, 0.5f, 1.0f, 1.0f);
else if (KeyboardDebugScreen.pinsA[i] == -1) } else if (KeyboardDebugScreen.pinsA[i] == -1) {
renderer.glColor4f(0.7f, 0.7f, 0.7f, 1.0f); renderer.glColor4f(0.7f, 0.7f, 0.7f, 1.0f);
else if (KeyboardDebugScreen.pinsA[i] == 0) } else if (KeyboardDebugScreen.pinsA[i] == 0) {
renderer.glColor4f(1.0f, 0.0f, 0.0f, 1.0f); renderer.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
}
renderer.glFillColor(-80 + 103 + 25 * (7 - i), 80, 20, 20); renderer.glFillColor(-80 + 103 + 25 * (7 - i), 80, 20, 20);
renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f); renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
renderer.glDrawStringCenter(-80 + 113 + 25 * (7 - i), 90 - renderer.getCurrentFont().getCharacterHeight() / 2, "" + (i + 1)); renderer.glDrawStringCenter(-80 + 113 + 25 * (7 - i), 90 - renderer.getCurrentFont().getCharacterHeight() / 2, "" + (i + 1));
} }
for (int i = 15; i >= 8; i--) { for (int i = 15; i >= 8; i--) {
if (KeyboardDebugScreen.pinsA[i] == 1) if (KeyboardDebugScreen.pinsA[i] == 1) {
renderer.glColor4f(0.0f, 1.0f, 0.0f, 1.0f); renderer.glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
else if (KeyboardDebugScreen.pinsA[i] == 2) } else if (KeyboardDebugScreen.pinsA[i] == 2) {
renderer.glColor4f(0.5f, 0.5f, 1.0f, 1.0f); renderer.glColor4f(0.5f, 0.5f, 1.0f, 1.0f);
else if (KeyboardDebugScreen.pinsA[i] == -1) } else if (KeyboardDebugScreen.pinsA[i] == -1) {
renderer.glColor4f(0.7f, 0.7f, 0.7f, 1.0f); renderer.glColor4f(0.7f, 0.7f, 0.7f, 1.0f);
else if (KeyboardDebugScreen.pinsA[i] == 0) } else if (KeyboardDebugScreen.pinsA[i] == 0) {
renderer.glColor4f(1.0f, 0.0f, 0.0f, 1.0f); renderer.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
}
renderer.glFillColor(-80 + 103 + 25 * (i - 8), 170, 20, 20); renderer.glFillColor(-80 + 103 + 25 * (i - 8), 170, 20, 20);
renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f); renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
renderer.glDrawStringCenter(-80 + 113 + 25 * (i - 8), 180 - renderer.getCurrentFont().getCharacterHeight() / 2, "" + (i + 1)); renderer.glDrawStringCenter(-80 + 113 + 25 * (i - 8), 180 - renderer.getCurrentFont().getCharacterHeight() / 2, "" + (i + 1));
} }
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
if (KeyboardDebugScreen.dataA[i]) if (KeyboardDebugScreen.dataA[i]) {
renderer.glColor4f(0.0f, 1.0f, 0.0f, 1.0f); renderer.glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
else } else {
renderer.glColor4f(1.0f, 0.0f, 0.0f, 1.0f); renderer.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
}
renderer.glFillColor(-80 + 160 + 10 * i, 150, 8, 8); renderer.glFillColor(-80 + 160 + 10 * i, 150, 8, 8);
} }
@ -99,45 +104,49 @@ public class KeyboardDebugScreen extends Screen {
Engine.INSTANCE.getHardwareDevice().getDisplayManager().fonts[3].use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine); Engine.INSTANCE.getHardwareDevice().getDisplayManager().fonts[3].use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine);
renderer.glColor4f(0.0f, 0.0f, 1.0f, 1.0f); renderer.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
for (int i = 15; i >= 8; i--) { for (int i = 15; i >= 8; i--) {
if (KeyboardDebugScreen.pinsB[i] == 1) if (KeyboardDebugScreen.pinsB[i] == 1) {
renderer.glColor4f(0.0f, 1.0f, 0.0f, 1.0f); renderer.glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
else if (KeyboardDebugScreen.pinsB[i] == 2) } else if (KeyboardDebugScreen.pinsB[i] == 2) {
renderer.glColor4f(0.5f, 0.5f, 1.0f, 1.0f); renderer.glColor4f(0.5f, 0.5f, 1.0f, 1.0f);
else if (KeyboardDebugScreen.pinsB[i] == -1) } else if (KeyboardDebugScreen.pinsB[i] == -1) {
renderer.glColor4f(0.7f, 0.7f, 0.7f, 1.0f); renderer.glColor4f(0.7f, 0.7f, 0.7f, 1.0f);
else if (KeyboardDebugScreen.pinsB[i] == 0) } else if (KeyboardDebugScreen.pinsB[i] == 0) {
renderer.glColor4f(1.0f, 0.0f, 0.0f, 1.0f); renderer.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
}
renderer.glFillColor(150 + 103 + 25 * (15 - i), 80, 20, 20); renderer.glFillColor(150 + 103 + 25 * (15 - i), 80, 20, 20);
renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f); renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
renderer.glDrawStringCenter(150 + 113 + 25 * (15 - i), 90 - renderer.getCurrentFont().getCharacterHeight() / 2, "" + (i + 1)); renderer.glDrawStringCenter(150 + 113 + 25 * (15 - i), 90 - renderer.getCurrentFont().getCharacterHeight() / 2, "" + (i + 1));
} }
for (int i = 7; i >= 0; i--) { for (int i = 7; i >= 0; i--) {
if (KeyboardDebugScreen.pinsB[i] == 1) if (KeyboardDebugScreen.pinsB[i] == 1) {
renderer.glColor4f(0.0f, 1.0f, 0.0f, 1.0f); renderer.glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
else if (KeyboardDebugScreen.pinsB[i] == 2) } else if (KeyboardDebugScreen.pinsB[i] == 2) {
renderer.glColor4f(0.5f, 0.5f, 1.0f, 1.0f); renderer.glColor4f(0.5f, 0.5f, 1.0f, 1.0f);
else if (KeyboardDebugScreen.pinsB[i] == -1) } else if (KeyboardDebugScreen.pinsB[i] == -1) {
renderer.glColor4f(0.7f, 0.7f, 0.7f, 1.0f); renderer.glColor4f(0.7f, 0.7f, 0.7f, 1.0f);
else if (KeyboardDebugScreen.pinsB[i] == 0) } else if (KeyboardDebugScreen.pinsB[i] == 0) {
renderer.glColor4f(1.0f, 0.0f, 0.0f, 1.0f); renderer.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
}
renderer.glFillColor(150 + 103 + 25 * i, 170, 20, 20); renderer.glFillColor(150 + 103 + 25 * i, 170, 20, 20);
renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f); renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
renderer.glDrawStringCenter(150 + 113 + 25 * i, 180 - renderer.getCurrentFont().getCharacterHeight() / 2, "" + (i + 1)); renderer.glDrawStringCenter(150 + 113 + 25 * i, 180 - renderer.getCurrentFont().getCharacterHeight() / 2, "" + (i + 1));
} }
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
if (KeyboardDebugScreen.dataB[i]) if (KeyboardDebugScreen.dataB[i]) {
renderer.glColor4f(0.0f, 1.0f, 0.0f, 1.0f); renderer.glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
else } else {
renderer.glColor4f(1.0f, 0.0f, 0.0f, 1.0f); renderer.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
}
renderer.glFillColor(150 + 160 + 10 * i, 150, 8, 8); renderer.glFillColor(150 + 160 + 10 * i, 150, 8, 8);
} }
//GPIO //GPIO
for (int i = 0; i < 40; i++) { for (int i = 0; i < 40; i++) {
if (KeyboardDebugScreen.gpio[i] == true) if (KeyboardDebugScreen.gpio[i] == true) {
renderer.glColor4f(0.0f, 1.0f, 0.0f, 1.0f); renderer.glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
else } else {
renderer.glColor4f(1.0f, 0.0f, 0.0f, 1.0f); renderer.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
}
if (i % 2 == 0) { if (i % 2 == 0) {
renderer.glFillColor(53 + 15 * (i / 2), 50, 5, 5); renderer.glFillColor(53 + 15 * (i / 2), 50, 5, 5);
renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f); renderer.glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
@ -150,14 +159,16 @@ public class KeyboardDebugScreen extends Screen {
} }
//KEYS //KEYS
for (int c = 0; c < 8; c++) for (int c = 0; c < 8; c++) {
for (int r = 0; r < 8; r++) { for (int r = 0; r < 8; r++) {
if (KeyboardDebugScreen.ks[c][r]) if (KeyboardDebugScreen.ks[c][r]) {
renderer.glColor4f(0.0f, 1.0f, 0.0f, 1.0f); renderer.glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
else } else {
renderer.glColor4f(1.0f, 0.0f, 0.0f, 1.0f); renderer.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
}
renderer.glFillColor(250 + 6 * c, 250 + 6 * r, 5, 5); renderer.glFillColor(250 + 6 * c, 250 + 6 * r, 5, 5);
} }
}
} }
@Override @Override
@ -204,8 +215,9 @@ public class KeyboardDebugScreen extends Screen {
public static void log(final String str) { public static void log(final String str) {
final String[] newlog = KeyboardDebugScreen.log; final String[] newlog = KeyboardDebugScreen.log;
for (int i = 1; i < 5; i++) for (int i = 1; i < 5; i++) {
newlog[i - 1] = newlog[i]; newlog[i - 1] = newlog[i];
}
newlog[4] = "[" + System.currentTimeMillis() + "]" + str; newlog[4] = "[" + System.currentTimeMillis() + "]" + str;
KeyboardDebugScreen.log = newlog; KeyboardDebugScreen.log = newlog;
} }

View File

@ -60,8 +60,9 @@ public class LoadingScreen extends Screen {
if (mustRefresh) { if (mustRefresh) {
mustRefresh = false; mustRefresh = false;
return true; return true;
} else } else {
return false; return false;
}
} }
} }

View File

@ -44,15 +44,18 @@ public class MarioScreen extends Screen {
@Override @Override
public void initialized() { public void initialized() {
try { try {
if (MarioScreen.skin == null) if (MarioScreen.skin == null) {
MarioScreen.skin = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadSkin("marioskin.png"); MarioScreen.skin = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadSkin("marioskin.png");
if (MarioScreen.groundskin == null) }
if (MarioScreen.groundskin == null) {
MarioScreen.groundskin = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadSkin("marioground.png"); MarioScreen.groundskin = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadSkin("marioground.png");
if (MarioScreen.gpuTest2 == null) }
if (MarioScreen.gpuTest2 == null) {
try { try {
MarioScreen.gpuTest2 = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadFont("gputest2"); MarioScreen.gpuTest2 = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadFont("gputest2");
} catch (final Exception ex) {} } catch (final Exception ex) {}
if (MarioScreen.gpuTest1 == null) }
if (MarioScreen.gpuTest1 == null) {
try { try {
MarioScreen.gpuTest1 = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadFont("gputest12"); MarioScreen.gpuTest1 = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadFont("gputest12");
MarioScreen.gpuTest12 = true; MarioScreen.gpuTest12 = true;
@ -62,12 +65,14 @@ public class MarioScreen extends Screen {
MarioScreen.gpuTest1 = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadFont("gputest1"); MarioScreen.gpuTest1 = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadFont("gputest1");
} catch (final Exception ex2) {} } catch (final Exception ex2) {}
} }
if (MarioScreen.gpuTest3 == null) }
if (MarioScreen.gpuTest3 == null) {
try { try {
MarioScreen.gpuTest3 = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadSkin("font_gputest3.png"); MarioScreen.gpuTest3 = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadSkin("font_gputest3.png");
} catch (final Exception ex) { } catch (final Exception ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
}
} catch (final IOException e) { } catch (final IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -75,8 +80,9 @@ public class MarioScreen extends Screen {
@Override @Override
public void created() throws InterruptedException { public void created() throws InterruptedException {
if (!errored) if (!errored) {
g = new MarioGame(); g = new MarioGame();
}
} }
@Override @Override
@ -105,9 +111,9 @@ public class MarioScreen extends Screen {
@Override @Override
public void render() { public void render() {
if (errored) if (errored) {
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringLeft(0, 20, "ERROR"); Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringLeft(0, 20, "ERROR");
else { } else {
if (MarioScreen.groundskin != null) { if (MarioScreen.groundskin != null) {
final double playerX = g.getPlayer().getX(); final double playerX = g.getPlayer().getX();
final double playerY = g.getPlayer().getY(); final double playerY = g.getPlayer().getY();
@ -120,7 +126,7 @@ public class MarioScreen extends Screen {
final float shiftX = -8 + 16 * (float) playerX; final float shiftX = -8 + 16 * (float) playerX;
final float shiftY = -8 + 16 * (height - (float) playerY); final float shiftY = -8 + 16 * (height - (float) playerY);
int blue = -1; int blue = -1;
for (int ix = 0; ix < width; ix++) for (int ix = 0; ix < width; ix++) {
for (int iy = 0; iy < height; iy++) { for (int iy = 0; iy < height; iy++) {
final double distX = Math.abs(playerX - ix); final double distX = Math.abs(playerX - ix);
final double distY = Math.abs(playerY - iy - 1.5d); final double distY = Math.abs(playerY - iy - 1.5d);
@ -141,6 +147,7 @@ public class MarioScreen extends Screen {
} }
} }
} }
}
if (blue != 0) { if (blue != 0) {
blue = 0; blue = 0;
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor(0xffffffff); Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor(0xffffffff);

View File

@ -84,12 +84,14 @@ public class MathInputScreen extends Screen {
@Override @Override
public void beforeRender(final float dt) { public void beforeRender(final float dt) {
if (Engine.INSTANCE.getHardwareDevice().getDisplayManager().error == null) if (Engine.INSTANCE.getHardwareDevice().getDisplayManager().error == null) {
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glClearColor(0xFFc5c2af); Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glClearColor(0xFFc5c2af);
else } else {
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glClearColor(0xFFDC3C32); Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glClearColor(0xFFDC3C32);
if (userInput.beforeRender(dt)) }
if (userInput.beforeRender(dt)) {
mustRefresh = true; mustRefresh = true;
}
if (computingResult) { if (computingResult) {
computingElapsedTime += dt; computingElapsedTime += dt;
computingAnimationElapsedTime += dt; computingAnimationElapsedTime += dt;
@ -98,8 +100,9 @@ public class MathInputScreen extends Screen {
computingAnimationIndex = (computingAnimationIndex + 1) % 16; computingAnimationIndex = (computingAnimationIndex + 1) % 16;
mustRefresh = true; mustRefresh = true;
} }
if (computingElapsedTime > 5) if (computingElapsedTime > 5) {
computingBreakTipVisible = true; computingBreakTipVisible = true;
}
} else { } else {
computingElapsedTime = 0; computingElapsedTime = 0;
computingAnimationElapsedTime = 0; computingAnimationElapsedTime = 0;
@ -131,8 +134,9 @@ public class MathInputScreen extends Screen {
renderer.glColor3f(0.75f, 0, 0); renderer.glColor3f(0.75f, 0, 0);
renderer.glDrawStringRight(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getWidth() - 4 - size - 4, Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getHeight() - size / 2 - renderer.getCurrentFont().getCharacterHeight() / 2 - 4, "Press (=) to stop"); renderer.glDrawStringRight(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getWidth() - 4 - size - 4, Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getHeight() - size / 2 - renderer.getCurrentFont().getCharacterHeight() / 2 - 4, "Press (=) to stop");
} }
} else if (!result.isContentEmpty()) } else if (!result.isContentEmpty()) {
result.draw(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine, renderer, Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getWidth() - result.getWidth() - 2, Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getHeight() - result.getHeight() - 2); result.draw(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine, renderer, Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getWidth() - result.getWidth() - 2, Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getHeight() - result.getHeight() - 2);
}
} }
@Override @Override
@ -142,10 +146,11 @@ public class MathInputScreen extends Screen {
final int pos = 2; final int pos = 2;
final int spacersNumb = 1; final int spacersNumb = 1;
int skinN = 0; int skinN = 0;
if (calc.exactMode) if (calc.exactMode) {
skinN = 22; skinN = 22;
else } else {
skinN = 21; skinN = 21;
}
Engine.INSTANCE.getHardwareDevice().getDisplayManager().guiSkin.use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine); Engine.INSTANCE.getHardwareDevice().getDisplayManager().guiSkin.use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine);
renderer.glFillRect(2 + 18 * pos + 2 * spacersNumb, 2, 16, 16, 16 * skinN, 16 * 0, 16, 16); renderer.glFillRect(2 + 18 * pos + 2 * spacersNumb, 2, 16, 16, 16 * skinN, 16 * 0, 16, 16);
} }
@ -155,8 +160,9 @@ public class MathInputScreen extends Screen {
if (mustRefresh) { if (mustRefresh) {
mustRefresh = false; mustRefresh = false;
return true; return true;
} else } else {
return false; return false;
}
} }
@Override @Override
@ -192,8 +198,9 @@ public class MathInputScreen extends Screen {
case STEP: case STEP:
currentStep++; currentStep++;
case SIMPLIFY: case SIMPLIFY:
if (!step) if (!step) {
currentStep = 0; currentStep = 0;
}
if (Engine.INSTANCE.getHardwareDevice().getDisplayManager().error != null) { if (Engine.INSTANCE.getHardwareDevice().getDisplayManager().error != null) {
//TODO: make the error management a global API rather than being relegated to this screen. //TODO: make the error management a global API rather than being relegated to this screen.
Engine.getPlatform().getConsoleUtils().out().println(1, "Resetting after error..."); Engine.getPlatform().getConsoleUtils().out().println(1, "Resetting after error...");
@ -222,8 +229,9 @@ public class MathInputScreen extends Screen {
final ObjectArrayList<ObjectArrayList<Function>> resultSteps = ms.solveAllSteps(); final ObjectArrayList<ObjectArrayList<Function>> resultSteps = ms.solveAllSteps();
resultSteps.add(0, Utils.newArrayList(expr)); resultSteps.add(0, Utils.newArrayList(expr));
final ObjectArrayList<Function> resultExpressions = resultSteps.get(resultSteps.size() - 1); final ObjectArrayList<Function> resultExpressions = resultSteps.get(resultSteps.size() - 1);
for (final Function rr : resultExpressions) for (final Function rr : resultExpressions) {
Engine.getPlatform().getConsoleUtils().out().println(0, "RESULT: " + rr.toString()); Engine.getPlatform().getConsoleUtils().out().println(0, "RESULT: " + rr.toString());
}
final ObjectArrayList<ObjectArrayList<Block>> resultBlocks = MathParser.parseOutput(calc, resultExpressions); final ObjectArrayList<ObjectArrayList<Block>> resultBlocks = MathParser.parseOutput(calc, resultExpressions);
result.setContentAsMultipleGroups(resultBlocks); result.setContentAsMultipleGroups(resultBlocks);
// showVariablesDialog(() -> { // showVariablesDialog(() -> {
@ -234,8 +242,9 @@ public class MathInputScreen extends Screen {
} catch (final InterruptedException ex) { } catch (final InterruptedException ex) {
Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN, "Computing thread stopped."); Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN, "Computing thread stopped.");
} catch (final Exception ex) { } catch (final Exception ex) {
if (Engine.getPlatform().getSettings().isDebugEnabled()) if (Engine.getPlatform().getSettings().isDebugEnabled()) {
ex.printStackTrace(); ex.printStackTrace();
}
throw new Error(Errors.SYNTAX_ERROR); throw new Error(Errors.SYNTAX_ERROR);
} }
} catch (final Error e) { } catch (final Error e) {
@ -435,12 +444,13 @@ public class MathInputScreen extends Screen {
} }
return false; return false;
case DRG_CYCLE: case DRG_CYCLE:
if (calc.angleMode.equals(AngleMode.DEG) == true) if (calc.angleMode.equals(AngleMode.DEG) == true) {
calc.angleMode = AngleMode.RAD; calc.angleMode = AngleMode.RAD;
else if (calc.angleMode.equals(AngleMode.RAD) == true) } else if (calc.angleMode.equals(AngleMode.RAD) == true) {
calc.angleMode = AngleMode.GRA; calc.angleMode = AngleMode.GRA;
else } else {
calc.angleMode = AngleMode.DEG; calc.angleMode = AngleMode.DEG;
}
currentStep = 0; currentStep = 0;
return true; return true;
default: default:
@ -505,7 +515,7 @@ public class MathInputScreen extends Screen {
partialResults.clear(); partialResults.clear();
} }
} }
if (results.size() == 0) { if (results.size() == 0) {
calc.resultsCount = 0; calc.resultsCount = 0;
} else { } else {
@ -547,7 +557,7 @@ public class MathInputScreen extends Screen {
return; return;
} }
} }
final ObjectArrayList<Function> results = solveExpression(calc.f); final ObjectArrayList<Function> results = solveExpression(calc.f);
if (results.size() == 0) { if (results.size() == 0) {
calc.resultsCount = 0; calc.resultsCount = 0;
@ -600,15 +610,16 @@ public class MathInputScreen extends Screen {
@Override @Override
public boolean onKeyReleased(final KeyReleasedEvent k) { public boolean onKeyReleased(final KeyReleasedEvent k) {
if (k.getKey() == Key.OK) if (k.getKey() == Key.OK) {
return true; return true;
else if (userInput.isExtraOpened() && userInput.getExtraKeyboardEventListener().onKeyReleased(k)) } else if (userInput.isExtraOpened() && userInput.getExtraKeyboardEventListener().onKeyReleased(k)) {
return true; return true;
else } else {
switch (k.getKey()) { switch (k.getKey()) {
default: default:
return false; return false;
} }
}
} }
public void showVariablesDialog() { public void showVariablesDialog() {
@ -618,9 +629,11 @@ public class MathInputScreen extends Screen {
public void showVariablesDialog(final Runnable runnable) { public void showVariablesDialog(final Runnable runnable) {
final Thread ct = new Thread(() -> { final Thread ct = new Thread(() -> {
final ObjectArrayList<Function> knownVarsInFunctions = getKnownVariables(calc.f.toArray(new Function[calc.f.size()])); final ObjectArrayList<Function> knownVarsInFunctions = getKnownVariables(calc.f.toArray(new Function[calc.f.size()]));
for (final VariableValue f : calc.variablesValues) for (final VariableValue f : calc.variablesValues) {
if (knownVarsInFunctions.contains(f.v)) if (knownVarsInFunctions.contains(f.v)) {
knownVarsInFunctions.remove(f.v); knownVarsInFunctions.remove(f.v);
}
}
boolean cancelled = false; boolean cancelled = false;
for (final Function f : knownVarsInFunctions) { for (final Function f : knownVarsInFunctions) {
@ -634,15 +647,19 @@ public class MathInputScreen extends Screen {
break; break;
} else { } else {
final int is = calc.variablesValues.size(); final int is = calc.variablesValues.size();
for (int i = 0; i < is; i++) for (int i = 0; i < is; i++) {
if (calc.variablesValues.get(i).v == f) if (calc.variablesValues.get(i).v == f) {
calc.variablesValues.remove(i); calc.variablesValues.remove(i);
}
}
calc.variablesValues.add(new VariableValue((Variable) f, (Number) cvs.resultNumberValue)); calc.variablesValues.add(new VariableValue((Variable) f, (Number) cvs.resultNumberValue));
} }
} }
if (!cancelled) if (!cancelled) {
if (runnable != null) if (runnable != null) {
runnable.run(); runnable.run();
}
}
}); });
Engine.getPlatform().setThreadName(ct, "Variables user-input queue thread"); Engine.getPlatform().setThreadName(ct, "Variables user-input queue thread");
ct.setPriority(Thread.MIN_PRIORITY); ct.setPriority(Thread.MIN_PRIORITY);
@ -652,17 +669,21 @@ public class MathInputScreen extends Screen {
private ObjectArrayList<Function> getKnownVariables(final Function[] fncs) { private ObjectArrayList<Function> getKnownVariables(final Function[] fncs) {
final ObjectArrayList<Function> res = new ObjectArrayList<>(); final ObjectArrayList<Function> res = new ObjectArrayList<>();
for (final Function f : fncs) for (final Function f : fncs) {
if (f instanceof FunctionOperator) if (f instanceof FunctionOperator) {
res.addAll(getKnownVariables(new Function[] { ((FunctionOperator) f).getParameter1(), ((FunctionOperator) f).getParameter2() })); res.addAll(getKnownVariables(new Function[] { ((FunctionOperator) f).getParameter1(), ((FunctionOperator) f).getParameter2() }));
else if (f instanceof FunctionDynamic) } else if (f instanceof FunctionDynamic) {
res.addAll(getKnownVariables(((FunctionDynamic) f).getParameters())); res.addAll(getKnownVariables(((FunctionDynamic) f).getParameters()));
else if (f instanceof FunctionSingle) } else if (f instanceof FunctionSingle) {
res.addAll(getKnownVariables(new Function[] { ((FunctionSingle) f).getParameter() })); res.addAll(getKnownVariables(new Function[] { ((FunctionSingle) f).getParameter() }));
else if (f instanceof Variable) } else if (f instanceof Variable) {
if (((Variable) f).getType() == Variable.V_TYPE.CONSTANT) if (((Variable) f).getType() == Variable.V_TYPE.CONSTANT) {
if (!res.contains(f)) if (!res.contains(f)) {
res.add(f); res.add(f);
}
}
}
}
return res; return res;
} }

View File

@ -15,10 +15,11 @@ public abstract class FunctionDynamic implements Function {
} }
public FunctionDynamic(final Function[] values) { public FunctionDynamic(final Function[] values) {
if (values.length > 0) if (values.length > 0) {
root = values[0].getMathContext(); root = values[0].getMathContext();
else } else {
throw new NullPointerException("Nessun elemento nell'array. Impossibile ricavare il nodo root"); throw new NullPointerException("Nessun elemento nell'array. Impossibile ricavare il nodo root");
}
functions = values; functions = values;
} }
@ -38,8 +39,9 @@ public abstract class FunctionDynamic implements Function {
final FunctionDynamic f = clone(); final FunctionDynamic f = clone();
final int vsize = value.size(); final int vsize = value.size();
final Function[] tmp = new Function[vsize]; final Function[] tmp = new Function[vsize];
for (int i = 0; i < vsize; i++) for (int i = 0; i < vsize; i++) {
tmp[i] = value.get(i); tmp[i] = value.get(i);
}
f.functions = tmp; f.functions = tmp;
return f; return f;
} }
@ -87,33 +89,37 @@ public abstract class FunctionDynamic implements Function {
@Override @Override
public final ObjectArrayList<Function> simplify(final Rule rule) throws Error, InterruptedException { public final ObjectArrayList<Function> simplify(final Rule rule) throws Error, InterruptedException {
final Function[] fncs = getParameters(); final Function[] fncs = getParameters();
if (Thread.interrupted()) if (Thread.interrupted()) {
throw new InterruptedException(); throw new InterruptedException();
}
final ObjectArrayList<Function> result = new ObjectArrayList<>(); final ObjectArrayList<Function> result = new ObjectArrayList<>();
final ObjectArrayList<ObjectArrayList<Function>> ln = new ObjectArrayList<>(); final ObjectArrayList<ObjectArrayList<Function>> ln = new ObjectArrayList<>();
boolean alreadySolved = true; boolean alreadySolved = true;
for (final Function fnc : fncs) { for (final Function fnc : fncs) {
final ObjectArrayList<Function> l = new ObjectArrayList<>(); final ObjectArrayList<Function> l = new ObjectArrayList<>();
if (Thread.interrupted()) if (Thread.interrupted()) {
throw new InterruptedException(); throw new InterruptedException();
}
final ObjectArrayList<Function> simplifiedFnc = fnc.simplify(rule); final ObjectArrayList<Function> simplifiedFnc = fnc.simplify(rule);
if (simplifiedFnc == null) if (simplifiedFnc == null) {
l.add(fnc); l.add(fnc);
else { } else {
l.addAll(simplifiedFnc); l.addAll(simplifiedFnc);
alreadySolved = false; alreadySolved = false;
} }
ln.add(l); ln.add(l);
} }
if (alreadySolved) if (alreadySolved) {
return rule.execute(this); return rule.execute(this);
}
final Function[][] results = Utils.joinFunctionsResults(ln); final Function[][] results = Utils.joinFunctionsResults(ln);
for (final Function[] f : results) for (final Function[] f : results) {
result.add(this.setParameters(f)); result.add(this.setParameters(f));
}
return result; return result;
} }

View File

@ -115,49 +115,57 @@ public abstract class FunctionOperator implements Function {
@Override @Override
public final ObjectArrayList<Function> simplify(final Rule rule) throws Error, InterruptedException { public final ObjectArrayList<Function> simplify(final Rule rule) throws Error, InterruptedException {
if (Thread.interrupted()) if (Thread.interrupted()) {
throw new InterruptedException(); throw new InterruptedException();
}
final ObjectArrayList<Function> simplifiedParam1 = parameter1.simplify(rule); final ObjectArrayList<Function> simplifiedParam1 = parameter1.simplify(rule);
final ObjectArrayList<Function> simplifiedParam2 = parameter2.simplify(rule); final ObjectArrayList<Function> simplifiedParam2 = parameter2.simplify(rule);
try { try {
if (simplifiedParam1 == null & simplifiedParam2 == null) if (simplifiedParam1 == null & simplifiedParam2 == null) {
return rule.execute(this); return rule.execute(this);
}
} catch (final Exception e) { } catch (final Exception e) {
final Error err = new Error(Errors.ERROR, "Error while executing rule '" + rule.getRuleName() + "'!\n" + e.getMessage()); final Error err = new Error(Errors.ERROR, "Error while executing rule '" + rule.getRuleName() + "'!\n" + e.getMessage());
err.initCause(e); err.initCause(e);
throw err; throw err;
} }
if (Thread.interrupted()) if (Thread.interrupted()) {
throw new InterruptedException(); throw new InterruptedException();
}
final ObjectArrayList<Function> result = new ObjectArrayList<>(); final ObjectArrayList<Function> result = new ObjectArrayList<>();
final ObjectArrayList<Function> l1 = new ObjectArrayList<>(); final ObjectArrayList<Function> l1 = new ObjectArrayList<>();
final ObjectArrayList<Function> l2 = new ObjectArrayList<>(); final ObjectArrayList<Function> l2 = new ObjectArrayList<>();
if (Thread.interrupted()) if (Thread.interrupted()) {
throw new InterruptedException(); throw new InterruptedException();
if (simplifiedParam1 == null) }
if (simplifiedParam1 == null) {
l1.add(parameter1); l1.add(parameter1);
else { } else {
if (Thread.interrupted()) if (Thread.interrupted()) {
throw new InterruptedException(); throw new InterruptedException();
}
l1.addAll(simplifiedParam1); l1.addAll(simplifiedParam1);
} }
if (Thread.interrupted()) if (Thread.interrupted()) {
throw new InterruptedException(); throw new InterruptedException();
if (simplifiedParam2 == null) }
if (simplifiedParam2 == null) {
l2.add(parameter2); l2.add(parameter2);
else { } else {
if (Thread.interrupted()) if (Thread.interrupted()) {
throw new InterruptedException(); throw new InterruptedException();
}
l2.addAll(simplifiedParam2); l2.addAll(simplifiedParam2);
} }
final Function[][] results = Utils.joinFunctionsResults(l1, l2); final Function[][] results = Utils.joinFunctionsResults(l1, l2);
for (final Function[] f : results) for (final Function[] f : results) {
result.add(setParameter1(f[0]).setParameter2(f[1])); result.add(setParameter1(f[0]).setParameter2(f[1]));
}
return result; return result;
} }

View File

@ -74,18 +74,20 @@ public abstract class FunctionSingle implements Function {
@Override @Override
public FunctionSingle setParameter(final int index, final Function var) throws IndexOutOfBoundsException { public FunctionSingle setParameter(final int index, final Function var) throws IndexOutOfBoundsException {
if (index == 0) if (index == 0) {
return this.setParameter(var); return this.setParameter(var);
else } else {
throw new IndexOutOfBoundsException(); throw new IndexOutOfBoundsException();
}
} }
@Override @Override
public Function getParameter(final int index) throws IndexOutOfBoundsException { public Function getParameter(final int index) throws IndexOutOfBoundsException {
if (index == 0) if (index == 0) {
return this.getParameter(); return this.getParameter();
else } else {
throw new IndexOutOfBoundsException(); throw new IndexOutOfBoundsException();
}
} }
@Override @Override
@ -96,12 +98,14 @@ public abstract class FunctionSingle implements Function {
@Override @Override
public final ObjectArrayList<Function> simplify(final Rule rule) throws Error, InterruptedException { public final ObjectArrayList<Function> simplify(final Rule rule) throws Error, InterruptedException {
final ObjectArrayList<Function> simplifiedParam = parameter.simplify(rule); final ObjectArrayList<Function> simplifiedParam = parameter.simplify(rule);
if (simplifiedParam == null) if (simplifiedParam == null) {
return rule.execute(this); return rule.execute(this);
}
final ObjectArrayList<Function> result = new ObjectArrayList<>(); final ObjectArrayList<Function> result = new ObjectArrayList<>();
for (final Function f : simplifiedParam) for (final Function f : simplifiedParam) {
result.add(this.setParameter(f)); result.add(this.setParameter(f));
}
return result; return result;
} }

View File

@ -43,8 +43,9 @@ public class MathematicalSymbols {
public static final char[] functionsAndSignums = Utils.concat(MathematicalSymbols.functions, MathematicalSymbols.signumsWithMultiplication); public static final char[] functionsAndSignums = Utils.concat(MathematicalSymbols.functions, MathematicalSymbols.signumsWithMultiplication);
public static final char[] signums(final boolean withMultiplication) { public static final char[] signums(final boolean withMultiplication) {
if (withMultiplication) if (withMultiplication) {
return MathematicalSymbols.signumsWithMultiplication; return MathematicalSymbols.signumsWithMultiplication;
}
return MathematicalSymbols.signumsWithoutMultiplication; return MathematicalSymbols.signumsWithoutMultiplication;
} }

View File

@ -42,10 +42,12 @@ public class Division extends FunctionOperator {
final BlockDivision bd = new BlockDivision(); final BlockDivision bd = new BlockDivision();
final BlockContainer uc = bd.getUpperContainer(); final BlockContainer uc = bd.getUpperContainer();
final BlockContainer lc = bd.getLowerContainer(); final BlockContainer lc = bd.getLowerContainer();
for (final Block b : sub1) for (final Block b : sub1) {
uc.appendBlockUnsafe(b); uc.appendBlockUnsafe(b);
for (final Block b : sub2) }
for (final Block b : sub2) {
lc.appendBlockUnsafe(b); lc.appendBlockUnsafe(b);
}
uc.recomputeDimensions(); uc.recomputeDimensions();
lc.recomputeDimensions(); lc.recomputeDimensions();
bd.recomputeDimensions(); bd.recomputeDimensions();

View File

@ -40,7 +40,7 @@ public class Expression extends FunctionSingle {
super(root); super(root);
this.initialParenthesis = initialParenthesis; this.initialParenthesis = initialParenthesis;
boolean isNumber = false; boolean isNumber = false;
// Determine if the expression is already a number: // Determine if the expression is already a number:
// Determina se l'espressione è già un numero: // Determina se l'espressione è già un numero:
try { try {
@ -49,12 +49,12 @@ public class Expression extends FunctionSingle {
} catch (final NumberFormatException ex) { } catch (final NumberFormatException ex) {
isNumber = false; isNumber = false;
} }
String processExpression = string; String processExpression = string;
Utils.debug.println(debugSpaces + "•Analyzing expression:" + processExpression); Utils.debug.println(debugSpaces + "•Analyzing expression:" + processExpression);
isNumber = false; //TODO: rimuovere isNumber, alcune semplificazione come la divisione per zero altrimenti verrebbero saltate. isNumber = false; //TODO: rimuovere isNumber, alcune semplificazione come la divisione per zero altrimenti verrebbero saltate.
if (isNumber) { if (isNumber) {
// If the expression is already a number: // If the expression is already a number:
// Se l'espressione è già un numero: // Se l'espressione è già un numero:
@ -65,10 +65,10 @@ public class Expression extends FunctionSingle {
// Else prepare the expression: // Else prepare the expression:
// Altrimenti prepara l'espressione: // Altrimenti prepara l'espressione:
debugSpaces += " "; debugSpaces += " ";
// IF the expression is not a number: // IF the expression is not a number:
// Se l'espressione non è già un numero: // Se l'espressione non è già un numero:
// Check if there are more than one equal symbol (=) // Check if there are more than one equal symbol (=)
// Controlla se ci sono più di un uguale (=) // Controlla se ci sono più di un uguale (=)
int equationsFound = 0; int equationsFound = 0;
@ -88,7 +88,7 @@ public class Expression extends FunctionSingle {
if (equationsFound != systemsFound) { if (equationsFound != systemsFound) {
throw new Error(Errors.SYNTAX_ERROR); throw new Error(Errors.SYNTAX_ERROR);
} }
//Solve the exceeding symbols ++ and -- //Solve the exceeding symbols ++ and --
// Correggi i segni ++ e -- in eccesso // Correggi i segni ++ e -- in eccesso
Pattern pattern = Pattern.compile("\\+\\++?|\\-\\-+?"); Pattern pattern = Pattern.compile("\\+\\++?|\\-\\-+?");
@ -100,7 +100,7 @@ public class Expression extends FunctionSingle {
processExpression = processExpression.substring(0, matcher.start(0)) + correzione + processExpression.substring(matcher.start(0) + matcher.group(0).length(), processExpression.length()); processExpression = processExpression.substring(0, matcher.start(0)) + correzione + processExpression.substring(matcher.start(0) + matcher.group(0).length(), processExpression.length());
matcher = pattern.matcher(processExpression); matcher = pattern.matcher(processExpression);
} }
// Correct the exceeding symbols +- and -+ // Correct the exceeding symbols +- and -+
// Correggi i segni +- e -+ in eccesso // Correggi i segni +- e -+ in eccesso
pattern = Pattern.compile("\\+\\-|\\-\\+"); pattern = Pattern.compile("\\+\\-|\\-\\+");
@ -111,25 +111,25 @@ public class Expression extends FunctionSingle {
processExpression = processExpression.substring(0, matcher.start(0)) + correzione + processExpression.substring(matcher.start(0) + matcher.group(0).length(), processExpression.length()); processExpression = processExpression.substring(0, matcher.start(0)) + correzione + processExpression.substring(matcher.start(0) + matcher.group(0).length(), processExpression.length());
matcher = pattern.matcher(processExpression); matcher = pattern.matcher(processExpression);
} }
// Rimuovi i segni appena dopo le parentesi // Rimuovi i segni appena dopo le parentesi
if (processExpression.contains("(+")) { if (processExpression.contains("(+")) {
symbolsChanged = true; symbolsChanged = true;
processExpression = processExpression.replace("(+", "("); processExpression = processExpression.replace("(+", "(");
} }
// // Cambia i segni appena prima le parentesi // // Cambia i segni appena prima le parentesi
// if (processExpression.contains("-(")) { // if (processExpression.contains("-(")) {
// symbolsChanged = true; // symbolsChanged = true;
// processExpression = processExpression.replace("-(", "-1*("); // processExpression = processExpression.replace("-(", "-1*(");
// } // }
// Rimuovi i segni appena dopo l'inizio // Rimuovi i segni appena dopo l'inizio
if (processExpression.startsWith("+")) { if (processExpression.startsWith("+")) {
symbolsChanged = true; symbolsChanged = true;
processExpression = processExpression.substring(1, processExpression.length()); processExpression = processExpression.substring(1, processExpression.length());
} }
// Rimuovi i + in eccesso // Rimuovi i + in eccesso
pattern = Pattern.compile("[" + ArrayToRegex(Utils.add(concat(MathematicalSymbols.signums(true), MathematicalSymbols.functions), '(')) + "]\\+[^" + ArrayToRegex(concat(concat(MathematicalSymbols.signums(true), MathematicalSymbols.functions), new char[] { '(', ')' })) + "]+?[" + ArrayToRegex(concat(MathematicalSymbols.signums(true), MathematicalSymbols.functions)) + "]|[" + ArrayToRegex(concat(MathematicalSymbols.signums(true), MathematicalSymbols.functions)) + "]+?\\+[^" + ArrayToRegex(concat(concat(MathematicalSymbols.signums(true), MathematicalSymbols.functions), new char[] { '(', ')' })) + "]"); pattern = Pattern.compile("[" + ArrayToRegex(Utils.add(concat(MathematicalSymbols.signums(true), MathematicalSymbols.functions), '(')) + "]\\+[^" + ArrayToRegex(concat(concat(MathematicalSymbols.signums(true), MathematicalSymbols.functions), new char[] { '(', ')' })) + "]+?[" + ArrayToRegex(concat(MathematicalSymbols.signums(true), MathematicalSymbols.functions)) + "]|[" + ArrayToRegex(concat(MathematicalSymbols.signums(true), MathematicalSymbols.functions)) + "]+?\\+[^" + ArrayToRegex(concat(concat(MathematicalSymbols.signums(true), MathematicalSymbols.functions), new char[] { '(', ')' })) + "]");
matcher = pattern.matcher(processExpression); matcher = pattern.matcher(processExpression);
@ -140,10 +140,10 @@ public class Expression extends FunctionSingle {
processExpression = processExpression.substring(0, matcher.start(0) + 1) + correzione + processExpression.substring(matcher.start(0) + matcher.group(0).length(), processExpression.length()); processExpression = processExpression.substring(0, matcher.start(0) + 1) + correzione + processExpression.substring(matcher.start(0) + matcher.group(0).length(), processExpression.length());
matcher = pattern.matcher(processExpression); matcher = pattern.matcher(processExpression);
} }
// Correggi i segni - in // Correggi i segni - in
processExpression = processExpression.replace('-', MathematicalSymbols.SUBTRACTION); processExpression = processExpression.replace('-', MathematicalSymbols.SUBTRACTION);
// Correggi i segni dopo di espressioni o funzioni SN in - // Correggi i segni dopo di espressioni o funzioni SN in -
pattern = Pattern.compile("[" + Utils.ArrayToRegex(concat(concat(MathematicalSymbols.functions, new char[] { MathematicalSymbols.PARENTHESIS_OPEN }), MathematicalSymbols.signums(true))) + "]" + MathematicalSymbols.SUBTRACTION); pattern = Pattern.compile("[" + Utils.ArrayToRegex(concat(concat(MathematicalSymbols.functions, new char[] { MathematicalSymbols.PARENTHESIS_OPEN }), MathematicalSymbols.signums(true))) + "]" + MathematicalSymbols.SUBTRACTION);
matcher = pattern.matcher(processExpression); matcher = pattern.matcher(processExpression);
@ -153,17 +153,17 @@ public class Expression extends FunctionSingle {
processExpression = processExpression.substring(0, matcher.start(0) + 1) + correzione + processExpression.substring(matcher.start(0) + 2, processExpression.length()); processExpression = processExpression.substring(0, matcher.start(0) + 1) + correzione + processExpression.substring(matcher.start(0) + 2, processExpression.length());
matcher = pattern.matcher(processExpression); matcher = pattern.matcher(processExpression);
} }
// Cambia il segno iniziale in - // Cambia il segno iniziale in -
if (processExpression.startsWith("")) { if (processExpression.startsWith("")) {
symbolsChanged = true; symbolsChanged = true;
processExpression = "-" + processExpression.substring(1, processExpression.length()); processExpression = "-" + processExpression.substring(1, processExpression.length());
} }
if (symbolsChanged) { if (symbolsChanged) {
Utils.debug.println(debugSpaces + "•Resolved signs:" + processExpression); Utils.debug.println(debugSpaces + "•Resolved signs:" + processExpression);
} }
// // Aggiungi le parentesi implicite per le potenze con una incognita // // Aggiungi le parentesi implicite per le potenze con una incognita
// pattern = Pattern.compile("(?<!(?:\\(|^))(["+Utils.ArrayToRegex(MathematicalSymbols.variables())+"]+"+MathematicalSymbols.POWER+"[^" + Utils.ArrayToRegex(Utils.add(concat(MathematicalSymbols.functionsNSN(), concat(MathematicalSymbols.signums(true), MathematicalSymbols.genericSyntax())), ")")) + "])(?!\\))"); // pattern = Pattern.compile("(?<!(?:\\(|^))(["+Utils.ArrayToRegex(MathematicalSymbols.variables())+"]+"+MathematicalSymbols.POWER+"[^" + Utils.ArrayToRegex(Utils.add(concat(MathematicalSymbols.functionsNSN(), concat(MathematicalSymbols.signums(true), MathematicalSymbols.genericSyntax())), ")")) + "])(?!\\))");
// matcher = pattern.matcher(processExpression); // matcher = pattern.matcher(processExpression);
@ -176,7 +176,7 @@ public class Expression extends FunctionSingle {
// } // }
// //
// processExpression = processExpression.replace("", MathematicalSymbols.POWER); // processExpression = processExpression.replace("", MathematicalSymbols.POWER);
// Aggiungi i segni * accanto alle parentesi // Aggiungi i segni * accanto alle parentesi
pattern = Pattern.compile("\\([^\\(]+?\\)"); pattern = Pattern.compile("\\([^\\(]+?\\)");
matcher = pattern.matcher(processExpression); matcher = pattern.matcher(processExpression);
@ -197,17 +197,17 @@ public class Expression extends FunctionSingle {
processExpression = beforeexp + "" + newexp + "" + afterexp; processExpression = beforeexp + "" + newexp + "" + afterexp;
matcher = pattern.matcher(processExpression); matcher = pattern.matcher(processExpression);
} }
processExpression = processExpression.replace("", "(").replace("", ")"); processExpression = processExpression.replace("", "(").replace("", ")");
if (symbolsChanged) { if (symbolsChanged) {
Utils.debug.println(debugSpaces + "•Added implicit multiplications:" + processExpression); Utils.debug.println(debugSpaces + "•Added implicit multiplications:" + processExpression);
} }
Utils.debug.println(debugSpaces + "•Subdivision in classes:"); Utils.debug.println(debugSpaces + "•Subdivision in classes:");
debugSpaces += " "; debugSpaces += " ";
// Convert the expression to a list of objects // Convert the expression to a list of objects
Expression imputRawParenthesis = new Expression(root); Expression imputRawParenthesis = new Expression(root);
imputRawParenthesis = (Expression) imputRawParenthesis.setParameter(null); imputRawParenthesis = (Expression) imputRawParenthesis.setParameter(null);
@ -217,7 +217,7 @@ public class Expression extends FunctionSingle {
// Per ogni carattere cerca se è un numero o una funzione: // Per ogni carattere cerca se è un numero o una funzione:
final char charI = processExpression.charAt(i); final char charI = processExpression.charAt(i);
if (Utils.isInArray(charI, functions)) { if (Utils.isInArray(charI, functions)) {
// Finds the type of function fron the following list // Finds the type of function fron the following list
// Cerca il tipo di funzione tra le esistenti // Cerca il tipo di funzione tra le esistenti
Function f = null; Function f = null;
@ -292,7 +292,7 @@ public class Expression extends FunctionSingle {
} }
startIndex += 1; startIndex += 1;
i = startIndex; i = startIndex;
String tmpExpr = ""; String tmpExpr = "";
while (i < endIndex) { while (i < endIndex) {
tmpExpr += processExpression.charAt(i); tmpExpr += processExpression.charAt(i);
@ -378,7 +378,7 @@ public class Expression extends FunctionSingle {
} }
tmp = ""; tmp = "";
} }
int dsl = debugSpaces.length(); int dsl = debugSpaces.length();
debugSpaces = ""; debugSpaces = "";
for (int i = 0; i < dsl - 2; i++) { for (int i = 0; i < dsl - 2; i++) {
@ -386,7 +386,7 @@ public class Expression extends FunctionSingle {
} }
Utils.debug.println(debugSpaces + "•Finished the subdivision in classes."); Utils.debug.println(debugSpaces + "•Finished the subdivision in classes.");
// Fine suddivisione di insieme // Fine suddivisione di insieme
Utils.debug.println(debugSpaces + "•Removing useless parentheses"); Utils.debug.println(debugSpaces + "•Removing useless parentheses");
for (int i = 0; i < imputRawParenthesis.getParametersLength(); i++) { for (int i = 0; i < imputRawParenthesis.getParametersLength(); i++) {
if (imputRawParenthesis.getParameter(i) instanceof Expression) { if (imputRawParenthesis.getParameter(i) instanceof Expression) {
@ -400,10 +400,10 @@ public class Expression extends FunctionSingle {
} }
} }
} }
// Inizia l'affinazione dell'espressione // Inizia l'affinazione dell'espressione
Utils.debug.println(debugSpaces + "•Pushing classes..."); Utils.debug.println(debugSpaces + "•Pushing classes...");
final Function[] oldFunctionsArray = imputRawParenthesis.getParameters(); final Function[] oldFunctionsArray = imputRawParenthesis.getParameters();
final ObjectArrayList<Function> oldFunctionsList = new ObjectArrayList<>(); final ObjectArrayList<Function> oldFunctionsList = new ObjectArrayList<>();
for (int i = 0; i < oldFunctionsArray.length; i++) { for (int i = 0; i < oldFunctionsArray.length; i++) {
@ -423,10 +423,10 @@ public class Expression extends FunctionSingle {
oldFunctionsList.add(funzione); oldFunctionsList.add(funzione);
} }
} }
if (oldFunctionsList.size() > 1) { if (oldFunctionsList.size() > 1) {
Utils.debug.println(debugSpaces + " •Correcting classes:"); Utils.debug.println(debugSpaces + " •Correcting classes:");
int before = 0; int before = 0;
String step = "SN Functions"; String step = "SN Functions";
int n = 0; int n = 0;
@ -457,18 +457,18 @@ public class Expression extends FunctionSingle {
if (step != "SN Functions") { if (step != "SN Functions") {
if ((step == "sums" && (funzioneTMP instanceof Sum || funzioneTMP instanceof SumSubtraction || funzioneTMP instanceof Subtraction) == true && ((funzioneTMP instanceof FunctionSingle && ((FunctionSingle) funzioneTMP).getParameter() == null) || (funzioneTMP instanceof FunctionOperator && ((FunctionOperator) funzioneTMP).getParameter1() == null && ((FunctionOperator) funzioneTMP).getParameter2() == null) || (!(funzioneTMP instanceof FunctionSingle) && !(funzioneTMP instanceof FunctionOperator)))) || (step.equals("multiplications") && ((funzioneTMP instanceof Multiplication) || (funzioneTMP instanceof Division)) && ((FunctionOperator) funzioneTMP).getParameter1() == null && ((FunctionOperator) funzioneTMP).getParameter2() == null) || (step == "NSN Functions" && (funzioneTMP instanceof Sum) == false && (funzioneTMP instanceof SumSubtraction) == false && (funzioneTMP instanceof Subtraction) == false && (funzioneTMP instanceof Multiplication) == false && (funzioneTMP instanceof Division) == false && ((funzioneTMP instanceof FunctionSingle && ((FunctionSingle) funzioneTMP).getParameter() == null) || (funzioneTMP instanceof FunctionOperator && ((FunctionOperator) funzioneTMP).getParameter1() == null && ((FunctionOperator) funzioneTMP).getParameter2() == null) || (!(funzioneTMP instanceof FunctionSingle) && !(funzioneTMP instanceof FunctionOperator))))) { if ((step == "sums" && (funzioneTMP instanceof Sum || funzioneTMP instanceof SumSubtraction || funzioneTMP instanceof Subtraction) == true && ((funzioneTMP instanceof FunctionSingle && ((FunctionSingle) funzioneTMP).getParameter() == null) || (funzioneTMP instanceof FunctionOperator && ((FunctionOperator) funzioneTMP).getParameter1() == null && ((FunctionOperator) funzioneTMP).getParameter2() == null) || (!(funzioneTMP instanceof FunctionSingle) && !(funzioneTMP instanceof FunctionOperator)))) || (step.equals("multiplications") && ((funzioneTMP instanceof Multiplication) || (funzioneTMP instanceof Division)) && ((FunctionOperator) funzioneTMP).getParameter1() == null && ((FunctionOperator) funzioneTMP).getParameter2() == null) || (step == "NSN Functions" && (funzioneTMP instanceof Sum) == false && (funzioneTMP instanceof SumSubtraction) == false && (funzioneTMP instanceof Subtraction) == false && (funzioneTMP instanceof Multiplication) == false && (funzioneTMP instanceof Division) == false && ((funzioneTMP instanceof FunctionSingle && ((FunctionSingle) funzioneTMP).getParameter() == null) || (funzioneTMP instanceof FunctionOperator && ((FunctionOperator) funzioneTMP).getParameter1() == null && ((FunctionOperator) funzioneTMP).getParameter2() == null) || (!(funzioneTMP instanceof FunctionSingle) && !(funzioneTMP instanceof FunctionOperator))))) {
change = true; change = true;
if (i + 1 < oldFunctionsList.size() && i - 1 >= 0) { if (i + 1 < oldFunctionsList.size() && i - 1 >= 0) {
funzioneTMP = ((FunctionOperator) funzioneTMP).setParameter1(oldFunctionsList.get(i - 1)); funzioneTMP = ((FunctionOperator) funzioneTMP).setParameter1(oldFunctionsList.get(i - 1));
funzioneTMP = ((FunctionOperator) funzioneTMP).setParameter2(oldFunctionsList.get(i + 1)); funzioneTMP = ((FunctionOperator) funzioneTMP).setParameter2(oldFunctionsList.get(i + 1));
oldFunctionsList.set(i, funzioneTMP); oldFunctionsList.set(i, funzioneTMP);
// è importante togliere prima gli elementi // è importante togliere prima gli elementi
// in fondo e poi quelli davanti, perché gli // in fondo e poi quelli davanti, perché gli
// indici scalano da destra a sinistra. // indici scalano da destra a sinistra.
oldFunctionsList.remove(i + 1); oldFunctionsList.remove(i + 1);
oldFunctionsList.remove(i - 1); oldFunctionsList.remove(i - 1);
Utils.debug.println(debugSpaces + " •Set variable to expression:" + funzioneTMP.getClass().getSimpleName()); Utils.debug.println(debugSpaces + " •Set variable to expression:" + funzioneTMP.getClass().getSimpleName());
try { try {
Utils.debug.println(debugSpaces + " " + "var1=" + ((FunctionOperator) funzioneTMP).getParameter1().toString()); Utils.debug.println(debugSpaces + " " + "var1=" + ((FunctionOperator) funzioneTMP).getParameter1().toString());
@ -479,7 +479,7 @@ public class Expression extends FunctionSingle {
try { try {
Utils.debug.println(debugSpaces + " " + "(result)=" + ((FunctionOperator) funzioneTMP).toString()); Utils.debug.println(debugSpaces + " " + "(result)=" + ((FunctionOperator) funzioneTMP).toString());
} catch (final NullPointerException ex2) {} } catch (final NullPointerException ex2) {}
} else { } else {
throw new Error(Errors.SYNTAX_ERROR); throw new Error(Errors.SYNTAX_ERROR);
} }
@ -490,17 +490,17 @@ public class Expression extends FunctionSingle {
if (i + 1 < oldFunctionsList.size()) { if (i + 1 < oldFunctionsList.size()) {
final Function nextFunc = oldFunctionsList.get(i + 1); final Function nextFunc = oldFunctionsList.get(i + 1);
if (nextFunc instanceof FunctionSingle && ((FunctionSingle) nextFunc).getParameter() == null) { if (nextFunc instanceof FunctionSingle && ((FunctionSingle) nextFunc).getParameter() == null) {
} else { } else {
change = true; change = true;
funzioneTMP = ((FunctionSingle) funzioneTMP).setParameter(nextFunc); funzioneTMP = ((FunctionSingle) funzioneTMP).setParameter(nextFunc);
oldFunctionsList.set(i, funzioneTMP); oldFunctionsList.set(i, funzioneTMP);
// è importante togliere prima gli elementi in // è importante togliere prima gli elementi in
// fondo e poi quelli davanti, perché gli indici // fondo e poi quelli davanti, perché gli indici
// scalano da destra a sinistra. // scalano da destra a sinistra.
oldFunctionsList.remove(i + 1); oldFunctionsList.remove(i + 1);
Utils.debug.println(debugSpaces + " •Set variable to expression:" + funzioneTMP.getClass().getSimpleName()); Utils.debug.println(debugSpaces + " •Set variable to expression:" + funzioneTMP.getClass().getSimpleName());
final Function var = ((FunctionSingle) funzioneTMP).getParameter(); final Function var = ((FunctionSingle) funzioneTMP).getParameter();
if (var == null) { if (var == null) {
@ -531,14 +531,14 @@ public class Expression extends FunctionSingle {
} else { } else {
super.functions = oldFunctionsList.toArray(new Function[oldFunctionsList.size()]); super.functions = oldFunctionsList.toArray(new Function[oldFunctionsList.size()]);
} }
dsl = debugSpaces.length(); dsl = debugSpaces.length();
debugSpaces = ""; debugSpaces = "";
for (int i = 0; i < dsl - 2; i++) { for (int i = 0; i < dsl - 2; i++) {
debugSpaces += " "; debugSpaces += " ";
} }
Utils.debug.println(debugSpaces + "•Finished correcting classes."); Utils.debug.println(debugSpaces + "•Finished correcting classes.");
final String result = toString(); final String result = toString();
Utils.debug.println(debugSpaces + "•Result:" + result); Utils.debug.println(debugSpaces + "•Result:" + result);
} }
@ -547,19 +547,22 @@ public class Expression extends FunctionSingle {
public boolean parenthesisNeeded() { public boolean parenthesisNeeded() {
boolean parenthesisneeded = true; boolean parenthesisneeded = true;
if (initialParenthesis) if (initialParenthesis) {
parenthesisneeded = false; parenthesisneeded = false;
else { } else {
final Function f = getParameter(0); final Function f = getParameter(0);
if (f instanceof Number || f instanceof Variable || f instanceof Expression || f instanceof Division || f instanceof Joke || f instanceof Undefined || f instanceof Power || f instanceof Sine || f instanceof Cosine || f instanceof Tangent || f instanceof ArcSine || f instanceof ArcCosine || f instanceof ArcTangent || f instanceof RootSquare) if (f instanceof Number || f instanceof Variable || f instanceof Expression || f instanceof Division || f instanceof Joke || f instanceof Undefined || f instanceof Power || f instanceof Sine || f instanceof Cosine || f instanceof Tangent || f instanceof ArcSine || f instanceof ArcCosine || f instanceof ArcTangent || f instanceof RootSquare) {
parenthesisneeded = false; parenthesisneeded = false;
if (f instanceof Multiplication) }
if (((Multiplication) f).getParameter1() instanceof Number) if (f instanceof Multiplication) {
if (((Multiplication) f).getParameter1() instanceof Number) {
parenthesisneeded = !(((Multiplication) f).getParameter2() instanceof Variable); parenthesisneeded = !(((Multiplication) f).getParameter2() instanceof Variable);
else if (((Multiplication) f).getParameter2() instanceof Number) } else if (((Multiplication) f).getParameter2() instanceof Number) {
parenthesisneeded = !(((Multiplication) f).getParameter1() instanceof Variable); parenthesisneeded = !(((Multiplication) f).getParameter1() instanceof Variable);
else if (((Multiplication) f).getParameter1() instanceof Variable || ((Multiplication) f).getParameter2() instanceof Variable) } else if (((Multiplication) f).getParameter1() instanceof Variable || ((Multiplication) f).getParameter2() instanceof Variable) {
parenthesisneeded = false; parenthesisneeded = false;
}
}
} }
return parenthesisneeded; return parenthesisneeded;
} }
@ -570,8 +573,9 @@ public class Expression extends FunctionSingle {
final ObjectArrayList<Block> sub = getParameter(0).toBlock(context); final ObjectArrayList<Block> sub = getParameter(0).toBlock(context);
final BlockParenthesis bp = new BlockParenthesis(); final BlockParenthesis bp = new BlockParenthesis();
final BlockContainer bpc = bp.getNumberContainer(); final BlockContainer bpc = bp.getNumberContainer();
for (final Block b : sub) for (final Block b : sub) {
bpc.appendBlockUnsafe(b); bpc.appendBlockUnsafe(b);
}
bpc.recomputeDimensions(); bpc.recomputeDimensions();
bp.recomputeDimensions(); bp.recomputeDimensions();
result.add(bp); result.add(bp);
@ -581,24 +585,26 @@ public class Expression extends FunctionSingle {
@Override @Override
public String toString() { public String toString() {
String s = "("; String s = "(";
if (parameter == null) if (parameter == null) {
s += "null"; s += "null";
else } else {
s += parameter.toString(); s += parameter.toString();
}
s += ")"; s += ")";
return s; return s;
} }
@Override @Override
public boolean equals(final Object o) { public boolean equals(final Object o) {
if (parameter == null | o == null) if (parameter == null | o == null) {
return parameter == o; return parameter == o;
else { } else {
final Function f = (Function) o; final Function f = (Function) o;
if (f instanceof Expression) if (f instanceof Expression) {
return getParameter(0).equals(((Expression) f).getParameter(0)); return getParameter(0).equals(((Expression) f).getParameter(0));
else } else {
return getParameter(0).equals(f); return getParameter(0).equals(f);
}
} }
} }

View File

@ -37,10 +37,12 @@ public class Logarithm extends FunctionOperator {
final BlockLogarithm bd = new BlockLogarithm(); final BlockLogarithm bd = new BlockLogarithm();
final BlockContainer uc = bd.getBaseContainer(); final BlockContainer uc = bd.getBaseContainer();
final BlockContainer lc = bd.getNumberContainer(); final BlockContainer lc = bd.getNumberContainer();
for (final Block b : sub1) for (final Block b : sub1) {
uc.appendBlockUnsafe(b); uc.appendBlockUnsafe(b);
for (final Block b : sub2) }
for (final Block b : sub2) {
lc.appendBlockUnsafe(b); lc.appendBlockUnsafe(b);
}
uc.recomputeDimensions(); uc.recomputeDimensions();
lc.recomputeDimensions(); lc.recomputeDimensions();
bd.recomputeDimensions(); bd.recomputeDimensions();

View File

@ -24,10 +24,11 @@ public class Multiplication extends FunctionOperator {
public boolean equals(final Object o) { public boolean equals(final Object o) {
if (o instanceof Multiplication) { if (o instanceof Multiplication) {
final FunctionOperator f = (FunctionOperator) o; final FunctionOperator f = (FunctionOperator) o;
if (parameter1.equals(f.getParameter1()) && parameter2.equals(f.getParameter2())) if (parameter1.equals(f.getParameter1()) && parameter2.equals(f.getParameter2())) {
return true; return true;
else if (parameter1.equals(f.getParameter2()) && parameter2.equals(f.getParameter1())) } else if (parameter1.equals(f.getParameter2()) && parameter2.equals(f.getParameter1())) {
return true; return true;
}
} }
return false; return false;
} }
@ -53,26 +54,30 @@ public class Multiplication extends FunctionOperator {
final ObjectArrayList<Block> parBlocks = par2.toBlock(context); final ObjectArrayList<Block> parBlocks = par2.toBlock(context);
final BlockParenthesis par = new BlockParenthesis(parBlocks); final BlockParenthesis par = new BlockParenthesis(parBlocks);
result.add(par); result.add(par);
} else } else {
result.addAll(sub2); result.addAll(sub2);
}
return result; return result;
} else { } else {
if (new Expression(context, par1).parenthesisNeeded()) { if (new Expression(context, par1).parenthesisNeeded()) {
final ObjectArrayList<Block> parBlocks = par1.toBlock(context); final ObjectArrayList<Block> parBlocks = par1.toBlock(context);
final BlockParenthesis par = new BlockParenthesis(parBlocks); final BlockParenthesis par = new BlockParenthesis(parBlocks);
result.add(par); result.add(par);
} else } else {
result.addAll(sub1); result.addAll(sub1);
}
if (nearLeft instanceof BlockChar && nearRight instanceof BlockChar && !(par2 instanceof Negative) && !(par1 instanceof Number && par2 instanceof Number)) { if (nearLeft instanceof BlockChar && nearRight instanceof BlockChar && !(par2 instanceof Negative) && !(par1 instanceof Number && par2 instanceof Number)) {
} else } else {
result.add(new BlockChar(MathematicalSymbols.MULTIPLICATION)); result.add(new BlockChar(MathematicalSymbols.MULTIPLICATION));
}
if (new Expression(context, par2).parenthesisNeeded()) { if (new Expression(context, par2).parenthesisNeeded()) {
final ObjectArrayList<Block> parBlocks = par2.toBlock(context); final ObjectArrayList<Block> parBlocks = par2.toBlock(context);
final BlockParenthesis par = new BlockParenthesis(parBlocks); final BlockParenthesis par = new BlockParenthesis(parBlocks);
result.add(par); result.add(par);
} else } else {
result.addAll(sub2); result.addAll(sub2);
}
return result; return result;
} }
} }
@ -82,12 +87,13 @@ public class Multiplication extends FunctionOperator {
} }
public Function toPositive() { public Function toPositive() {
if (parameter1.equals(new Number(getMathContext(), -1))) if (parameter1.equals(new Number(getMathContext(), -1))) {
return parameter2; return parameter2;
else if (parameter2.equals(new Number(getMathContext(), -1))) } else if (parameter2.equals(new Number(getMathContext(), -1))) {
return parameter2; return parameter2;
else } else {
return null; return null;
}
} }
public static Multiplication newNegative(final MathContext context, final Function value2) { public static Multiplication newNegative(final MathContext context, final Function value2) {

View File

@ -18,8 +18,9 @@ public class Negative extends FunctionSingle {
@Override @Override
public boolean equals(final Object o) { public boolean equals(final Object o) {
if (o instanceof Negative) if (o instanceof Negative) {
return ((Negative) o).getParameter().equals(parameter); return ((Negative) o).getParameter().equals(parameter);
}
return false; return false;
} }
@ -35,12 +36,14 @@ public class Negative extends FunctionSingle {
if (new Expression(context, getParameter()).parenthesisNeeded()) { if (new Expression(context, getParameter()).parenthesisNeeded()) {
final BlockParenthesis par = new BlockParenthesis(); final BlockParenthesis par = new BlockParenthesis();
final ObjectArrayList<Block> parBlocks = getParameter().toBlock(context); final ObjectArrayList<Block> parBlocks = getParameter().toBlock(context);
for (final Block b : parBlocks) for (final Block b : parBlocks) {
par.getNumberContainer().appendBlockUnsafe(b); // Skips recomputeDimension par.getNumberContainer().appendBlockUnsafe(b); // Skips recomputeDimension
}
par.recomputeDimensions(); // Recompute dimensions after appendBlockUnsafe par.recomputeDimensions(); // Recompute dimensions after appendBlockUnsafe
blocks.add(par); blocks.add(par);
} else } else {
blocks.addAll(getParameter().toBlock(context)); blocks.addAll(getParameter().toBlock(context));
}
return blocks; return blocks;
// throw new Error(Errors.NOT_IMPLEMENTED, "Unknown function " + getClass().getSimpleName()); // throw new Error(Errors.NOT_IMPLEMENTED, "Unknown function " + getClass().getSimpleName());
} }

View File

@ -77,14 +77,17 @@ public class Number implements Function {
if (Utils.isIntegerValue(f.term)) { if (Utils.isIntegerValue(f.term)) {
final BigInteger bi = f.term.toBigInteger().abs(); final BigInteger bi = f.term.toBigInteger().abs();
for (BigInteger i = BigInteger.ZERO; i.compareTo(bi) < 0; i = i.add(BigInteger.ONE)) { for (BigInteger i = BigInteger.ZERO; i.compareTo(bi) < 0; i = i.add(BigInteger.ONE)) {
if (Thread.interrupted()) if (Thread.interrupted()) {
throw new InterruptedException(); throw new InterruptedException();
}
ret = ret.multiply(new Number(root, getTerm())); ret = ret.multiply(new Number(root, getTerm()));
} }
if (f.term.signum() == -1) if (f.term.signum() == -1) {
ret = new Number(root, 1).divide(ret); ret = new Number(root, 1).divide(ret);
} else }
} else {
ret.term = BigDecimalMath.pow(term, f.term); ret.term = BigDecimalMath.pow(term, f.term);
}
return ret; return ret;
} }
@ -96,13 +99,15 @@ public class Number implements Function {
String s = sWith0.indexOf(".") < 0 ? sWith0 : sWith0.replaceAll("0*$", "").replaceAll("\\.$", ""); String s = sWith0.indexOf(".") < 0 ? sWith0 : sWith0.replaceAll("0*$", "").replaceAll("\\.$", "");
final String sExtended = sExtendedWith0.indexOf(".") < 0 ? sExtendedWith0 : sExtendedWith0.replaceAll("0*$", "").replaceAll("\\.$", ""); final String sExtended = sExtendedWith0.indexOf(".") < 0 ? sExtendedWith0 : sExtendedWith0.replaceAll("0*$", "").replaceAll("\\.$", "");
if (sExtended.length() > s.length()) if (sExtended.length() > s.length()) {
s = s + ""; s = s + "";
}
if (root.exactMode == false) { if (root.exactMode == false) {
final String cuttedNumber = s.split("\\.")[0]; final String cuttedNumber = s.split("\\.")[0];
if (cuttedNumber.length() > 8) if (cuttedNumber.length() > 8) {
return cuttedNumber.substring(0, 1) + "," + cuttedNumber.substring(1, 8) + "" + (cuttedNumber.length() - 1); return cuttedNumber.substring(0, 1) + "," + cuttedNumber.substring(1, 8) + "" + (cuttedNumber.length() - 1);
}
} }
return s; return s;
} }
@ -132,18 +137,21 @@ public class Number implements Function {
@Override @Override
public boolean equals(final Object o) { public boolean equals(final Object o) {
if (o != null & term != null) if (o != null & term != null) {
if (o instanceof Number) { if (o instanceof Number) {
final BigDecimal nav = ((Number) o).getTerm(); final BigDecimal nav = ((Number) o).getTerm();
final boolean na1 = term.compareTo(BigDecimal.ZERO) == 0; final boolean na1 = term.compareTo(BigDecimal.ZERO) == 0;
final boolean na2 = nav.compareTo(BigDecimal.ZERO) == 0; final boolean na2 = nav.compareTo(BigDecimal.ZERO) == 0;
if (na1 == na2) { if (na1 == na2) {
if (na1 == true) if (na1 == true) {
return true; return true;
} else }
} else {
return false; return false;
}
return nav.compareTo(term) == 0; return nav.compareTo(term) == 0;
} }
}
return false; return false;
} }
@ -169,8 +177,9 @@ public class Number implements Function {
*/ */
public boolean canBeFactorized() { public boolean canBeFactorized() {
if (Utils.isIntegerValue(getTerm())) if (Utils.isIntegerValue(getTerm())) {
return getTerm().toBigIntegerExact().compareTo(BigInteger.valueOf(1)) > 1; return getTerm().toBigIntegerExact().compareTo(BigInteger.valueOf(1)) > 1;
}
return false; return false;
} }
@ -186,18 +195,21 @@ public class Number implements Function {
final int comparedToZero = n.compareTo(zero); final int comparedToZero = n.compareTo(zero);
final int comparedToTwo = n.compareTo(two); final int comparedToTwo = n.compareTo(two);
if (comparedToZero == 0) if (comparedToZero == 0) {
return fs; return fs;
if (comparedToTwo < 0) }
if (comparedToZero > 0) if (comparedToTwo < 0) {
if (comparedToZero > 0) {
return fs; return fs;
else { } else {
fs.add(BigInteger.valueOf(-1)); fs.add(BigInteger.valueOf(-1));
n = n.multiply(BigInteger.valueOf(-1)); n = n.multiply(BigInteger.valueOf(-1));
} }
}
if (n.compareTo(two) < 0) if (n.compareTo(two) < 0) {
throw new IllegalArgumentException("must be greater than one"); throw new IllegalArgumentException("must be greater than one");
}
while (n.mod(two).equals(BigInteger.ZERO)) { while (n.mod(two).equals(BigInteger.ZERO)) {
fs.add(two); fs.add(two);
@ -206,12 +218,14 @@ public class Number implements Function {
if (n.compareTo(BigInteger.ONE) > 0) { if (n.compareTo(BigInteger.ONE) > 0) {
BigInteger f = BigInteger.valueOf(3); BigInteger f = BigInteger.valueOf(3);
while (f.compareTo(Utils.maxFactor) <= 0 && f.multiply(f).compareTo(n) <= 0) while (f.compareTo(Utils.maxFactor) <= 0 && f.multiply(f).compareTo(n) <= 0) {
if (n.mod(f).equals(BigInteger.ZERO)) { if (n.mod(f).equals(BigInteger.ZERO)) {
fs.add(f); fs.add(f);
n = n.divide(f); n = n.divide(f);
} else } else {
f = f.add(two); f = f.add(two);
}
}
fs.add(n); fs.add(n);
} }
@ -226,17 +240,21 @@ public class Number implements Function {
final String[] numberParts = numberString.split("", 2); final String[] numberParts = numberString.split("", 2);
final BlockPower bp = new BlockExponentialNotation(); final BlockPower bp = new BlockExponentialNotation();
final BlockContainer bpec = bp.getExponentContainer(); final BlockContainer bpec = bp.getExponentContainer();
for (final char c : numberParts[0].toCharArray()) for (final char c : numberParts[0].toCharArray()) {
result.add(new BlockChar(c)); result.add(new BlockChar(c));
for (final char c : numberParts[1].toCharArray()) }
bpec.appendBlockUnsafe(new BlockChar(c));; for (final char c : numberParts[1].toCharArray()) {
bpec.appendBlockUnsafe(new BlockChar(c));
} ;
bpec.recomputeDimensions(); bpec.recomputeDimensions();
bp.recomputeDimensions(); bp.recomputeDimensions();
result.add(bp); result.add(bp);
return result; return result;
} else } else {
for (final char c : numberString.toCharArray()) for (final char c : numberString.toCharArray()) {
result.add(new BlockChar(c)); result.add(new BlockChar(c));
}
}
return result; return result;
} }

View File

@ -37,8 +37,9 @@ public class Power extends FunctionOperator {
final BlockPower bp = new BlockPower(); final BlockPower bp = new BlockPower();
final BlockContainer ec = bp.getExponentContainer(); final BlockContainer ec = bp.getExponentContainer();
result.addAll(sub1); result.addAll(sub1);
for (final Block b : sub2) for (final Block b : sub2) {
ec.appendBlockUnsafe(b); ec.appendBlockUnsafe(b);
}
ec.recomputeDimensions(); ec.recomputeDimensions();
bp.recomputeDimensions(); bp.recomputeDimensions();
result.add(bp); result.add(bp);

View File

@ -34,8 +34,9 @@ public class RootSquare extends FunctionOperator {
final ObjectArrayList<Block> result = new ObjectArrayList<>(); final ObjectArrayList<Block> result = new ObjectArrayList<>();
final BlockSquareRoot bsqr = new BlockSquareRoot(); final BlockSquareRoot bsqr = new BlockSquareRoot();
final BlockContainer bsqrc = bsqr.getNumberContainer(); final BlockContainer bsqrc = bsqr.getNumberContainer();
for (final Block b : getParameter2().toBlock(context)) for (final Block b : getParameter2().toBlock(context)) {
bsqrc.appendBlockUnsafe(b); bsqrc.appendBlockUnsafe(b);
}
bsqrc.recomputeDimensions(); bsqrc.recomputeDimensions();
bsqr.recomputeDimensions(); bsqr.recomputeDimensions();
result.add(bsqr); result.add(bsqr);

View File

@ -19,10 +19,11 @@ public class Sum extends FunctionOperator {
public boolean equals(final Object o) { public boolean equals(final Object o) {
if (o instanceof Sum) { if (o instanceof Sum) {
final FunctionOperator f = (FunctionOperator) o; final FunctionOperator f = (FunctionOperator) o;
if (parameter1.equals(f.getParameter1()) && parameter2.equals(f.getParameter2())) if (parameter1.equals(f.getParameter1()) && parameter2.equals(f.getParameter2())) {
return true; return true;
else if (parameter1.equals(f.getParameter2()) && parameter2.equals(f.getParameter1())) } else if (parameter1.equals(f.getParameter2()) && parameter2.equals(f.getParameter1())) {
return true; return true;
}
} }
return false; return false;
} }

View File

@ -67,8 +67,9 @@ public class Variable implements Function {
@Override @Override
public boolean equals(final Object o) { public boolean equals(final Object o) {
if (o instanceof Variable) if (o instanceof Variable) {
return ((Variable) o).getChar() == var && ((Variable) o).getType() == type; return ((Variable) o).getChar() == var && ((Variable) o).getType() == type;
}
return false; return false;
} }

View File

@ -33,8 +33,9 @@ public class Equation extends FunctionOperator {
for (final SolveMethod t : SolveMethod.techniques) { for (final SolveMethod t : SolveMethod.techniques) {
final ObjectArrayList<Equation> newResults = new ObjectArrayList<>(); final ObjectArrayList<Equation> newResults = new ObjectArrayList<>();
final int sz = result.size(); final int sz = result.size();
for (int n = 0; n < sz; n++) for (int n = 0; n < sz; n++) {
newResults.addAll(t.solve(result.get(n))); newResults.addAll(t.solve(result.get(n)));
}
final Set<Equation> hs = new HashSet<>(); final Set<Equation> hs = new HashSet<>();
hs.addAll(newResults); hs.addAll(newResults);
newResults.clear(); newResults.clear();

View File

@ -19,8 +19,9 @@ public class Sine extends FunctionSingle {
public boolean equals(final Object o) { public boolean equals(final Object o) {
if (o instanceof Sine) { if (o instanceof Sine) {
final FunctionSingle f = (FunctionSingle) o; final FunctionSingle f = (FunctionSingle) o;
if (parameter.equals(f.getParameter())) if (parameter.equals(f.getParameter())) {
return true; return true;
}
} }
return false; return false;
} }
@ -36,8 +37,9 @@ public class Sine extends FunctionSingle {
final ObjectArrayList<Block> sub = getParameter(0).toBlock(context); final ObjectArrayList<Block> sub = getParameter(0).toBlock(context);
final BlockSine bs = new BlockSine(); final BlockSine bs = new BlockSine();
final BlockContainer bpc = bs.getNumberContainer(); final BlockContainer bpc = bs.getNumberContainer();
for (final Block b : sub) for (final Block b : sub) {
bpc.appendBlockUnsafe(b); bpc.appendBlockUnsafe(b);
}
bpc.recomputeDimensions(); bpc.recomputeDimensions();
bs.recomputeDimensions(); bs.recomputeDimensions();
result.add(bs); result.add(bs);

View File

@ -46,8 +46,9 @@ public class MathParser {
final ObjectArrayList<ObjectArrayList<Block>> result = new ObjectArrayList<>(); final ObjectArrayList<ObjectArrayList<Block>> result = new ObjectArrayList<>();
for (final Function resultExpression : resultExpressions) { for (final Function resultExpression : resultExpressions) {
final ObjectArrayList<Block> resultBlocks = resultExpression.toBlock(context); final ObjectArrayList<Block> resultBlocks = resultExpression.toBlock(context);
if (resultBlocks == null) if (resultBlocks == null) {
throw new Error(Errors.NOT_IMPLEMENTED, "Unknown function " + resultExpression.getClass().getSimpleName()); throw new Error(Errors.NOT_IMPLEMENTED, "Unknown function " + resultExpression.getClass().getSimpleName());
}
result.add(resultBlocks); result.add(resultBlocks);
} }
return result; return result;
@ -61,15 +62,17 @@ public class MathParser {
for (final Feature f : features) { for (final Feature f : features) {
final Function fnc = f.toFunction(context); final Function fnc = f.toFunction(context);
if (fnc == null) if (fnc == null) {
throw new Error(Errors.SYNTAX_ERROR, "\"" + f.getClass().getSimpleName() + "\" can't be converted into a Function!"); throw new Error(Errors.SYNTAX_ERROR, "\"" + f.getClass().getSimpleName() + "\" can't be converted into a Function!");
}
process.add(fnc); process.add(fnc);
} }
process = MathParser.fixStack(context, process); process = MathParser.fixStack(context, process);
if (process.size() > 1) if (process.size() > 1) {
throw new Error(Errors.UNBALANCED_STACK, "The stack is unbalanced. Not all the functions are nested correctly"); throw new Error(Errors.UNBALANCED_STACK, "The stack is unbalanced. Not all the functions are nested correctly");
}
return process.get(0); return process.get(0);
} }
@ -82,14 +85,16 @@ public class MathParser {
if (Engine.getPlatform().getSettings().isDebugEnabled()) { if (Engine.getPlatform().getSettings().isDebugEnabled()) {
Engine.getPlatform().getConsoleUtils().out().print(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "\tStatus: "); Engine.getPlatform().getConsoleUtils().out().print(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "\tStatus: ");
for (final Function f : functionsList) for (final Function f : functionsList) {
Engine.getPlatform().getConsoleUtils().out().print(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, f.toString()); Engine.getPlatform().getConsoleUtils().out().print(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, f.toString());
}
Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE); Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE);
} }
for (final MathParserStep step : steps) { for (final MathParserStep step : steps) {
if (Engine.getPlatform().getSettings().isDebugEnabled()) if (Engine.getPlatform().getSettings().isDebugEnabled()) {
Engine.getPlatform().getConsoleUtils().out().println(2, "Stack fixing step \"" + step.getStepName() + "\""); Engine.getPlatform().getConsoleUtils().out().println(2, "Stack fixing step \"" + step.getStepName() + "\"");
}
final int stepQty = step.requiresReversedIteration() ? -1 : 1, final int stepQty = step.requiresReversedIteration() ? -1 : 1,
initialIndex = step.requiresReversedIteration() ? functionsList.size() - 1 : 0; initialIndex = step.requiresReversedIteration() ? functionsList.size() - 1 : 0;
do { do {
@ -100,8 +105,9 @@ public class MathParser {
final int i = curIndex.i; final int i = curIndex.i;
final Function f = functionsList.get(i); final Function f = functionsList.get(i);
if (step.eval(curIndex, lastElement, f, functionsList)) if (step.eval(curIndex, lastElement, f, functionsList)) {
lastLoopDidSomething = true; lastLoopDidSomething = true;
}
lastElement = i >= functionsList.size() ? null : functionsList.get(i); lastElement = i >= functionsList.size() ? null : functionsList.get(i);
curIndex.i += stepQty; curIndex.i += stepQty;
@ -110,8 +116,9 @@ public class MathParser {
if (Engine.getPlatform().getSettings().isDebugEnabled()) { if (Engine.getPlatform().getSettings().isDebugEnabled()) {
Engine.getPlatform().getConsoleUtils().out().print(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "\tStatus: "); Engine.getPlatform().getConsoleUtils().out().print(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "\tStatus: ");
for (final Function f : functionsList) for (final Function f : functionsList) {
Engine.getPlatform().getConsoleUtils().out().print(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, f.toString()); Engine.getPlatform().getConsoleUtils().out().print(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, f.toString());
}
Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE); Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE);
} }
} }
@ -157,7 +164,7 @@ public class MathParser {
final ObjectArrayList<Feature> features) throws Error { final ObjectArrayList<Feature> features) throws Error {
final ObjectArrayList<Feature> process = new ObjectArrayList<>(); final ObjectArrayList<Feature> process = new ObjectArrayList<>();
for (final Feature f : features) for (final Feature f : features) {
if (f instanceof FeatureChar) { if (f instanceof FeatureChar) {
final char featureChar = ((FeatureChar) f).ch; final char featureChar = ((FeatureChar) f).ch;
Feature result = null; Feature result = null;
@ -179,18 +186,22 @@ public class MathParser {
break; break;
} }
for (final char var : MathematicalSymbols.variables) for (final char var : MathematicalSymbols.variables) {
if (featureChar == var) { if (featureChar == var) {
result = new FeatureVariable(featureChar, V_TYPE.VARIABLE); result = new FeatureVariable(featureChar, V_TYPE.VARIABLE);
break; break;
} }
}
if (result == null) if (result == null) {
throw new Error(Errors.SYNTAX_ERROR, "Char " + featureChar + " isn't a known feature"); throw new Error(Errors.SYNTAX_ERROR, "Char " + featureChar + " isn't a known feature");
}
process.add(result); process.add(result);
} else } else {
process.add(f); process.add(f);
}
}
return process; return process;
} }
@ -207,31 +218,37 @@ public class MathParser {
final ObjectArrayList<Feature> process = new ObjectArrayList<>(); final ObjectArrayList<Feature> process = new ObjectArrayList<>();
FeatureNumber numberBuffer = null; FeatureNumber numberBuffer = null;
for (final Feature f : features) for (final Feature f : features) {
if (f instanceof FeatureChar) { if (f instanceof FeatureChar) {
final FeatureChar bcf = (FeatureChar) f; final FeatureChar bcf = (FeatureChar) f;
final char[] numbers = MathematicalSymbols.numbers; final char[] numbers = MathematicalSymbols.numbers;
boolean isNumber = false; boolean isNumber = false;
for (final char n : numbers) for (final char n : numbers) {
if (bcf.ch == n) { if (bcf.ch == n) {
isNumber = true; isNumber = true;
break; break;
} }
if (bcf.ch == MathematicalSymbols.MINUS || bcf.ch == '.') }
if (bcf.ch == MathematicalSymbols.MINUS || bcf.ch == '.') {
isNumber = true; isNumber = true;
}
if (isNumber) { if (isNumber) {
if (numberBuffer == null) { if (numberBuffer == null) {
numberBuffer = new FeatureNumber(bcf.ch); numberBuffer = new FeatureNumber(bcf.ch);
process.add(numberBuffer); process.add(numberBuffer);
} else } else {
numberBuffer.append(bcf.ch); numberBuffer.append(bcf.ch);
}
} else { } else {
if (numberBuffer != null) if (numberBuffer != null) {
numberBuffer = null; numberBuffer = null;
}
process.add(f); process.add(f);
} }
} else } else {
process.add(f); process.add(f);
}
}
return process; return process;
} }
@ -251,23 +268,26 @@ public class MathParser {
for (final Feature f : features) { for (final Feature f : features) {
if (f instanceof FeatureChar && (((FeatureChar) f).ch == MathematicalSymbols.SUBTRACTION || ((FeatureChar) f).ch == MathematicalSymbols.MINUS)) { if (f instanceof FeatureChar && (((FeatureChar) f).ch == MathematicalSymbols.SUBTRACTION || ((FeatureChar) f).ch == MathematicalSymbols.MINUS)) {
boolean isNegativeOfNumber = false; boolean isNegativeOfNumber = false;
if (lastFeature == null) if (lastFeature == null) {
isNegativeOfNumber = true; isNegativeOfNumber = true;
else if (lastFeature instanceof FeatureChar) { } else if (lastFeature instanceof FeatureChar) {
final FeatureChar lcf = (FeatureChar) lastFeature; final FeatureChar lcf = (FeatureChar) lastFeature;
final char[] operators = MathematicalSymbols.functionsAndSignums; final char[] operators = MathematicalSymbols.functionsAndSignums;
for (final char operator : operators) for (final char operator : operators) {
if (lcf.ch == operator) { if (lcf.ch == operator) {
isNegativeOfNumber = true; isNegativeOfNumber = true;
break; break;
} }
}
} }
if (isNegativeOfNumber) if (isNegativeOfNumber) {
process.add(new FeatureChar(MathematicalSymbols.MINUS)); process.add(new FeatureChar(MathematicalSymbols.MINUS));
else } else {
process.add(new FeatureChar(MathematicalSymbols.SUBTRACTION)); process.add(new FeatureChar(MathematicalSymbols.SUBTRACTION));
} else }
} else {
process.add(f); process.add(f);
}
lastFeature = f; lastFeature = f;
} }
return process; return process;
@ -288,12 +308,14 @@ public class MathParser {
Feature lastFeature = null; Feature lastFeature = null;
for (final Feature f : features) { for (final Feature f : features) {
if (f instanceof FeaturePowerChar) { if (f instanceof FeaturePowerChar) {
if (lastFeature != null) if (lastFeature != null) {
process.set(process.size() - 1, new FeaturePower(lastFeature.toFunction(context), ((FeaturePowerChar) f).getChild())); process.set(process.size() - 1, new FeaturePower(lastFeature.toFunction(context), ((FeaturePowerChar) f).getChild()));
else } else {
process.add(f); process.add(f);
} else }
} else {
process.add(f); process.add(f);
}
lastFeature = f; lastFeature = f;
} }

View File

@ -32,15 +32,17 @@ public class FeatureNumber implements FeatureBasic {
@Override @Override
public Number toFunction(final MathContext context) throws Error { public Number toFunction(final MathContext context) throws Error {
String nmbstr = getNumberString(); String nmbstr = getNumberString();
if (nmbstr.charAt(0) == '.') if (nmbstr.charAt(0) == '.') {
nmbstr = '0' + nmbstr; nmbstr = '0' + nmbstr;
else if (nmbstr.charAt(nmbstr.length() - 1) == '.') } else if (nmbstr.charAt(nmbstr.length() - 1) == '.') {
nmbstr += "0"; nmbstr += "0";
else if (nmbstr.length() == 1) } else if (nmbstr.length() == 1) {
if (nmbstr.charAt(0) == MathematicalSymbols.MINUS) if (nmbstr.charAt(0) == MathematicalSymbols.MINUS) {
nmbstr += "1"; nmbstr += "1";
else if (nmbstr.charAt(0) == MathematicalSymbols.SUBTRACTION) } else if (nmbstr.charAt(0) == MathematicalSymbols.SUBTRACTION) {
nmbstr += "1"; nmbstr += "1";
}
}
return new Number(context, nmbstr); return new Number(context, nmbstr);
} }
} }

View File

@ -24,12 +24,13 @@ public class AddImplicitMultiplications implements MathParserStep {
functionsList.remove(curIndex.i + 1); functionsList.remove(curIndex.i + 1);
return true; return true;
} }
} else if (currentFunction instanceof Function) } else if (currentFunction instanceof Function) {
if (lastFunction instanceof Function) { if (lastFunction instanceof Function) {
functionsList.set(curIndex.i, new Multiplication(context, currentFunction, lastFunction)); functionsList.set(curIndex.i, new Multiplication(context, currentFunction, lastFunction));
functionsList.remove(curIndex.i + 1); functionsList.remove(curIndex.i + 1);
return true; return true;
} }
}
return false; return false;
} }

View File

@ -14,8 +14,8 @@ public class FixMultiplicationsAndDivisions implements MathParserStep {
@Override @Override
public boolean eval(final IntWrapper curIndex, final Function lastFunction, final Function currentFunction, public boolean eval(final IntWrapper curIndex, final Function lastFunction, final Function currentFunction,
final ObjectArrayList<Function> functionsList) throws Error { final ObjectArrayList<Function> functionsList) throws Error {
if (currentFunction instanceof Multiplication || currentFunction instanceof Division) if (currentFunction instanceof Multiplication || currentFunction instanceof Division) {
if (currentFunction.getParameter(0) == null && currentFunction.getParameter(1) == null) if (currentFunction.getParameter(0) == null && currentFunction.getParameter(1) == null) {
if (curIndex.i - 1 >= 0 && curIndex.i + 1 < functionsList.size()) { if (curIndex.i - 1 >= 0 && curIndex.i + 1 < functionsList.size()) {
final Function next = functionsList.get(curIndex.i + 1); final Function next = functionsList.get(curIndex.i + 1);
final Function prev = functionsList.get(curIndex.i - 1); final Function prev = functionsList.get(curIndex.i - 1);
@ -24,8 +24,11 @@ public class FixMultiplicationsAndDivisions implements MathParserStep {
functionsList.remove(curIndex.i - 1); functionsList.remove(curIndex.i - 1);
curIndex.i--; curIndex.i--;
return true; return true;
} else if (currentFunction.getParameter(0) == null || currentFunction.getParameter(1) == null) } else if (currentFunction.getParameter(0) == null || currentFunction.getParameter(1) == null) {
throw new Error(Errors.MISSING_ARGUMENTS, "There is a function at the end without any argument specified."); throw new Error(Errors.MISSING_ARGUMENTS, "There is a function at the end without any argument specified.");
}
}
}
return false; return false;
} }

View File

@ -19,16 +19,17 @@ public class FixSingleFunctionArgs implements MathParserStep {
@Override @Override
public boolean eval(final IntWrapper curIndex, final Function lastFunction, final Function currentFunction, public boolean eval(final IntWrapper curIndex, final Function lastFunction, final Function currentFunction,
final ObjectArrayList<Function> functionsList) throws Error { final ObjectArrayList<Function> functionsList) throws Error {
if (currentFunction instanceof FunctionSingle) if (currentFunction instanceof FunctionSingle) {
if (((FunctionSingle) currentFunction).getParameter() == null) { if (((FunctionSingle) currentFunction).getParameter() == null) {
if (lastFunction == null) if (lastFunction == null) {
throw new Error(Errors.MISSING_ARGUMENTS, "There is a function at the end without any argument specified."); throw new Error(Errors.MISSING_ARGUMENTS, "There is a function at the end without any argument specified.");
else { } else {
((FunctionSingle) currentFunction).setParameter(lastFunction); ((FunctionSingle) currentFunction).setParameter(lastFunction);
functionsList.remove(curIndex.i + 1); functionsList.remove(curIndex.i + 1);
} }
return true; return true;
} }
}
return false; return false;
} }

View File

@ -15,8 +15,8 @@ public class FixSumsAndSubtractions implements MathParserStep {
@Override @Override
public boolean eval(final IntWrapper curIndex, final Function lastFunction, final Function currentFunction, public boolean eval(final IntWrapper curIndex, final Function lastFunction, final Function currentFunction,
final ObjectArrayList<Function> functionsList) throws Error { final ObjectArrayList<Function> functionsList) throws Error {
if (currentFunction instanceof Sum || currentFunction instanceof Subtraction || currentFunction instanceof SumSubtraction) if (currentFunction instanceof Sum || currentFunction instanceof Subtraction || currentFunction instanceof SumSubtraction) {
if (currentFunction.getParameter(0) == null && currentFunction.getParameter(1) == null) if (currentFunction.getParameter(0) == null && currentFunction.getParameter(1) == null) {
if (curIndex.i - 1 >= 0 && curIndex.i + 1 < functionsList.size()) { if (curIndex.i - 1 >= 0 && curIndex.i + 1 < functionsList.size()) {
final Function next = functionsList.get(curIndex.i + 1); final Function next = functionsList.get(curIndex.i + 1);
final Function prev = functionsList.get(curIndex.i - 1); final Function prev = functionsList.get(curIndex.i - 1);
@ -25,8 +25,11 @@ public class FixSumsAndSubtractions implements MathParserStep {
functionsList.remove(curIndex.i - 1); functionsList.remove(curIndex.i - 1);
curIndex.i--; curIndex.i--;
return true; return true;
} else if (currentFunction.getParameter(0) == null || currentFunction.getParameter(1) == null) } else if (currentFunction.getParameter(0) == null || currentFunction.getParameter(1) == null) {
throw new Error(Errors.MISSING_ARGUMENTS, "There is a function at the end without any argument specified."); throw new Error(Errors.MISSING_ARGUMENTS, "There is a function at the end without any argument specified.");
}
}
}
return false; return false;
} }

View File

@ -21,7 +21,7 @@ public class JoinNumberAndVariables implements MathParserStep {
@Override @Override
public boolean eval(final IntWrapper curIndex, final Function lastFunction, final Function currentFunction, public boolean eval(final IntWrapper curIndex, final Function lastFunction, final Function currentFunction,
final ObjectArrayList<Function> functionsList) { final ObjectArrayList<Function> functionsList) {
if (currentFunction instanceof Number | currentFunction instanceof Variable | currentFunction instanceof Division) if (currentFunction instanceof Number | currentFunction instanceof Variable | currentFunction instanceof Division) {
if (lastFunction instanceof Variable | lastFunction instanceof Number | (lastFunction instanceof Multiplication && ((Multiplication) lastFunction).getParameter2() != null)) { if (lastFunction instanceof Variable | lastFunction instanceof Number | (lastFunction instanceof Multiplication && ((Multiplication) lastFunction).getParameter2() != null)) {
final Function a = currentFunction; final Function a = currentFunction;
final Function b = lastFunction; final Function b = lastFunction;
@ -29,6 +29,7 @@ public class JoinNumberAndVariables implements MathParserStep {
functionsList.remove(curIndex.i + 1); functionsList.remove(curIndex.i + 1);
return true; return true;
} }
}
return false; return false;
} }

View File

@ -20,10 +20,11 @@ public class RemoveParentheses implements MathParserStep {
public boolean eval(final IntWrapper curIndex, final Function lastFunction, final Function currentFunction, public boolean eval(final IntWrapper curIndex, final Function lastFunction, final Function currentFunction,
final ObjectArrayList<Function> functionsList) { final ObjectArrayList<Function> functionsList) {
if (currentFunction instanceof Expression) { if (currentFunction instanceof Expression) {
if (((Expression) currentFunction).getParameter() == null) if (((Expression) currentFunction).getParameter() == null) {
functionsList.remove(curIndex.i); functionsList.remove(curIndex.i);
else } else {
functionsList.set(curIndex.i, ((Expression) currentFunction).getParameter()); functionsList.set(curIndex.i, ((Expression) currentFunction).getParameter());
}
return true; return true;
} }
return false; return false;

View File

@ -35,8 +35,9 @@ public class RulesManager {
public static void initialize() { public static void initialize() {
Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_NODEBUG, "RulesManager", "Loading the rules"); Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_NODEBUG, "RulesManager", "Loading the rules");
RulesManager.rules = new ObjectArrayList[RuleType.values().length]; RulesManager.rules = new ObjectArrayList[RuleType.values().length];
for (final RuleType val : RuleType.values()) for (final RuleType val : RuleType.values()) {
RulesManager.rules[val.ordinal()] = new ObjectArrayList<>(); RulesManager.rules[val.ordinal()] = new ObjectArrayList<>();
}
try { try {
boolean compiledSomething = false; boolean compiledSomething = false;
InputStream defaultRulesList; InputStream defaultRulesList;
@ -47,14 +48,16 @@ public class RulesManager {
} }
final List<String> ruleLines = new ArrayList<>(); final List<String> ruleLines = new ArrayList<>();
final File rulesPath = Engine.getPlatform().getStorageUtils().get("rules/"); final File rulesPath = Engine.getPlatform().getStorageUtils().get("rules/");
if (rulesPath.exists()) if (rulesPath.exists()) {
for (final File f : Engine.getPlatform().getStorageUtils().walk(rulesPath)) for (final File f : Engine.getPlatform().getStorageUtils().walk(rulesPath)) {
if (f.toString().endsWith(".java")) { if (f.toString().endsWith(".java")) {
String path = Engine.getPlatform().getStorageUtils().relativize(rulesPath, f).toString(); String path = Engine.getPlatform().getStorageUtils().relativize(rulesPath, f).toString();
path = path.substring(0, path.length() - ".java".length()); path = path.substring(0, path.length() - ".java".length());
ruleLines.add(path); ruleLines.add(path);
Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_NODEBUG, "RulesManager", "Found external rule: " + f.getAbsolutePath()); Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_NODEBUG, "RulesManager", "Found external rule: " + f.getAbsolutePath());
} }
}
}
ruleLines.addAll(Engine.getPlatform().getStorageUtils().readAllLines(defaultRulesList)); ruleLines.addAll(Engine.getPlatform().getStorageUtils().readAllLines(defaultRulesList));
final File tDir = Engine.getPlatform().getStorageUtils().resolve(Engine.getPlatform().getStorageUtils().get(System.getProperty("java.io.tmpdir"), "WarpPi-Calculator"), "rules-rt"); final File tDir = Engine.getPlatform().getStorageUtils().resolve(Engine.getPlatform().getStorageUtils().get(System.getProperty("java.io.tmpdir"), "WarpPi-Calculator"), "rules-rt");
@ -65,31 +68,34 @@ public class RulesManager {
File cacheFilePath = null; File cacheFilePath = null;
cacheFilePath = new File("math-rules-cache.zip"); cacheFilePath = new File("math-rules-cache.zip");
boolean cacheFileExists = false; boolean cacheFileExists = false;
if (Engine.getPlatform().isJavascript()) if (Engine.getPlatform().isJavascript()) {
Engine.getPlatform().loadPlatformRules(); Engine.getPlatform().loadPlatformRules();
else { } else {
if (cacheFilePath.exists()) { if (cacheFilePath.exists()) {
cacheFileExists = true; cacheFileExists = true;
cacheFileStream = new FileInputStream(cacheFilePath); cacheFileStream = new FileInputStream(cacheFilePath);
} else } else {
try { try {
cacheFileStream = Engine.getPlatform().getStorageUtils().getResourceStream("/math-rules-cache.zip");//Paths.get(Utils.getJarDirectory().toString()).resolve("math-rules-cache.zip").toAbsolutePath( cacheFileStream = Engine.getPlatform().getStorageUtils().getResourceStream("/math-rules-cache.zip");//Paths.get(Utils.getJarDirectory().toString()).resolve("math-rules-cache.zip").toAbsolutePath(
org.apache.commons.io.FileUtils.copyInputStreamToFile(cacheFileStream, cacheFilePath); org.apache.commons.io.FileUtils.copyInputStreamToFile(cacheFileStream, cacheFilePath);
cacheFileExists = true; cacheFileExists = true;
} catch (final IOException ex) { //File does not exists. } catch (final IOException ex) { //File does not exists.
} }
}
boolean useCache = false; boolean useCache = false;
if (cacheFileExists) if (cacheFileExists) {
try { try {
if (tDir.exists()) if (tDir.exists()) {
tDir.delete(); tDir.delete();
}
Engine.getPlatform().unzip(cacheFilePath.toString(), tDir.getParent().toString(), ""); Engine.getPlatform().unzip(cacheFilePath.toString(), tDir.getParent().toString(), "");
useCache = !StaticVars.startupArguments.isUncached(); useCache = !StaticVars.startupArguments.isUncached();
} catch (final Exception ex) { } catch (final Exception ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
}
for (final String rulesLine : ruleLines) for (final String rulesLine : ruleLines) {
if (rulesLine.length() > 0) { if (rulesLine.length() > 0) {
final String[] ruleDetails = rulesLine.split(",", 1); final String[] ruleDetails = rulesLine.split(",", 1);
final String ruleName = ruleDetails[0]; final String ruleName = ruleDetails[0];
@ -98,20 +104,22 @@ public class RulesManager {
final String pathWithoutExtension = "/rules/" + ruleNameEscaped; final String pathWithoutExtension = "/rules/" + ruleNameEscaped;
final String scriptFile = pathWithoutExtension + ".java"; final String scriptFile = pathWithoutExtension + ".java";
final InputStream resourcePath = Engine.getPlatform().getStorageUtils().getResourceStream(scriptFile); final InputStream resourcePath = Engine.getPlatform().getStorageUtils().getResourceStream(scriptFile);
if (resourcePath == null) if (resourcePath == null) {
System.err.println(new FileNotFoundException("/rules/" + ruleName + ".java not found!")); System.err.println(new FileNotFoundException("/rules/" + ruleName + ".java not found!"));
else { } else {
Rule r = null; Rule r = null;
if (useCache) if (useCache) {
try { try {
Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN, "RulesManager", ruleName, "Trying to load cached rule"); Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN, "RulesManager", ruleName, "Trying to load cached rule");
r = RulesManager.loadClassRuleFromSourceFile(scriptFile, tDir); r = RulesManager.loadClassRuleFromSourceFile(scriptFile, tDir);
if (r != null) if (r != null) {
Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN, "RulesManager", ruleName, "Loaded cached rule"); Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN, "RulesManager", ruleName, "Loaded cached rule");
}
} catch (final Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_NODEBUG, "RulesManager", ruleName, "Can't load the rule " + ruleNameEscaped + "!"); Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_NODEBUG, "RulesManager", ruleName, "Can't load the rule " + ruleNameEscaped + "!");
} }
}
if (r == null || !useCache) { if (r == null || !useCache) {
Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN, "RulesManager", ruleName, "This rule is not cached. Compiling"); Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN, "RulesManager", ruleName, "This rule is not cached. Compiling");
try { try {
@ -122,20 +130,24 @@ public class RulesManager {
} }
} }
if (r != null) if (r != null) {
RulesManager.addRule(r); RulesManager.addRule(r);
}
} }
} }
}
} }
Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_NODEBUG, "RulesManager", "Loaded all the rules successfully"); Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_NODEBUG, "RulesManager", "Loaded all the rules successfully");
if (!Engine.getPlatform().isJavascript() && compiledSomething) { if (!Engine.getPlatform().isJavascript() && compiledSomething) {
if (cacheFileExists || cacheFilePath.exists()) if (cacheFileExists || cacheFilePath.exists()) {
cacheFilePath.delete(); cacheFilePath.delete();
}
Engine.getPlatform().zip(tDir.toString(), cacheFilePath.toString(), ""); Engine.getPlatform().zip(tDir.toString(), cacheFilePath.toString(), "");
Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_NODEBUG, "RulesManager", "Cached the compiled rules"); Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_NODEBUG, "RulesManager", "Cached the compiled rules");
} }
if (cacheFileStream != null) if (cacheFileStream != null) {
cacheFileStream.close(); cacheFileStream.close();
}
} catch (URISyntaxException | IOException e) { } catch (URISyntaxException | IOException e) {
e.printStackTrace(); e.printStackTrace();
Engine.getPlatform().exit(1); Engine.getPlatform().exit(1);
@ -157,25 +169,30 @@ public class RulesManager {
final File tDirPath = Engine.getPlatform().getStorageUtils().getParent(Engine.getPlatform().getStorageUtils().resolve(tDir, javaClassNameAndPath.replace('.', File.separatorChar))); final File tDirPath = Engine.getPlatform().getStorageUtils().getParent(Engine.getPlatform().getStorageUtils().resolve(tDir, javaClassNameAndPath.replace('.', File.separatorChar)));
final File tFileJava = Engine.getPlatform().getStorageUtils().resolve(tDirPath, javaClassNameOnly + ".java"); final File tFileJava = Engine.getPlatform().getStorageUtils().resolve(tDirPath, javaClassNameOnly + ".java");
final File tFileClass = Engine.getPlatform().getStorageUtils().resolve(tDirPath, javaClassNameOnly + ".class"); final File tFileClass = Engine.getPlatform().getStorageUtils().resolve(tDirPath, javaClassNameOnly + ".class");
if (!tDirPath.exists()) if (!tDirPath.exists()) {
Engine.getPlatform().getStorageUtils().createDirectories(tDirPath); Engine.getPlatform().getStorageUtils().createDirectories(tDirPath);
if (tFileJava.exists()) }
if (tFileJava.exists()) {
tFileJava.delete(); tFileJava.delete();
}
Engine.getPlatform().getStorageUtils(); Engine.getPlatform().getStorageUtils();
Engine.getPlatform().getStorageUtils(); Engine.getPlatform().getStorageUtils();
Engine.getPlatform().getStorageUtils().write(tFileJava, javaCode.getBytes("UTF-8"), StorageUtils.OpenOptionWrite, StorageUtils.OpenOptionCreate); Engine.getPlatform().getStorageUtils().write(tFileJava, javaCode.getBytes("UTF-8"), StorageUtils.OpenOptionWrite, StorageUtils.OpenOptionCreate);
final boolean compiled = Engine.getPlatform().compile(new String[] { "-nowarn", "-1.8", tFileJava.toString() }, new PrintWriter(System.out), new PrintWriter(System.err)); final boolean compiled = Engine.getPlatform().compile(new String[] { "-nowarn", "-1.8", tFileJava.toString() }, new PrintWriter(System.out), new PrintWriter(System.err));
if (StaticVars.startupArguments.isUncached()) if (StaticVars.startupArguments.isUncached()) {
tFileJava.deleteOnExit(); tFileJava.deleteOnExit();
else } else {
tFileJava.delete(); tFileJava.delete();
}
if (compiled) { if (compiled) {
tFileClass.deleteOnExit(); tFileClass.deleteOnExit();
return RulesManager.loadClassRuleDirectly(javaClassNameAndPath, tDir); return RulesManager.loadClassRuleDirectly(javaClassNameAndPath, tDir);
} else } else {
throw new IOException("Can't build script file '" + scriptFile + "'"); throw new IOException("Can't build script file '" + scriptFile + "'");
} else }
} else {
throw new IOException("Can't build script file '" + scriptFile + "', the header is missing or wrong."); throw new IOException("Can't build script file '" + scriptFile + "', the header is missing or wrong.");
}
} }
public static Rule loadClassRuleFromSourceFile(final String scriptFile, final File tDir) throws IOException, public static Rule loadClassRuleFromSourceFile(final String scriptFile, final File tDir) throws IOException,
@ -193,8 +210,9 @@ public class RulesManager {
ex.printStackTrace(); ex.printStackTrace();
return null; return null;
} }
} else } else {
throw new IOException("Can't load script file '" + scriptFile + "', the header is missing or wrong."); throw new IOException("Can't load script file '" + scriptFile + "', the header is missing or wrong.");
}
} }
public static Rule loadClassRuleDirectly(final String javaClassNameAndPath, final File tDir) throws IOException, public static Rule loadClassRuleDirectly(final String javaClassNameAndPath, final File tDir) throws IOException,

View File

@ -46,17 +46,20 @@ public class DivisionRule1 {
Function prec; Function prec;
for (int part = 0; part < 2; part++) { for (int part = 0; part < 2; part++) {
prec = null; prec = null;
for (int i = size[part] - 1; i >= 0; i--) for (int i = size[part] - 1; i >= 0; i--) {
if (i != workingElementCouple[part]) if (i != workingElementCouple[part]) {
if (prec == null) if (prec == null) {
prec = elements[part].get(i); prec = elements[part].get(i);
else { } else {
final Function a = elements[part].get(i); final Function a = elements[part].get(i);
final Function b = prec; final Function b = prec;
prec = new Multiplication(root, a, b); prec = new Multiplication(root, a, b);
} }
if (prec == null) }
}
if (prec == null) {
prec = new Number(root, 1); prec = new Number(root, 1);
}
resultDivisionArray[part] = prec; resultDivisionArray[part] = prec;
} }
@ -73,8 +76,9 @@ public class DivisionRule1 {
final ObjectArrayList<Function> elementsNumerator = new ObjectArrayList<>(); final ObjectArrayList<Function> elementsNumerator = new ObjectArrayList<>();
Function numMult = division.getParameter1(); Function numMult = division.getParameter1();
while (numMult instanceof Multiplication) { while (numMult instanceof Multiplication) {
if (Thread.interrupted()) if (Thread.interrupted()) {
throw new InterruptedException(); throw new InterruptedException();
}
elementsNumerator.add(((Multiplication) numMult).getParameter1()); elementsNumerator.add(((Multiplication) numMult).getParameter1());
numMult = ((Multiplication) numMult).getParameter2(); numMult = ((Multiplication) numMult).getParameter2();
} }
@ -83,8 +87,9 @@ public class DivisionRule1 {
final ObjectArrayList<Function> elementsDenominator = new ObjectArrayList<>(); final ObjectArrayList<Function> elementsDenominator = new ObjectArrayList<>();
Function denomMult = division.getParameter2(); Function denomMult = division.getParameter2();
while (denomMult instanceof Multiplication) { while (denomMult instanceof Multiplication) {
if (Thread.interrupted()) if (Thread.interrupted()) {
throw new InterruptedException(); throw new InterruptedException();
}
elementsDenominator.add(((Multiplication) denomMult).getParameter1()); elementsDenominator.add(((Multiplication) denomMult).getParameter1());
denomMult = ((Multiplication) denomMult).getParameter2(); denomMult = ((Multiplication) denomMult).getParameter2();
} }

View File

@ -30,8 +30,9 @@ public class MultiplicationMethod1 {
final int size = elements.size(); final int size = elements.size();
Function prec = new Multiplication(root, elem1, elem2); Function prec = new Multiplication(root, elem1, elem2);
for (int i = size - 1; i >= 0; i--) { for (int i = size - 1; i >= 0; i--) {
if (Thread.interrupted()) if (Thread.interrupted()) {
throw new InterruptedException(); throw new InterruptedException();
}
if (i != workingElementCouple[0] & i != workingElementCouple[1]) { if (i != workingElementCouple[0] & i != workingElementCouple[1]) {
final Function a = prec; final Function a = prec;
final Function b = elements.get(i); final Function b = elements.get(i);
@ -49,8 +50,9 @@ public class MultiplicationMethod1 {
private static ObjectArrayList<Function> getMultiplicationElements(Function mult) throws InterruptedException { private static ObjectArrayList<Function> getMultiplicationElements(Function mult) throws InterruptedException {
final ObjectArrayList<Function> elements = new ObjectArrayList<>(); final ObjectArrayList<Function> elements = new ObjectArrayList<>();
while (mult instanceof Multiplication) { while (mult instanceof Multiplication) {
if (Thread.interrupted()) if (Thread.interrupted()) {
throw new InterruptedException(); throw new InterruptedException();
}
elements.add(((Multiplication) mult).getParameter1()); elements.add(((Multiplication) mult).getParameter1());
mult = ((Multiplication) mult).getParameter2(); mult = ((Multiplication) mult).getParameter2();
} }

View File

@ -38,10 +38,11 @@ public class SumMethod1 {
final int size = elements.size(); final int size = elements.size();
Function prec = new Sum(root, elem1, elem2); Function prec = new Sum(root, elem1, elem2);
for (int i = size - 1; i >= 0; i--) for (int i = size - 1; i >= 0; i--) {
if (i != workingElementCouple[0] & i != workingElementCouple[1]) { if (i != workingElementCouple[0] & i != workingElementCouple[1]) {
if (Thread.interrupted()) if (Thread.interrupted()) {
throw new InterruptedException(); throw new InterruptedException();
}
final Function a = prec; final Function a = prec;
final Function b = elements.get(i); final Function b = elements.get(i);
if (b instanceof Negative) { if (b instanceof Negative) {
@ -50,9 +51,11 @@ public class SumMethod1 {
} else if (b instanceof Number && ((Number) b).getTerm().compareTo(BigDecimal.ZERO) < 0) { } else if (b instanceof Number && ((Number) b).getTerm().compareTo(BigDecimal.ZERO) < 0) {
prec = new Subtraction(root, a, ((Number) b).multiply(new Number(root, -1))); prec = new Subtraction(root, a, ((Number) b).multiply(new Number(root, -1)));
((FunctionOperator) prec).getParameter2(); ((FunctionOperator) prec).getParameter2();
} else } else {
prec = new Sum(root, a, b); prec = new Sum(root, a, b);
}
} }
}
result = prec; result = prec;
@ -65,12 +68,14 @@ public class SumMethod1 {
final MathContext root = sum.getMathContext(); final MathContext root = sum.getMathContext();
final ObjectArrayList<Function> elements = new ObjectArrayList<>(); final ObjectArrayList<Function> elements = new ObjectArrayList<>();
while (sum instanceof Sum || sum instanceof Subtraction) { while (sum instanceof Sum || sum instanceof Subtraction) {
if (Thread.interrupted()) if (Thread.interrupted()) {
throw new InterruptedException(); throw new InterruptedException();
if (sum instanceof Sum) }
if (sum instanceof Sum) {
elements.add(((FunctionOperator) sum).getParameter2()); elements.add(((FunctionOperator) sum).getParameter2());
else } else {
elements.add(new Negative(root, ((FunctionOperator) sum).getParameter2())); elements.add(new Negative(root, ((FunctionOperator) sum).getParameter2()));
}
sum = ((FunctionOperator) sum).getParameter1(); sum = ((FunctionOperator) sum).getParameter1();
} }
elements.add(sum); elements.add(sum);

View File

@ -43,13 +43,17 @@ public class MathSolver {
final ObjectArrayList<Function>[] currFncHistory = new ObjectArrayList[stepStates.length]; final ObjectArrayList<Function>[] currFncHistory = new ObjectArrayList[stepStates.length];
final String stepName = "Step " + stepNumber; final String stepName = "Step " + stepNumber;
if (initStepState > endStepState) { if (initStepState > endStepState) {
for (int i = initStepState; i < stepStates.length; i++) for (int i = initStepState; i < stepStates.length; i++) {
currFncHistory[i] = currFnc; currFncHistory[i] = currFnc;
for (int i = 0; i <= initStepState; i++) }
for (int i = 0; i <= initStepState; i++) {
currFncHistory[i] = currFnc; currFncHistory[i] = currFnc;
} else }
for (int i = initStepState; i <= endStepState; i++) } else {
for (int i = initStepState; i <= endStepState; i++) {
currFncHistory[i] = currFnc; currFncHistory[i] = currFnc;
}
}
if (currFnc != null) { if (currFnc != null) {
lastFunctions[1] = lastFunctions[0]; lastFunctions[1] = lastFunctions[0];
lastFunctions[0] = currFncHistory; lastFunctions[0] = currFncHistory;
@ -59,8 +63,9 @@ public class MathSolver {
Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", stepName, "Starting step " + stepStates[initStepState] + ". Input: " + currFnc); Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", stepName, "Starting step " + stepStates[initStepState] + ". Input: " + currFnc);
final ObjectArrayList<Function> stepResult = solveStep(lastFnc, stepState); final ObjectArrayList<Function> stepResult = solveStep(lastFnc, stepState);
if (stepResult != null) { if (stepResult != null) {
for (final Function result : stepResult) for (final Function result : stepResult) {
Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, result.toString()); Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, result.toString());
}
currFnc = stepResult; currFnc = stepResult;
steps.add(currFnc); steps.add(currFnc);
} }
@ -70,33 +75,39 @@ public class MathSolver {
Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", stepName, "Step result: " + stepResult); Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", stepName, "Step result: " + stepResult);
Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", stepName, "Step result details: Consecutive steps that did nothing: " + consecutiveNullSteps + ", this step did " + stepStateRepetitions + " simplifications."); Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", stepName, "Step result details: Consecutive steps that did nothing: " + consecutiveNullSteps + ", this step did " + stepStateRepetitions + " simplifications.");
Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", stepName, "Next step state: " + stepStates[endStepState]); Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", stepName, "Next step state: " + stepStates[endStepState]);
if (Engine.getPlatform().getSettings().isDebugEnabled()) if (Engine.getPlatform().getSettings().isDebugEnabled()) {
Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", stepName, currFnc + " is " + (checkEquals(currFnc, lastFunctions[0][endStepState]) ? "" : "not ") + "equals to [0]:" + lastFunctions[0][endStepState]); Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", stepName, currFnc + " is " + (checkEquals(currFnc, lastFunctions[0][endStepState]) ? "" : "not ") + "equals to [0]:" + lastFunctions[0][endStepState]);
if (Engine.getPlatform().getSettings().isDebugEnabled()) }
if (Engine.getPlatform().getSettings().isDebugEnabled()) {
Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", stepName, currFnc + " is " + (checkEquals(currFnc, lastFunctions[1][endStepState]) ? "" : "not ") + "equals to [1]:" + lastFunctions[1][endStepState]); Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", stepName, currFnc + " is " + (checkEquals(currFnc, lastFunctions[1][endStepState]) ? "" : "not ") + "equals to [1]:" + lastFunctions[1][endStepState]);
}
} while (consecutiveNullSteps < stepStates.length && !checkEquals(currFnc, lastFunctions[0][endStepState]) && !checkEquals(currFnc, lastFunctions[1][endStepState])); } while (consecutiveNullSteps < stepStates.length && !checkEquals(currFnc, lastFunctions[0][endStepState]) && !checkEquals(currFnc, lastFunctions[1][endStepState]));
if (consecutiveNullSteps >= stepStates.length) if (consecutiveNullSteps >= stepStates.length) {
Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", "Loop ended because " + consecutiveNullSteps + " >= " + stepStates.length); Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", "Loop ended because " + consecutiveNullSteps + " >= " + stepStates.length);
else if (checkEquals(currFnc, lastFunctions[0][endStepState])) } else if (checkEquals(currFnc, lastFunctions[0][endStepState])) {
Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", "Loop ended because " + currFnc + " is equals to [0]:" + lastFunctions[0][endStepState]); Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", "Loop ended because " + currFnc + " is equals to [0]:" + lastFunctions[0][endStepState]);
else } else {
Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", "Loop ended because " + currFnc + " is equals to [1]:" + lastFunctions[1][endStepState]); Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", "Loop ended because " + currFnc + " is equals to [1]:" + lastFunctions[1][endStepState]);
}
return steps; return steps;
} }
private boolean checkEquals(final ObjectArrayList<Function> a, final ObjectArrayList<Function> b) { private boolean checkEquals(final ObjectArrayList<Function> a, final ObjectArrayList<Function> b) {
if (a == null && b == null) if (a == null && b == null) {
return true; return true;
else if (a != null && b != null) } else if (a != null && b != null) {
if (a.isEmpty() == b.isEmpty()) { if (a.isEmpty() == b.isEmpty()) {
int size; int size;
if ((size = a.size()) == b.size()) { if ((size = a.size()) == b.size()) {
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++) {
if (a.get(i).equals(b.get(i)) == false) if (a.get(i).equals(b.get(i)) == false) {
return false; return false;
}
}
return true; return true;
} }
} }
}
return false; return false;
} }
@ -109,8 +120,9 @@ public class MathSolver {
private ObjectArrayList<Function> solveStep(ObjectArrayList<Function> fncs, final AtomicInteger stepState) private ObjectArrayList<Function> solveStep(ObjectArrayList<Function> fncs, final AtomicInteger stepState)
throws InterruptedException, Error { throws InterruptedException, Error {
final ObjectArrayList<Function> processedFncs = applyRules(fncs, RuleType.EXISTENCE); // Apply existence rules before everything final ObjectArrayList<Function> processedFncs = applyRules(fncs, RuleType.EXISTENCE); // Apply existence rules before everything
if (processedFncs != null) if (processedFncs != null) {
fncs = processedFncs; fncs = processedFncs;
}
RuleType currentAcceptedRules; RuleType currentAcceptedRules;
switch (stepStates[stepState.get()]) { switch (stepStates[stepState.get()]) {
case _1_CALCULATION: { case _1_CALCULATION: {
@ -204,8 +216,9 @@ public class MathSolver {
for (final Rule rule : rules) { for (final Rule rule : rules) {
final List<Function> ruleResults = fnc.simplify(rule); final List<Function> ruleResults = fnc.simplify(rule);
if (ruleResults != null && !ruleResults.isEmpty()) { if (ruleResults != null && !ruleResults.isEmpty()) {
if (results == null) if (results == null) {
results = new ObjectArrayList<>(); results = new ObjectArrayList<>();
}
results.addAll(ruleResults); results.addAll(ruleResults);
appliedRules.add(rule); appliedRules.add(rule);
didSomething = true; didSomething = true;
@ -213,21 +226,24 @@ public class MathSolver {
} }
} }
if (!didSomething && fncs.size() > 1) { if (!didSomething && fncs.size() > 1) {
if (results == null) if (results == null) {
results = new ObjectArrayList<>(); results = new ObjectArrayList<>();
}
results.add(fnc); results.add(fnc);
} }
} }
if (appliedRules.isEmpty()) if (appliedRules.isEmpty()) {
results = null; results = null;
}
if (Engine.getPlatform().getConsoleUtils().getOutputLevel() >= ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN & results != null && !appliedRules.isEmpty()) { if (Engine.getPlatform().getConsoleUtils().getOutputLevel() >= ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN & results != null && !appliedRules.isEmpty()) {
final StringBuilder rulesStr = new StringBuilder(); final StringBuilder rulesStr = new StringBuilder();
for (final Rule r : appliedRules) { for (final Rule r : appliedRules) {
rulesStr.append(r.getRuleName()); rulesStr.append(r.getRuleName());
rulesStr.append(','); rulesStr.append(',');
} }
if (rulesStr.length() > 0) if (rulesStr.length() > 0) {
rulesStr.setLength(rulesStr.length() - 1); rulesStr.setLength(rulesStr.length() - 1);
}
Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", currentAcceptedRules.toString(), "Applied rules: " + rulesStr); Engine.getPlatform().getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_VERBOSE, "Math Solver", currentAcceptedRules.toString(), "Applied rules: " + rulesStr);
} }
return results; return results;

View File

@ -14,9 +14,9 @@ public class CacheUtils {
public static <T> T get(final String entryName, final long expireDelta, final Supplier<T> function) { public static <T> T get(final String entryName, final long expireDelta, final Supplier<T> function) {
CacheUtils.refreshEntry(entryName); CacheUtils.refreshEntry(entryName);
synchronized (CacheUtils.cache) { synchronized (CacheUtils.cache) {
if (CacheUtils.cache.containsKey(entryName)) if (CacheUtils.cache.containsKey(entryName)) {
return (T) CacheUtils.cache.get(entryName); return (T) CacheUtils.cache.get(entryName);
else { } else {
CacheUtils.time.put(entryName, System.currentTimeMillis() + expireDelta); CacheUtils.time.put(entryName, System.currentTimeMillis() + expireDelta);
final T result = function.get(); final T result = function.get();
CacheUtils.cache.put(entryName, result); CacheUtils.cache.put(entryName, result);
@ -28,11 +28,12 @@ public class CacheUtils {
private static void refreshEntry(final String entryName) { private static void refreshEntry(final String entryName) {
synchronized (CacheUtils.time) { synchronized (CacheUtils.time) {
synchronized (CacheUtils.cache) { synchronized (CacheUtils.cache) {
if (CacheUtils.time.containsKey(entryName)) if (CacheUtils.time.containsKey(entryName)) {
if (CacheUtils.time.get(entryName) <= System.currentTimeMillis()) { if (CacheUtils.time.get(entryName) <= System.currentTimeMillis()) {
CacheUtils.time.remove(entryName); CacheUtils.time.remove(entryName);
CacheUtils.cache.remove(entryName); CacheUtils.cache.remove(entryName);
} }
}
} }
} }
} }

View File

@ -56,9 +56,11 @@ public class Utils {
} }
public static boolean isInArray(final char ch, final char[] a) { public static boolean isInArray(final char ch, final char[] a) {
for (final char c : a) for (final char c : a) {
if (c == ch) if (c == ch) {
return true; return true;
}
}
return false; return false;
} }
@ -68,20 +70,23 @@ public class Utils {
String regex = null; String regex = null;
for (final String symbol : array) { for (final String symbol : array) {
boolean contained = false; boolean contained = false;
for (final String smb : Utils.regexNormalSymbols) for (final String smb : Utils.regexNormalSymbols) {
if (smb.equals(symbol)) { if (smb.equals(symbol)) {
contained = true; contained = true;
break; break;
} }
}
if (contained) { if (contained) {
if (regex != null) if (regex != null) {
regex += "|\\" + symbol; regex += "|\\" + symbol;
else } else {
regex = "\\" + symbol; regex = "\\" + symbol;
} else if (regex != null) }
} else if (regex != null) {
regex += "|" + symbol; regex += "|" + symbol;
else } else {
regex = symbol; regex = symbol;
}
} }
return regex; return regex;
} }
@ -90,20 +95,23 @@ public class Utils {
String regex = null; String regex = null;
for (final char symbol : array) { for (final char symbol : array) {
boolean contained = false; boolean contained = false;
for (final String smb : Utils.regexNormalSymbols) for (final String smb : Utils.regexNormalSymbols) {
if (smb.equals(symbol + "")) { if (smb.equals(symbol + "")) {
contained = true; contained = true;
break; break;
} }
}
if (contained) { if (contained) {
if (regex != null) if (regex != null) {
regex += "|\\" + symbol; regex += "|\\" + symbol;
else } else {
regex = "\\" + symbol; regex = "\\" + symbol;
} else if (regex != null) }
} else if (regex != null) {
regex += "|" + symbol; regex += "|" + symbol;
else } else {
regex = symbol + ""; regex = symbol + "";
}
} }
return regex; return regex;
} }
@ -143,112 +151,152 @@ public class Utils {
} }
public static boolean areThereOnlySettedUpFunctionsSumsEquationsAndSystems(final List<Function> fl) { public static boolean areThereOnlySettedUpFunctionsSumsEquationsAndSystems(final List<Function> fl) {
for (int i = 0; i < fl.size(); i++) for (int i = 0; i < fl.size(); i++) {
if (!(fl.get(i) instanceof Number || fl.get(i) instanceof Variable || fl.get(i) instanceof Sum || fl.get(i) instanceof SumSubtraction || fl.get(i) instanceof Subtraction || fl.get(i) instanceof Equation || fl.get(i) instanceof EquationsSystemPart || fl.get(i) instanceof Expression)) if (!(fl.get(i) instanceof Number || fl.get(i) instanceof Variable || fl.get(i) instanceof Sum || fl.get(i) instanceof SumSubtraction || fl.get(i) instanceof Subtraction || fl.get(i) instanceof Equation || fl.get(i) instanceof EquationsSystemPart || fl.get(i) instanceof Expression)) {
if (fl.get(i) instanceof FunctionSingle) { if (fl.get(i) instanceof FunctionSingle) {
if (((FunctionSingle) fl.get(i)).getParameter() == null) if (((FunctionSingle) fl.get(i)).getParameter() == null) {
return false; return false;
}
} else if (fl.get(i) instanceof FunctionOperator) { } else if (fl.get(i) instanceof FunctionOperator) {
if (((FunctionOperator) fl.get(i)).getParameter1() == null || ((FunctionOperator) fl.get(i)).getParameter2() == null) if (((FunctionOperator) fl.get(i)).getParameter1() == null || ((FunctionOperator) fl.get(i)).getParameter2() == null) {
return false; return false;
} else }
} else {
return false; return false;
}
}
}
return true; return true;
} }
public static boolean areThereOnlySettedUpFunctionsSumsMultiplicationsEquationsAndSystems(final List<Function> fl) { public static boolean areThereOnlySettedUpFunctionsSumsMultiplicationsEquationsAndSystems(final List<Function> fl) {
for (int i = 0; i < fl.size(); i++) for (int i = 0; i < fl.size(); i++) {
if (!(fl.get(i) instanceof Number || fl.get(i) instanceof Variable || fl.get(i) instanceof Multiplication || fl.get(i) instanceof Sum || fl.get(i) instanceof SumSubtraction || fl.get(i) instanceof Subtraction || fl.get(i) instanceof Equation || fl.get(i) instanceof EquationsSystemPart || fl.get(i) instanceof Expression)) if (!(fl.get(i) instanceof Number || fl.get(i) instanceof Variable || fl.get(i) instanceof Multiplication || fl.get(i) instanceof Sum || fl.get(i) instanceof SumSubtraction || fl.get(i) instanceof Subtraction || fl.get(i) instanceof Equation || fl.get(i) instanceof EquationsSystemPart || fl.get(i) instanceof Expression)) {
if (fl.get(i) instanceof FunctionSingle) { if (fl.get(i) instanceof FunctionSingle) {
if (((FunctionSingle) fl.get(i)).getParameter() == null) if (((FunctionSingle) fl.get(i)).getParameter() == null) {
return false; return false;
}
} else if (fl.get(i) instanceof FunctionOperator) { } else if (fl.get(i) instanceof FunctionOperator) {
if (((FunctionOperator) fl.get(i)).getParameter1() == null || ((FunctionOperator) fl.get(i)).getParameter2() == null) if (((FunctionOperator) fl.get(i)).getParameter1() == null || ((FunctionOperator) fl.get(i)).getParameter2() == null) {
return false; return false;
} else }
} else {
return false; return false;
}
}
}
return true; return true;
} }
public static boolean areThereOnlySettedUpFunctionsEquationsAndSystems(final List<Function> fl) { public static boolean areThereOnlySettedUpFunctionsEquationsAndSystems(final List<Function> fl) {
for (int i = 0; i < fl.size(); i++) for (int i = 0; i < fl.size(); i++) {
if (!(fl.get(i) instanceof Number || fl.get(i) instanceof Variable || fl.get(i) instanceof Equation || fl.get(i) instanceof EquationsSystemPart || fl.get(i) instanceof Expression)) if (!(fl.get(i) instanceof Number || fl.get(i) instanceof Variable || fl.get(i) instanceof Equation || fl.get(i) instanceof EquationsSystemPart || fl.get(i) instanceof Expression)) {
if (fl.get(i) instanceof FunctionSingle) { if (fl.get(i) instanceof FunctionSingle) {
if (((FunctionSingle) fl.get(i)).getParameter() == null) if (((FunctionSingle) fl.get(i)).getParameter() == null) {
return false; return false;
}
} else if (fl.get(i) instanceof FunctionOperator) { } else if (fl.get(i) instanceof FunctionOperator) {
if (((FunctionOperator) fl.get(i)).getParameter1() == null || ((FunctionOperator) fl.get(i)).getParameter2() == null) if (((FunctionOperator) fl.get(i)).getParameter1() == null || ((FunctionOperator) fl.get(i)).getParameter2() == null) {
return false; return false;
} else }
} else {
return false; return false;
}
}
}
return true; return true;
} }
public static boolean areThereOnlySettedUpFunctionsAndSystems(final List<Function> fl) { public static boolean areThereOnlySettedUpFunctionsAndSystems(final List<Function> fl) {
for (int i = 0; i < fl.size(); i++) for (int i = 0; i < fl.size(); i++) {
if (!(fl.get(i) instanceof Number || fl.get(i) instanceof Variable || fl.get(i) instanceof Equation || fl.get(i) instanceof EquationsSystemPart || fl.get(i) instanceof Expression)) if (!(fl.get(i) instanceof Number || fl.get(i) instanceof Variable || fl.get(i) instanceof Equation || fl.get(i) instanceof EquationsSystemPart || fl.get(i) instanceof Expression)) {
if (fl.get(i) instanceof FunctionSingle) { if (fl.get(i) instanceof FunctionSingle) {
if (((FunctionSingle) fl.get(i)).getParameter() == null) if (((FunctionSingle) fl.get(i)).getParameter() == null) {
return false; return false;
}
} else if (fl.get(i) instanceof FunctionOperator) { } else if (fl.get(i) instanceof FunctionOperator) {
if (((FunctionOperator) fl.get(i)).getParameter1() == null || ((FunctionOperator) fl.get(i)).getParameter2() == null) if (((FunctionOperator) fl.get(i)).getParameter1() == null || ((FunctionOperator) fl.get(i)).getParameter2() == null) {
return false; return false;
} else }
} else {
return false; return false;
}
}
}
return true; return true;
} }
public static boolean areThereOnlyEmptySNFunctions(final List<Function> fl) { public static boolean areThereOnlyEmptySNFunctions(final List<Function> fl) {
for (int i = 0; i < fl.size(); i++) for (int i = 0; i < fl.size(); i++) {
if (fl.get(i) instanceof FunctionSingle) if (fl.get(i) instanceof FunctionSingle) {
if (((FunctionSingle) fl.get(i)).getParameter() == null) if (((FunctionSingle) fl.get(i)).getParameter() == null) {
return true; return true;
}
}
}
return false; return false;
} }
public static boolean areThereOnlyEmptyNSNFunctions(final List<Function> fl) { public static boolean areThereOnlyEmptyNSNFunctions(final List<Function> fl) {
for (int i = 0; i < fl.size(); i++) for (int i = 0; i < fl.size(); i++) {
if (fl.get(i) instanceof FunctionOperator && !(fl.get(i) instanceof Sum) && !(fl.get(i) instanceof SumSubtraction) && !(fl.get(i) instanceof Subtraction) && !(fl.get(i) instanceof Multiplication) && !(fl.get(i) instanceof Division)) if (fl.get(i) instanceof FunctionOperator && !(fl.get(i) instanceof Sum) && !(fl.get(i) instanceof SumSubtraction) && !(fl.get(i) instanceof Subtraction) && !(fl.get(i) instanceof Multiplication) && !(fl.get(i) instanceof Division)) {
if (((FunctionOperator) fl.get(i)).getParameter1() == null && ((FunctionOperator) fl.get(i)).getParameter2() == null) if (((FunctionOperator) fl.get(i)).getParameter1() == null && ((FunctionOperator) fl.get(i)).getParameter2() == null) {
return true; return true;
}
}
}
return false; return false;
} }
public static boolean areThereEmptyMultiplications(final List<Function> fl) { public static boolean areThereEmptyMultiplications(final List<Function> fl) {
for (int i = 0; i < fl.size(); i++) for (int i = 0; i < fl.size(); i++) {
if (fl.get(i) instanceof Multiplication || fl.get(i) instanceof Division) if (fl.get(i) instanceof Multiplication || fl.get(i) instanceof Division) {
if (((FunctionOperator) fl.get(i)).getParameter1() == null && ((FunctionOperator) fl.get(i)).getParameter2() == null) if (((FunctionOperator) fl.get(i)).getParameter1() == null && ((FunctionOperator) fl.get(i)).getParameter2() == null) {
return true; return true;
}
}
}
return false; return false;
} }
public static boolean areThereEmptySums(final List<Function> fl) { public static boolean areThereEmptySums(final List<Function> fl) {
for (int i = 0; i < fl.size(); i++) for (int i = 0; i < fl.size(); i++) {
if (fl.get(i) instanceof Sum || fl.get(i) instanceof SumSubtraction || fl.get(i) instanceof Subtraction) if (fl.get(i) instanceof Sum || fl.get(i) instanceof SumSubtraction || fl.get(i) instanceof Subtraction) {
if (((FunctionOperator) fl.get(i)).getParameter1() == null && ((FunctionOperator) fl.get(i)).getParameter2() == null) if (((FunctionOperator) fl.get(i)).getParameter1() == null && ((FunctionOperator) fl.get(i)).getParameter2() == null) {
return true; return true;
}
}
}
return false; return false;
} }
public static boolean areThereEmptySystems(final List<Function> fl) { public static boolean areThereEmptySystems(final List<Function> fl) {
for (int i = 0; i < fl.size(); i++) for (int i = 0; i < fl.size(); i++) {
if (fl.get(i) instanceof EquationsSystemPart) if (fl.get(i) instanceof EquationsSystemPart) {
if (((EquationsSystemPart) fl.get(i)).getParameter() == null) if (((EquationsSystemPart) fl.get(i)).getParameter() == null) {
return true; return true;
}
}
}
return false; return false;
} }
public static boolean areThereOtherSettedUpFunctions(final List<Function> fl) { public static boolean areThereOtherSettedUpFunctions(final List<Function> fl) {
for (int i = 0; i < fl.size(); i++) for (int i = 0; i < fl.size(); i++) {
if (!(fl.get(i) instanceof Number || fl.get(i) instanceof Variable || fl.get(i) instanceof Sum || fl.get(i) instanceof SumSubtraction || fl.get(i) instanceof Expression || fl.get(i) instanceof FunctionSingle || fl.get(i) instanceof Multiplication || fl.get(i) instanceof Division)) if (!(fl.get(i) instanceof Number || fl.get(i) instanceof Variable || fl.get(i) instanceof Sum || fl.get(i) instanceof SumSubtraction || fl.get(i) instanceof Expression || fl.get(i) instanceof FunctionSingle || fl.get(i) instanceof Multiplication || fl.get(i) instanceof Division)) {
if (fl.get(i) instanceof FunctionSingle) { if (fl.get(i) instanceof FunctionSingle) {
if (((FunctionSingle) fl.get(i)).getParameter() == null) if (((FunctionSingle) fl.get(i)).getParameter() == null) {
return true; return true;
}
} else if (fl.get(i) instanceof FunctionOperator) { } else if (fl.get(i) instanceof FunctionOperator) {
if (((FunctionOperator) fl.get(i)).getParameter1() == null || ((FunctionOperator) fl.get(i)).getParameter2() == null) if (((FunctionOperator) fl.get(i)).getParameter1() == null || ((FunctionOperator) fl.get(i)).getParameter2() == null) {
return true; return true;
} else }
} else {
return true; return true;
}
}
}
return false; return false;
} }
@ -266,8 +314,9 @@ public class Utils {
return new Rational(str); return new Rational(str);
} catch (final NumberFormatException ex) { } catch (final NumberFormatException ex) {
if (new BigDecimal(str).compareTo(new BigDecimal(8000.0)) < 0 && new BigDecimal(str).compareTo(new BigDecimal(-8000.0)) > 0) { if (new BigDecimal(str).compareTo(new BigDecimal(8000.0)) < 0 && new BigDecimal(str).compareTo(new BigDecimal(-8000.0)) > 0) {
if (str.equals("-")) if (str.equals("-")) {
str = "-1"; str = "-1";
}
final long bits = Double.doubleToLongBits(Double.parseDouble(str)); final long bits = Double.doubleToLongBits(Double.parseDouble(str));
final long sign = bits >>> 63; final long sign = bits >>> 63;
@ -283,13 +332,15 @@ public class Utils {
b *= 2; b *= 2;
} }
if (exponent > 0) if (exponent > 0) {
a *= 1 << exponent; a *= 1 << exponent;
else } else {
b *= 1 << -exponent; b *= 1 << -exponent;
}
if (sign == 1) if (sign == 1) {
a *= -1; a *= -1;
}
if (b == 0) { if (b == 0) {
a = 0; a = 0;
@ -314,12 +365,14 @@ public class Utils {
} }
public static boolean equalsVariables(final List<Variable> variables, final List<Variable> variables2) { public static boolean equalsVariables(final List<Variable> variables, final List<Variable> variables2) {
if (variables.size() != variables2.size()) if (variables.size() != variables2.size()) {
return false; return false;
else { } else {
for (final Variable v : variables) for (final Variable v : variables) {
if (!variables2.contains(v)) if (!variables2.contains(v)) {
return false; return false;
}
}
return true; return true;
} }
} }
@ -356,14 +409,16 @@ public class Utils {
public static final int getFontIndex(final boolean small, final boolean zoomed) { public static final int getFontIndex(final boolean small, final boolean zoomed) {
if (small) { if (small) {
if (zoomed) if (zoomed) {
return 3; return 3;
else } else {
return 1; return 1;
} else if (zoomed) }
} else if (zoomed) {
return 2; return 2;
else } else {
return 0; return 0;
}
} }
public static final int getFontHeight(final boolean small) { public static final int getFontHeight(final boolean small) {
@ -372,30 +427,34 @@ public class Utils {
public static final int getFontHeight(final boolean small, final boolean zoomed) { public static final int getFontHeight(final boolean small, final boolean zoomed) {
if (small) { if (small) {
if (zoomed) if (zoomed) {
return Engine.INSTANCE.getHardwareDevice().getDisplayManager().glyphsHeight[3]; return Engine.INSTANCE.getHardwareDevice().getDisplayManager().glyphsHeight[3];
else } else {
return Engine.INSTANCE.getHardwareDevice().getDisplayManager().glyphsHeight[1]; return Engine.INSTANCE.getHardwareDevice().getDisplayManager().glyphsHeight[1];
} else if (zoomed) }
} else if (zoomed) {
return Engine.INSTANCE.getHardwareDevice().getDisplayManager().glyphsHeight[2]; return Engine.INSTANCE.getHardwareDevice().getDisplayManager().glyphsHeight[2];
else } else {
return Engine.INSTANCE.getHardwareDevice().getDisplayManager().glyphsHeight[0]; return Engine.INSTANCE.getHardwareDevice().getDisplayManager().glyphsHeight[0];
}
} }
public static byte[] convertStreamToByteArray(final InputStream stream, final long size) throws IOException { public static byte[] convertStreamToByteArray(final InputStream stream, final long size) throws IOException {
// check to ensure that file size is not larger than Integer.MAX_VALUE. // check to ensure that file size is not larger than Integer.MAX_VALUE.
if (size > Integer.MAX_VALUE) if (size > Integer.MAX_VALUE) {
return new byte[0]; return new byte[0];
}
final byte[] buffer = new byte[(int) size]; final byte[] buffer = new byte[(int) size];
final ByteArrayOutputStream os = new ByteArrayOutputStream(); final ByteArrayOutputStream os = new ByteArrayOutputStream();
int line = 0; int line = 0;
// read bytes from stream, and store them in buffer // read bytes from stream, and store them in buffer
while ((line = stream.read(buffer)) != -1) while ((line = stream.read(buffer)) != -1) {
// Writes bytes from byte array (buffer) into output stream. // Writes bytes from byte array (buffer) into output stream.
os.write(buffer, 0, line); os.write(buffer, 0, line);
}
stream.close(); stream.close();
os.flush(); os.flush();
os.close(); os.close();
@ -405,8 +464,9 @@ public class Utils {
public static int[] realBytes(final byte[] bytes) { public static int[] realBytes(final byte[] bytes) {
final int len = bytes.length; final int len = bytes.length;
final int[] realbytes = new int[len]; final int[] realbytes = new int[len];
for (int i = 0; i < len; i++) for (int i = 0; i < len; i++) {
realbytes[i] = bytes[i] & 0xFF; realbytes[i] = bytes[i] & 0xFF;
}
return realbytes; return realbytes;
} }
@ -419,58 +479,74 @@ public class Utils {
final Function[][] results = new Function[total][2]; final Function[][] results = new Function[total][2];
for (int i = 0; i < total; i++) { for (int i = 0; i < total; i++) {
results[i] = new Function[] { l1.get(cur1), l2.get(cur2) }; results[i] = new Function[] { l1.get(cur1), l2.get(cur2) };
if (i % size2 == 0) if (i % size2 == 0) {
cur1 += 1; cur1 += 1;
if (i % size1 == 0) }
if (i % size1 == 0) {
cur2 += 1; cur2 += 1;
if (cur1 >= size1) }
if (cur1 >= size1) {
cur1 = 0; cur1 = 0;
if (cur2 >= size2) }
if (cur2 >= size2) {
cur2 = 0; cur2 = 0;
}
} }
return results; return results;
} }
public static Function[][] joinFunctionsResults(final ObjectArrayList<ObjectArrayList<Function>> ln) { public static Function[][] joinFunctionsResults(final ObjectArrayList<ObjectArrayList<Function>> ln) {
final int[] sizes = new int[ln.size()]; final int[] sizes = new int[ln.size()];
for (int i = 0; i < ln.size(); i++) for (int i = 0; i < ln.size(); i++) {
sizes[i] = ln.get(i).size(); sizes[i] = ln.get(i).size();
}
final int[] curs = new int[sizes.length]; final int[] curs = new int[sizes.length];
int total = 0; int total = 0;
for (int i = 0; i < ln.size(); i++) for (int i = 0; i < ln.size(); i++) {
if (i == 0) if (i == 0) {
total = sizes[i]; total = sizes[i];
else } else {
total *= sizes[i]; total *= sizes[i];
}
}
final Function[][] results = new Function[total][sizes.length]; final Function[][] results = new Function[total][sizes.length];
for (int i = 0; i < total; i++) { for (int i = 0; i < total; i++) {
results[i] = new Function[sizes.length]; results[i] = new Function[sizes.length];
for (int j = 0; j < sizes.length; j++) for (int j = 0; j < sizes.length; j++) {
results[i][j] = ln.get(j).get(curs[j]); results[i][j] = ln.get(j).get(curs[j]);
for (int k = 0; k < sizes.length; k++) }
if (i % sizes[k] == 0) for (int k = 0; k < sizes.length; k++) {
for (int l = 0; l < sizes.length; l++) if (i % sizes[k] == 0) {
if (l != k) for (int l = 0; l < sizes.length; l++) {
if (l != k) {
curs[l] += 1; curs[l] += 1;
for (int k = 0; k < sizes.length; k++) }
if (curs[k] >= sizes[k]) }
}
}
for (int k = 0; k < sizes.length; k++) {
if (curs[k] >= sizes[k]) {
curs[k] = 0; curs[k] = 0;
}
}
} }
return results; return results;
} }
public static boolean isNegative(final Function b) { public static boolean isNegative(final Function b) {
if (b instanceof Negative) if (b instanceof Negative) {
return true; return true;
else if (b instanceof Number && ((Number) b).getTerm().compareTo(BigDecimal.ZERO) < 0) } else if (b instanceof Number && ((Number) b).getTerm().compareTo(BigDecimal.ZERO) < 0) {
return true; return true;
}
return false; return false;
} }
public static CharSequence multipleChars(final String string, final int i) { public static CharSequence multipleChars(final String string, final int i) {
String result = ""; String result = "";
for (int j = 0; j < i; j++) for (int j = 0; j < i; j++) {
result += string; result += string;
}
return result; return result;
} }
@ -481,15 +557,17 @@ public class Utils {
@SafeVarargs @SafeVarargs
public static <T> String arrayToString(final T... data) { public static <T> String arrayToString(final T... data) {
String sdata = ""; String sdata = "";
for (final T o : data) for (final T o : data) {
sdata += "," + o; sdata += "," + o;
}
return sdata.substring(1); return sdata.substring(1);
} }
public static String arrayToString(final boolean... data) { public static String arrayToString(final boolean... data) {
String sdata = ""; String sdata = "";
for (final boolean o : data) for (final boolean o : data) {
sdata += o ? 1 : 0; sdata += o ? 1 : 0;
}
return sdata; return sdata;
} }
@ -509,30 +587,34 @@ public class Utils {
boolean mb = false; boolean mb = false;
final String displayName = method.getName(); final String displayName = method.getName();
final String displayValue = value.toString(); final String displayValue = value.toString();
if (displayName.endsWith("CpuLoad")) if (displayName.endsWith("CpuLoad")) {
percent = true; percent = true;
if (displayName.endsWith("MemorySize")) }
if (displayName.endsWith("MemorySize")) {
mb = true; mb = true;
}
final List<String> arr = new ArrayList<>(); final List<String> arr = new ArrayList<>();
arr.add("getFreePhysicalMemorySize"); arr.add("getFreePhysicalMemorySize");
arr.add("getProcessCpuLoad"); arr.add("getProcessCpuLoad");
arr.add("getSystemCpuLoad"); arr.add("getSystemCpuLoad");
arr.add("getTotalPhysicalMemorySize"); arr.add("getTotalPhysicalMemorySize");
if (arr.contains(displayName)) if (arr.contains(displayName)) {
if (percent) if (percent) {
try { try {
System.out.println(displayName + " = " + (int) (Float.parseFloat(displayValue) * 10000f) / 100f + "%"); System.out.println(displayName + " = " + (int) (Float.parseFloat(displayValue) * 10000f) / 100f + "%");
} catch (final Exception ex) { } catch (final Exception ex) {
System.out.println(displayName + " = " + displayValue); System.out.println(displayName + " = " + displayValue);
} }
else if (mb) } else if (mb) {
try { try {
System.out.println(displayName + " = " + Long.parseLong(displayValue) / 1024L / 1024L + " MB"); System.out.println(displayName + " = " + Long.parseLong(displayValue) / 1024L / 1024L + " MB");
} catch (final Exception ex) { } catch (final Exception ex) {
System.out.println(displayName + " = " + displayValue); System.out.println(displayName + " = " + displayValue);
} }
else } else {
System.out.println(displayName + " = " + displayValue); System.out.println(displayName + " = " + displayValue);
}
}
} // if } // if
} // for } // for
System.out.println("============"); System.out.println("============");
@ -561,9 +643,10 @@ public class Utils {
} }
public static <T, U> U getOrDefault(final Map<T, U> enginesList, final T key, final U object) { public static <T, U> U getOrDefault(final Map<T, U> enginesList, final T key, final U object) {
if (enginesList.containsKey(key)) if (enginesList.containsKey(key)) {
return enginesList.get(key); return enginesList.get(key);
else } else {
return object; return object;
}
} }
} }

View File

@ -35,11 +35,12 @@ public class Bernoulli {
*/ */
protected void set(final int n, final Rational value) { protected void set(final int n, final Rational value) {
final int nindx = n / 2; final int nindx = n / 2;
if (nindx < Bernoulli.a.size()) if (nindx < Bernoulli.a.size()) {
Bernoulli.a.set(nindx, value); Bernoulli.a.set(nindx, value);
else { } else {
while (Bernoulli.a.size() < nindx) while (Bernoulli.a.size() < nindx) {
Bernoulli.a.add(Rational.ZERO); Bernoulli.a.add(Rational.ZERO);
}
Bernoulli.a.add(value); Bernoulli.a.add(value);
} }
} }
@ -53,15 +54,17 @@ public class Bernoulli {
* @throws Error * @throws Error
*/ */
public Rational at(final int n) throws Error { public Rational at(final int n) throws Error {
if (n == 1) if (n == 1) {
return new Rational(-1, 2); return new Rational(-1, 2);
else if (n % 2 != 0) } else if (n % 2 != 0) {
return Rational.ZERO; return Rational.ZERO;
else { } else {
final int nindx = n / 2; final int nindx = n / 2;
if (Bernoulli.a.size() <= nindx) if (Bernoulli.a.size() <= nindx) {
for (int i = 2 * Bernoulli.a.size(); i <= n; i += 2) for (int i = 2 * Bernoulli.a.size(); i <= n; i += 2) {
set(i, doubleSum(i)); set(i, doubleSum(i));
}
}
return Bernoulli.a.elementAt(nindx); return Bernoulli.a.elementAt(nindx);
} }
} }
@ -80,10 +83,11 @@ public class Bernoulli {
BigInteger bin = BigInteger.ONE; BigInteger bin = BigInteger.ONE;
for (int j = 0; j <= k; j++) { for (int j = 0; j <= k; j++) {
final BigInteger jpown = new BigInteger("" + j).pow(n); final BigInteger jpown = new BigInteger("" + j).pow(n);
if (j % 2 == 0) if (j % 2 == 0) {
jsum = jsum.add(bin.multiply(jpown)); jsum = jsum.add(bin.multiply(jpown));
else } else {
jsum = jsum.subtract(bin.multiply(jpown)); jsum = jsum.subtract(bin.multiply(jpown));
}
/* /*
* update binomial(k,j) recursively * update binomial(k,j) recursively

View File

@ -165,14 +165,16 @@ public class BigComplex {
* and v= +- sqrt((l-re)/2 as the new real and imaginary parts. * and v= +- sqrt((l-re)/2 as the new real and imaginary parts.
*/ */
final BigDecimal l = abs(mc); final BigDecimal l = abs(mc);
if (l.compareTo(BigDecimal.ZERO) == 0) if (l.compareTo(BigDecimal.ZERO) == 0) {
return new BigComplex(BigDecimalMath.scalePrec(BigDecimal.ZERO, mc), BigDecimalMath.scalePrec(BigDecimal.ZERO, mc)); return new BigComplex(BigDecimalMath.scalePrec(BigDecimal.ZERO, mc), BigDecimalMath.scalePrec(BigDecimal.ZERO, mc));
}
final BigDecimal u = BigDecimalMath.sqrt(l.add(re).divide(half, mc), mc); final BigDecimal u = BigDecimalMath.sqrt(l.add(re).divide(half, mc), mc);
final BigDecimal v = BigDecimalMath.sqrt(l.subtract(re).divide(half, mc), mc); final BigDecimal v = BigDecimalMath.sqrt(l.subtract(re).divide(half, mc), mc);
if (im.compareTo(BigDecimal.ZERO) >= 0) if (im.compareTo(BigDecimal.ZERO) >= 0) {
return new BigComplex(u, v); return new BigComplex(u, v);
else } else {
return new BigComplex(u, v.negate()); return new BigComplex(u, v.negate());
}
} }
/** /**

View File

@ -60,9 +60,9 @@ public class BigDecimalMath {
*/ */
static public BigDecimal pi(final MathContext mc) throws Error { static public BigDecimal pi(final MathContext mc) throws Error {
/* look it up if possible */ /* look it up if possible */
if (mc.getPrecision() < BigDecimalMath.PI.precision()) if (mc.getPrecision() < BigDecimalMath.PI.precision()) {
return BigDecimalMath.PI.round(mc); return BigDecimalMath.PI.round(mc);
else { } else {
/* /*
* Broadhurst <a * Broadhurst <a
* href="http://arxiv.org/abs/math/9803067">arXiv:math/9803067</a> * href="http://arxiv.org/abs/math/9803067">arXiv:math/9803067</a>
@ -84,9 +84,9 @@ public class BigDecimalMath {
*/ */
static public BigDecimal gamma(final MathContext mc) throws Error { static public BigDecimal gamma(final MathContext mc) throws Error {
/* look it up if possible */ /* look it up if possible */
if (mc.getPrecision() < BigDecimalMath.GAMMA.precision()) if (mc.getPrecision() < BigDecimalMath.GAMMA.precision()) {
return BigDecimalMath.GAMMA.round(mc); return BigDecimalMath.GAMMA.round(mc);
else { } else {
final double eps = BigDecimalMath.prec2err(0.577, mc.getPrecision()); final double eps = BigDecimalMath.prec2err(0.577, mc.getPrecision());
/* /*
@ -116,8 +116,9 @@ public class BigDecimalMath {
fourn = fourn.shiftLeft(2 * n); fourn = fourn.shiftLeft(2 * n);
c = BigDecimalMath.divideRound(c, fourn); c = BigDecimalMath.divideRound(c, fourn);
resul = resul.subtract(c); resul = resul.subtract(c);
if (c.doubleValue() < 0.1 * eps) if (c.doubleValue() < 0.1 * eps) {
break; break;
}
} }
return resul.round(mc); return resul.round(mc);
} }
@ -134,10 +135,12 @@ public class BigDecimalMath {
* @since 2008-10-27 * @since 2008-10-27
*/ */
static public BigDecimal sqrt(final BigDecimal x, final MathContext mc) { static public BigDecimal sqrt(final BigDecimal x, final MathContext mc) {
if (x.compareTo(BigDecimal.ZERO) < 0) if (x.compareTo(BigDecimal.ZERO) < 0) {
throw new ArithmeticException("negative argument " + x.toString() + " of square root"); throw new ArithmeticException("negative argument " + x.toString() + " of square root");
if (x.abs().subtract(new BigDecimal(Math.pow(10., -mc.getPrecision()))).compareTo(BigDecimal.ZERO) < 0) }
if (x.abs().subtract(new BigDecimal(Math.pow(10., -mc.getPrecision()))).compareTo(BigDecimal.ZERO) < 0) {
return BigDecimalMath.scalePrec(BigDecimal.ZERO, mc); return BigDecimalMath.scalePrec(BigDecimal.ZERO, mc);
}
/* start the computation from a double precision estimate */ /* start the computation from a double precision estimate */
BigDecimal s = new BigDecimal(Math.sqrt(x.doubleValue()), mc); BigDecimal s = new BigDecimal(Math.sqrt(x.doubleValue()), mc);
final BigDecimal half = new BigDecimal("2"); final BigDecimal half = new BigDecimal("2");
@ -157,8 +160,9 @@ public class BigDecimalMath {
* (actually half of this, which we use for a little bit of * (actually half of this, which we use for a little bit of
* additional protection). * additional protection).
*/ */
if (Math.abs(BigDecimal.ONE.subtract(x.divide(s.pow(2, locmc), locmc)).doubleValue()) <= eps) if (Math.abs(BigDecimal.ONE.subtract(x.divide(s.pow(2, locmc), locmc)).doubleValue()) <= eps) {
break; break;
}
s = s.add(x.divide(s, locmc)).divide(half, locmc); s = s.add(x.divide(s, locmc)).divide(half, locmc);
/* debugging */ /* debugging */
// System.out.println("itr "+x.round(locmc).toString() + " " + // System.out.println("itr "+x.round(locmc).toString() + " " +
@ -177,8 +181,9 @@ public class BigDecimalMath {
* @since 2009-06-25 * @since 2009-06-25
*/ */
static public BigDecimal sqrt(final BigDecimal x) { static public BigDecimal sqrt(final BigDecimal x) {
if (x.compareTo(BigDecimal.ZERO) < 0) if (x.compareTo(BigDecimal.ZERO) < 0) {
throw new ArithmeticException("negative argument " + x.toString() + " of square root"); throw new ArithmeticException("negative argument " + x.toString() + " of square root");
}
return BigDecimalMath.root(2, x); return BigDecimalMath.root(2, x);
} /* BigDecimalMath.sqrt */ } /* BigDecimalMath.sqrt */
@ -194,10 +199,11 @@ public class BigDecimalMath {
* @since 2009-08-16 * @since 2009-08-16
*/ */
static public BigDecimal cbrt(final BigDecimal x) { static public BigDecimal cbrt(final BigDecimal x) {
if (x.compareTo(BigDecimal.ZERO) < 0) if (x.compareTo(BigDecimal.ZERO) < 0) {
return BigDecimalMath.root(3, x.negate()).negate(); return BigDecimalMath.root(3, x.negate()).negate();
else } else {
return BigDecimalMath.root(3, x); return BigDecimalMath.root(3, x);
}
} /* BigDecimalMath.cbrt */ } /* BigDecimalMath.cbrt */
/** /**
@ -212,13 +218,16 @@ public class BigDecimalMath {
* @since 2009-07-30 * @since 2009-07-30
*/ */
static public BigDecimal root(final int n, final BigDecimal x) { static public BigDecimal root(final int n, final BigDecimal x) {
if (x.compareTo(BigDecimal.ZERO) < 0) if (x.compareTo(BigDecimal.ZERO) < 0) {
throw new ArithmeticException("negative argument " + x.toString() + " of root"); throw new ArithmeticException("negative argument " + x.toString() + " of root");
if (n <= 0) }
if (n <= 0) {
throw new ArithmeticException("negative power " + n + " of root"); throw new ArithmeticException("negative power " + n + " of root");
}
if (n == 1) if (n == 1) {
return x; return x;
}
/* start the computation from a double precision estimate */ /* start the computation from a double precision estimate */
BigDecimal s = new BigDecimal(Math.pow(x.doubleValue(), 1.0 / n)); BigDecimal s = new BigDecimal(Math.pow(x.doubleValue(), 1.0 / n));
@ -251,8 +260,9 @@ public class BigDecimalMath {
final MathContext locmc = SafeMathContext.newMathContext(c.precision()); final MathContext locmc = SafeMathContext.newMathContext(c.precision());
c = c.divide(nth, locmc); c = c.divide(nth, locmc);
s = s.subtract(c); s = s.subtract(c);
if (Math.abs(c.doubleValue() / s.doubleValue()) < eps) if (Math.abs(c.doubleValue() / s.doubleValue()) < eps) {
break; break;
}
} }
return s.round(SafeMathContext.newMathContext(BigDecimalMath.err2prec(eps))); return s.round(SafeMathContext.newMathContext(BigDecimalMath.err2prec(eps)));
} /* BigDecimalMath.root */ } /* BigDecimalMath.root */
@ -367,14 +377,14 @@ public class BigDecimalMath {
*/ */
final MathContext mc = SafeMathContext.newMathContext(invx.precision()); final MathContext mc = SafeMathContext.newMathContext(invx.precision());
return BigDecimal.ONE.divide(invx, mc); return BigDecimal.ONE.divide(invx, mc);
} else if (x.compareTo(BigDecimal.ZERO) == 0) } else if (x.compareTo(BigDecimal.ZERO) == 0) {
/* /*
* recover the valid number of digits from x.ulp(), if x hits the * recover the valid number of digits from x.ulp(), if x hits the
* zero. The x.precision() is 1 then, and does not provide this * zero. The x.precision() is 1 then, and does not provide this
* information. * information.
*/ */
return BigDecimalMath.scalePrec(BigDecimal.ONE, -(int) Math.log10(x.ulp().doubleValue())); return BigDecimalMath.scalePrec(BigDecimal.ONE, -(int) Math.log10(x.ulp().doubleValue()));
else { } else {
/* /*
* Push the number in the Taylor expansion down to a small * Push the number in the Taylor expansion down to a small
* value where TAYLOR_NTERM terms will do. If x<1, the n-th term is * value where TAYLOR_NTERM terms will do. If x<1, the n-th term is
@ -416,8 +426,9 @@ public class BigDecimalMath {
xpowi = xpowi.multiply(x); xpowi = xpowi.multiply(x);
final BigDecimal c = xpowi.divide(new BigDecimal(ifac), mcTay); final BigDecimal c = xpowi.divide(new BigDecimal(ifac), mcTay);
resul = resul.add(c); resul = resul.add(c);
if (Math.abs(xpowi.doubleValue()) < i && Math.abs(c.doubleValue()) < 0.5 * xUlpDbl) if (Math.abs(xpowi.doubleValue()) < i && Math.abs(c.doubleValue()) < 0.5 * xUlpDbl) {
break; break;
}
} }
/* /*
* exp(x+deltax) = exp(x)(1+deltax) if deltax is <<1. So the * exp(x+deltax) = exp(x)(1+deltax) if deltax is <<1. So the
@ -454,8 +465,9 @@ public class BigDecimalMath {
exSc -= exsub; exSc -= exsub;
final MathContext mctmp = SafeMathContext.newMathContext(expxby10.precision() - exsub + 2); final MathContext mctmp = SafeMathContext.newMathContext(expxby10.precision() - exsub + 2);
int pex = 1; int pex = 1;
while (exsub-- > 0) while (exsub-- > 0) {
pex *= 10; pex *= 10;
}
expxby10 = expxby10.pow(pex, mctmp); expxby10 = expxby10.pow(pex, mctmp);
} }
return expxby10.round(mc); return expxby10.round(mc);
@ -473,9 +485,9 @@ public class BigDecimalMath {
*/ */
static public BigDecimal exp(final MathContext mc) { static public BigDecimal exp(final MathContext mc) {
/* look it up if possible */ /* look it up if possible */
if (mc.getPrecision() < BigDecimalMath.E.precision()) if (mc.getPrecision() < BigDecimalMath.E.precision()) {
return BigDecimalMath.E.round(mc); return BigDecimalMath.E.round(mc);
else { } else {
/* /*
* Instantiate a 1.0 with the requested pseudo-accuracy * Instantiate a 1.0 with the requested pseudo-accuracy
* and delegate the computation to the public method above. * and delegate the computation to the public method above.
@ -500,12 +512,12 @@ public class BigDecimalMath {
/* /*
* the value is undefined if x is negative. * the value is undefined if x is negative.
*/ */
if (x.compareTo(BigDecimal.ZERO) < 0) if (x.compareTo(BigDecimal.ZERO) < 0) {
throw new ArithmeticException("Cannot take log of negative " + x.toString()); throw new ArithmeticException("Cannot take log of negative " + x.toString());
else if (x.compareTo(BigDecimal.ONE) == 0) } else if (x.compareTo(BigDecimal.ONE) == 0) {
/* log 1. = 0. */ /* log 1. = 0. */
return BigDecimalMath.scalePrec(BigDecimal.ZERO, x.precision() - 1); return BigDecimalMath.scalePrec(BigDecimal.ZERO, x.precision() - 1);
else if (Math.abs(x.doubleValue() - 1.0) <= 0.3) { } else if (Math.abs(x.doubleValue() - 1.0) <= 0.3) {
/* /*
* The standard Taylor series around x=1, z=0, z=x-1. * The standard Taylor series around x=1, z=0, z=x-1.
* Abramowitz-Stegun 4.124. * Abramowitz-Stegun 4.124.
@ -518,12 +530,14 @@ public class BigDecimalMath {
for (int k = 2;; k++) { for (int k = 2;; k++) {
zpown = BigDecimalMath.multiplyRound(zpown, z); zpown = BigDecimalMath.multiplyRound(zpown, z);
final BigDecimal c = BigDecimalMath.divideRound(zpown, k); final BigDecimal c = BigDecimalMath.divideRound(zpown, k);
if (k % 2 == 0) if (k % 2 == 0) {
resul = resul.subtract(c); resul = resul.subtract(c);
else } else {
resul = resul.add(c); resul = resul.add(c);
if (Math.abs(c.doubleValue()) < eps) }
if (Math.abs(c.doubleValue()) < eps) {
break; break;
}
} }
final MathContext mc = SafeMathContext.newMathContext(BigDecimalMath.err2prec(resul.doubleValue(), eps)); final MathContext mc = SafeMathContext.newMathContext(BigDecimalMath.err2prec(resul.doubleValue(), eps));
return resul.round(mc); return resul.round(mc);
@ -580,14 +594,14 @@ public class BigDecimalMath {
/* /*
* the value is undefined if x is negative. * the value is undefined if x is negative.
*/ */
if (n <= 0) if (n <= 0) {
throw new ArithmeticException("Cannot take log of negative " + n); throw new ArithmeticException("Cannot take log of negative " + n);
else if (n == 1) } else if (n == 1) {
return BigDecimal.ZERO; return BigDecimal.ZERO;
else if (n == 2) { } else if (n == 2) {
if (mc.getPrecision() < BigDecimalMath.LOG2.precision()) if (mc.getPrecision() < BigDecimalMath.LOG2.precision()) {
return BigDecimalMath.LOG2.round(mc); return BigDecimalMath.LOG2.round(mc);
else { } else {
/* /*
* Broadhurst <a * Broadhurst <a
* href="http://arxiv.org/abs/math/9803067">arXiv:math/9803067</ * href="http://arxiv.org/abs/math/9803067">arXiv:math/9803067</
@ -625,18 +639,20 @@ public class BigDecimalMath {
Rational pk = new Rational(7153, 524288); Rational pk = new Rational(7153, 524288);
for (int k = 1;; k++) { for (int k = 1;; k++) {
final Rational tmp = pk.divide(k); final Rational tmp = pk.divide(k);
if (tmp.doubleValue() < eps) if (tmp.doubleValue() < eps) {
break; break;
}
/* /*
* how many digits of tmp do we need in the sum? * how many digits of tmp do we need in the sum?
*/ */
mcloc = SafeMathContext.newMathContext(BigDecimalMath.err2prec(tmp.doubleValue(), eps)); mcloc = SafeMathContext.newMathContext(BigDecimalMath.err2prec(tmp.doubleValue(), eps));
final BigDecimal c = pk.divide(k).BigDecimalValue(mcloc); final BigDecimal c = pk.divide(k).BigDecimalValue(mcloc);
if (k % 2 != 0) if (k % 2 != 0) {
log3 = log3.add(c); log3 = log3.add(c);
else } else {
log3 = log3.subtract(c); log3 = log3.subtract(c);
}
pk = pk.multiply(r); pk = pk.multiply(r);
} }
log3 = BigDecimalMath.divideRound(log3, 12); log3 = BigDecimalMath.divideRound(log3, 12);
@ -665,8 +681,9 @@ public class BigDecimalMath {
Rational pk = new Rational(759, 16384); Rational pk = new Rational(759, 16384);
for (int k = 1;; k++) { for (int k = 1;; k++) {
final Rational tmp = pk.divide(k); final Rational tmp = pk.divide(k);
if (tmp.doubleValue() < eps) if (tmp.doubleValue() < eps) {
break; break;
}
/* /*
* how many digits of tmp do we need in the sum? * how many digits of tmp do we need in the sum?
@ -699,8 +716,9 @@ public class BigDecimalMath {
Rational pk = new Rational(1, 8); Rational pk = new Rational(1, 8);
for (int k = 1;; k++) { for (int k = 1;; k++) {
final Rational tmp = pk.divide(k); final Rational tmp = pk.divide(k);
if (tmp.doubleValue() < eps) if (tmp.doubleValue() < eps) {
break; break;
}
/* /*
* how many digits of tmp do we need in the sum? * how many digits of tmp do we need in the sum?
@ -760,11 +778,11 @@ public class BigDecimalMath {
/* /*
* the value is undefined if x is negative. * the value is undefined if x is negative.
*/ */
if (r.compareTo(Rational.ZERO) <= 0) if (r.compareTo(Rational.ZERO) <= 0) {
throw new ArithmeticException("Cannot take log of negative " + r.toString()); throw new ArithmeticException("Cannot take log of negative " + r.toString());
else if (r.compareTo(Rational.ONE) == 0) } else if (r.compareTo(Rational.ONE) == 0) {
return BigDecimal.ZERO; return BigDecimal.ZERO;
else { } else {
/* /*
* log(r+epsr) = log(r)+epsr/r. Convert the precision to an absolute * log(r+epsr) = log(r)+epsr/r. Convert the precision to an absolute
@ -799,11 +817,11 @@ public class BigDecimalMath {
* @since 2009-06-01 * @since 2009-06-01
*/ */
static public BigDecimal pow(final BigDecimal x, final BigDecimal y) { static public BigDecimal pow(final BigDecimal x, final BigDecimal y) {
if (x.compareTo(BigDecimal.ZERO) < 0) if (x.compareTo(BigDecimal.ZERO) < 0) {
throw new ArithmeticException("Cannot power negative " + x.toString()); throw new ArithmeticException("Cannot power negative " + x.toString());
else if (x.compareTo(BigDecimal.ZERO) == 0) } else if (x.compareTo(BigDecimal.ZERO) == 0) {
return BigDecimal.ZERO; return BigDecimal.ZERO;
else { } else {
/* /*
* return x^y = exp(y*log(x)) ; * return x^y = exp(y*log(x)) ;
*/ */
@ -836,11 +854,11 @@ public class BigDecimalMath {
/** /**
* Special cases: x^1=x and x^0 = 1 * Special cases: x^1=x and x^0 = 1
*/ */
if (n == 1) if (n == 1) {
return x; return x;
else if (n == 0) } else if (n == 0) {
return BigDecimal.ONE; return BigDecimal.ONE;
else { } else {
/* /*
* The relative error in the result is n times the relative error in * The relative error in the result is n times the relative error in
* the input. * the input.
@ -850,10 +868,11 @@ public class BigDecimalMath {
* split the algorithm. * split the algorithm.
*/ */
final MathContext mc = SafeMathContext.newMathContext(x.precision() - (int) Math.log10(Math.abs(n))); final MathContext mc = SafeMathContext.newMathContext(x.precision() - (int) Math.log10(Math.abs(n)));
if (n > 0) if (n > 0) {
return x.pow(n, mc); return x.pow(n, mc);
else } else {
return BigDecimal.ONE.divide(x.pow(-n), mc); return BigDecimal.ONE.divide(x.pow(-n), mc);
}
} }
} /* BigDecimalMath.powRound */ } /* BigDecimalMath.powRound */
@ -876,10 +895,11 @@ public class BigDecimalMath {
* implemented to decompose larger powers into cascaded calls to smaller * implemented to decompose larger powers into cascaded calls to smaller
* ones. * ones.
*/ */
if (n.compareTo(Rational.MAX_INT) > 0 || n.compareTo(Rational.MIN_INT) < 0) if (n.compareTo(Rational.MAX_INT) > 0 || n.compareTo(Rational.MIN_INT) < 0) {
throw new ProviderException("Not implemented: big power " + n.toString()); throw new ProviderException("Not implemented: big power " + n.toString());
else } else {
return BigDecimalMath.powRound(x, n.intValue()); return BigDecimalMath.powRound(x, n.intValue());
}
} /* BigDecimalMath.powRound */ } /* BigDecimalMath.powRound */
/** /**
@ -900,20 +920,20 @@ public class BigDecimalMath {
/** /**
* Special cases: x^1=x and x^0 = 1 * Special cases: x^1=x and x^0 = 1
*/ */
if (q.compareTo(BigInteger.ONE) == 0) if (q.compareTo(BigInteger.ONE) == 0) {
return x; return x;
else if (q.signum() == 0) } else if (q.signum() == 0) {
return BigDecimal.ONE; return BigDecimal.ONE;
else if (q.isInteger()) } else if (q.isInteger()) {
/* /*
* We are sure that the denominator is positive here, because * We are sure that the denominator is positive here, because
* normalize() has been * normalize() has been
* called during constrution etc. * called during constrution etc.
*/ */
return BigDecimalMath.powRound(x, q.a); return BigDecimalMath.powRound(x, q.a);
else if (x.compareTo(BigDecimal.ZERO) < 0) } else if (x.compareTo(BigDecimal.ZERO) < 0) {
throw new ArithmeticException("Cannot power negative " + x.toString()); throw new ArithmeticException("Cannot power negative " + x.toString());
else if (q.isIntegerFrac()) { } else if (q.isIntegerFrac()) {
/* /*
* Newton method with first estimate in double precision. * Newton method with first estimate in double precision.
* The disadvantage of this first line here is that the result * The disadvantage of this first line here is that the result
@ -957,14 +977,14 @@ public class BigDecimalMath {
final BigDecimal err = res.multiply(reserr, MathContext.DECIMAL64); final BigDecimal err = res.multiply(reserr, MathContext.DECIMAL64);
final int precDiv = 2 + BigDecimalMath.err2prec(eps, err); final int precDiv = 2 + BigDecimalMath.err2prec(eps, err);
if (precDiv <= 0) if (precDiv <= 0) {
/* /*
* The case when the precision is already reached and * The case when the precision is already reached and
* any precision * any precision
* will do. * will do.
*/ */
eps = nu.divide(de, MathContext.DECIMAL32); eps = nu.divide(de, MathContext.DECIMAL32);
else { } else {
final MathContext mc = SafeMathContext.newMathContext(precDiv); final MathContext mc = SafeMathContext.newMathContext(precDiv);
eps = nu.divide(de, mc); eps = nu.divide(de, mc);
} }
@ -1013,11 +1033,11 @@ public class BigDecimalMath {
* @since 2009-06-01 * @since 2009-06-01
*/ */
static public BigDecimal sin(final BigDecimal x) throws Error { static public BigDecimal sin(final BigDecimal x) throws Error {
if (x.compareTo(BigDecimal.ZERO) < 0) if (x.compareTo(BigDecimal.ZERO) < 0) {
return BigDecimalMath.sin(x.negate()).negate(); return BigDecimalMath.sin(x.negate()).negate();
else if (x.compareTo(BigDecimal.ZERO) == 0) } else if (x.compareTo(BigDecimal.ZERO) == 0) {
return BigDecimal.ZERO; return BigDecimal.ZERO;
else { } else {
/* /*
* reduce modulo 2pi * reduce modulo 2pi
*/ */
@ -1026,27 +1046,27 @@ public class BigDecimalMath {
MathContext mc = SafeMathContext.newMathContext(2 + BigDecimalMath.err2prec(3.14159, errpi)); MathContext mc = SafeMathContext.newMathContext(2 + BigDecimalMath.err2prec(3.14159, errpi));
final BigDecimal p = BigDecimalMath.pi(mc); final BigDecimal p = BigDecimalMath.pi(mc);
mc = SafeMathContext.newMathContext(x.precision()); mc = SafeMathContext.newMathContext(x.precision());
if (res.compareTo(p) > 0) if (res.compareTo(p) > 0) {
/* /*
* pi<x<=2pi: sin(x)= - sin(x-pi) * pi<x<=2pi: sin(x)= - sin(x-pi)
*/ */
return BigDecimalMath.sin(BigDecimalMath.subtractRound(res, p)).negate(); return BigDecimalMath.sin(BigDecimalMath.subtractRound(res, p)).negate();
else if (res.multiply(new BigDecimal("2")).compareTo(p) > 0) } else if (res.multiply(new BigDecimal("2")).compareTo(p) > 0) {
/* /*
* pi/2<x<=pi: sin(x)= sin(pi-x) * pi/2<x<=pi: sin(x)= sin(pi-x)
*/ */
return BigDecimalMath.sin(BigDecimalMath.subtractRound(p, res)); return BigDecimalMath.sin(BigDecimalMath.subtractRound(p, res));
else /* } else /*
* for the range 0<=x<Pi/2 one could use sin(2x)=2sin(x)cos(x) * for the range 0<=x<Pi/2 one could use sin(2x)=2sin(x)cos(x)
* to split this further. Here, use the sine up to pi/4 and the * to split this further. Here, use the sine up to pi/4 and the
* cosine higher up. * cosine higher up.
*/ */
if (res.multiply(new BigDecimal("4")).compareTo(p) > 0) if (res.multiply(new BigDecimal("4")).compareTo(p) > 0) {
/* /*
* x>pi/4: sin(x) = cos(pi/2-x) * x>pi/4: sin(x) = cos(pi/2-x)
*/ */
return BigDecimalMath.cos(BigDecimalMath.subtractRound(p.divide(new BigDecimal("2")), res)); return BigDecimalMath.cos(BigDecimalMath.subtractRound(p.divide(new BigDecimal("2")), res));
else { } else {
/* /*
* Simple Taylor expansion, sum_{i=1..infinity} * Simple Taylor expansion, sum_{i=1..infinity}
* (-1)^(..)res^(2i+1)/(2i+1)! * (-1)^(..)res^(2i+1)/(2i+1)!
@ -1083,8 +1103,9 @@ public class BigDecimalMath {
xpowi = xpowi.multiply(res).multiply(res).negate(); xpowi = xpowi.multiply(res).multiply(res).negate();
final BigDecimal corr = xpowi.divide(new BigDecimal(ifac), mcTay); final BigDecimal corr = xpowi.divide(new BigDecimal(ifac), mcTay);
resul = resul.add(corr); resul = resul.add(corr);
if (corr.abs().doubleValue() < 0.5 * xUlpDbl) if (corr.abs().doubleValue() < 0.5 * xUlpDbl) {
break; break;
}
} }
/* /*
* The error in the result is set by the error in x itself. * The error in the result is set by the error in x itself.
@ -1105,11 +1126,11 @@ public class BigDecimalMath {
* @since 2009-06-01 * @since 2009-06-01
*/ */
static public BigDecimal cos(final BigDecimal x) throws Error { static public BigDecimal cos(final BigDecimal x) throws Error {
if (x.compareTo(BigDecimal.ZERO) < 0) if (x.compareTo(BigDecimal.ZERO) < 0) {
return BigDecimalMath.cos(x.negate()); return BigDecimalMath.cos(x.negate());
else if (x.compareTo(BigDecimal.ZERO) == 0) } else if (x.compareTo(BigDecimal.ZERO) == 0) {
return BigDecimal.ONE; return BigDecimal.ONE;
else { } else {
/* /*
* reduce modulo 2pi * reduce modulo 2pi
*/ */
@ -1118,28 +1139,28 @@ public class BigDecimalMath {
MathContext mc = SafeMathContext.newMathContext(2 + BigDecimalMath.err2prec(3.14159, errpi)); MathContext mc = SafeMathContext.newMathContext(2 + BigDecimalMath.err2prec(3.14159, errpi));
final BigDecimal p = BigDecimalMath.pi(mc); final BigDecimal p = BigDecimalMath.pi(mc);
mc = SafeMathContext.newMathContext(x.precision()); mc = SafeMathContext.newMathContext(x.precision());
if (res.compareTo(p) > 0) if (res.compareTo(p) > 0) {
/* /*
* pi<x<=2pi: cos(x)= - cos(x-pi) * pi<x<=2pi: cos(x)= - cos(x-pi)
*/ */
return BigDecimalMath.cos(BigDecimalMath.subtractRound(res, p)).negate(); return BigDecimalMath.cos(BigDecimalMath.subtractRound(res, p)).negate();
else if (res.multiply(new BigDecimal("2")).compareTo(p) > 0) } else if (res.multiply(new BigDecimal("2")).compareTo(p) > 0) {
/* /*
* pi/2<x<=pi: cos(x)= -cos(pi-x) * pi/2<x<=pi: cos(x)= -cos(pi-x)
*/ */
return BigDecimalMath.cos(BigDecimalMath.subtractRound(p, res)).negate(); return BigDecimalMath.cos(BigDecimalMath.subtractRound(p, res)).negate();
else /* } else /*
* for the range 0<=x<Pi/2 one could use cos(2x)= 1-2*sin^2(x) * for the range 0<=x<Pi/2 one could use cos(2x)= 1-2*sin^2(x)
* to split this further, or use the cos up to pi/4 and the sine * to split this further, or use the cos up to pi/4 and the sine
* higher up. * higher up.
* throw new ProviderException("Not implemented: cosine ") ; * throw new ProviderException("Not implemented: cosine ") ;
*/ */
if (res.multiply(new BigDecimal("4")).compareTo(p) > 0) if (res.multiply(new BigDecimal("4")).compareTo(p) > 0) {
/* /*
* x>pi/4: cos(x) = sin(pi/2-x) * x>pi/4: cos(x) = sin(pi/2-x)
*/ */
return BigDecimalMath.sin(BigDecimalMath.subtractRound(p.divide(new BigDecimal("2")), res)); return BigDecimalMath.sin(BigDecimalMath.subtractRound(p.divide(new BigDecimal("2")), res));
else { } else {
/* /*
* Simple Taylor expansion, sum_{i=0..infinity} * Simple Taylor expansion, sum_{i=0..infinity}
* (-1)^(..)res^(2i)/(2i)! * (-1)^(..)res^(2i)/(2i)!
@ -1176,8 +1197,9 @@ public class BigDecimalMath {
xpowi = xpowi.multiply(res).multiply(res).negate(); xpowi = xpowi.multiply(res).multiply(res).negate();
final BigDecimal corr = xpowi.divide(new BigDecimal(ifac), mcTay); final BigDecimal corr = xpowi.divide(new BigDecimal(ifac), mcTay);
resul = resul.add(corr); resul = resul.add(corr);
if (corr.abs().doubleValue() < 0.5 * xUlpDbl) if (corr.abs().doubleValue() < 0.5 * xUlpDbl) {
break; break;
}
} }
/* /*
* The error in the result is governed by the error in x * The error in the result is governed by the error in x
@ -1198,11 +1220,11 @@ public class BigDecimalMath {
* @throws Error * @throws Error
*/ */
static public BigDecimal tan(final BigDecimal x) throws Error { static public BigDecimal tan(final BigDecimal x) throws Error {
if (x.compareTo(BigDecimal.ZERO) == 0) if (x.compareTo(BigDecimal.ZERO) == 0) {
return BigDecimal.ZERO; return BigDecimal.ZERO;
else if (x.compareTo(BigDecimal.ZERO) < 0) } else if (x.compareTo(BigDecimal.ZERO) < 0) {
return BigDecimalMath.tan(x.negate()).negate(); return BigDecimalMath.tan(x.negate()).negate();
else { } else {
/* /*
* reduce modulo pi * reduce modulo pi
*/ */
@ -1244,8 +1266,9 @@ public class BigDecimalMath {
xpowi = BigDecimalMath.multiplyRound(xpowi, xhighprSq); xpowi = BigDecimalMath.multiplyRound(xpowi, xhighprSq);
final BigDecimal c = BigDecimalMath.multiplyRound(xpowi, f); final BigDecimal c = BigDecimalMath.multiplyRound(xpowi, f);
resul = resul.add(c); resul = resul.add(c);
if (Math.abs(c.doubleValue()) < 0.1 * eps) if (Math.abs(c.doubleValue()) < 0.1 * eps) {
break; break;
}
} }
final MathContext mc = SafeMathContext.newMathContext(BigDecimalMath.err2prec(resul.doubleValue(), eps)); final MathContext mc = SafeMathContext.newMathContext(BigDecimalMath.err2prec(resul.doubleValue(), eps));
return resul.round(mc); return resul.round(mc);
@ -1263,11 +1286,11 @@ public class BigDecimalMath {
* @since 2009-07-31 * @since 2009-07-31
*/ */
static public BigDecimal cot(final BigDecimal x) throws Error { static public BigDecimal cot(final BigDecimal x) throws Error {
if (x.compareTo(BigDecimal.ZERO) == 0) if (x.compareTo(BigDecimal.ZERO) == 0) {
throw new ArithmeticException("Cannot take cot of zero " + x.toString()); throw new ArithmeticException("Cannot take cot of zero " + x.toString());
else if (x.compareTo(BigDecimal.ZERO) < 0) } else if (x.compareTo(BigDecimal.ZERO) < 0) {
return BigDecimalMath.cot(x.negate()).negate(); return BigDecimalMath.cot(x.negate()).negate();
else { } else {
/* /*
* reduce modulo pi * reduce modulo pi
*/ */
@ -1301,12 +1324,14 @@ public class BigDecimalMath {
fac = fac.multiply(new BigInteger("" + 2 * i)).multiply(new BigInteger("" + (2 * i - 1))); fac = fac.multiply(new BigInteger("" + 2 * i)).multiply(new BigInteger("" + (2 * i - 1)));
f = f.multiply(fourn).divide(fac); f = f.multiply(fourn).divide(fac);
final BigDecimal c = BigDecimalMath.multiplyRound(xpowi, f); final BigDecimal c = BigDecimalMath.multiplyRound(xpowi, f);
if (i % 2 == 0) if (i % 2 == 0) {
resul = resul.add(c); resul = resul.add(c);
else } else {
resul = resul.subtract(c); resul = resul.subtract(c);
if (Math.abs(c.doubleValue()) < 0.1 * eps) }
if (Math.abs(c.doubleValue()) < 0.1 * eps) {
break; break;
}
fourn = fourn.shiftLeft(2); fourn = fourn.shiftLeft(2);
xpowi = BigDecimalMath.multiplyRound(xpowi, xhighprSq); xpowi = BigDecimalMath.multiplyRound(xpowi, xhighprSq);
@ -1325,20 +1350,20 @@ public class BigDecimalMath {
* @throws Error * @throws Error
*/ */
static public BigDecimal asin(final BigDecimal x) throws Error { static public BigDecimal asin(final BigDecimal x) throws Error {
if (x.compareTo(BigDecimal.ONE) > 0 || x.compareTo(BigDecimal.ONE.negate()) < 0) if (x.compareTo(BigDecimal.ONE) > 0 || x.compareTo(BigDecimal.ONE.negate()) < 0) {
throw new ArithmeticException("Out of range argument " + x.toString() + " of asin"); throw new ArithmeticException("Out of range argument " + x.toString() + " of asin");
else if (x.compareTo(BigDecimal.ZERO) == 0) } else if (x.compareTo(BigDecimal.ZERO) == 0) {
return BigDecimal.ZERO; return BigDecimal.ZERO;
else if (x.compareTo(BigDecimal.ONE) == 0) { } else if (x.compareTo(BigDecimal.ONE) == 0) {
/* /*
* arcsin(1) = pi/2 * arcsin(1) = pi/2
*/ */
final double errpi = Math.sqrt(x.ulp().doubleValue()); final double errpi = Math.sqrt(x.ulp().doubleValue());
final MathContext mc = SafeMathContext.newMathContext(BigDecimalMath.err2prec(3.14159, errpi)); final MathContext mc = SafeMathContext.newMathContext(BigDecimalMath.err2prec(3.14159, errpi));
return BigDecimalMath.pi(mc).divide(new BigDecimal(2)); return BigDecimalMath.pi(mc).divide(new BigDecimal(2));
} else if (x.compareTo(BigDecimal.ZERO) < 0) } else if (x.compareTo(BigDecimal.ZERO) < 0) {
return BigDecimalMath.asin(x.negate()).negate(); return BigDecimalMath.asin(x.negate()).negate();
else if (x.doubleValue() > 0.7) { } else if (x.doubleValue() > 0.7) {
final BigDecimal xCompl = BigDecimal.ONE.subtract(x); final BigDecimal xCompl = BigDecimal.ONE.subtract(x);
final double xDbl = x.doubleValue(); final double xDbl = x.doubleValue();
final double xUlpDbl = x.ulp().doubleValue() / 2.; final double xUlpDbl = x.ulp().doubleValue() / 2.;
@ -1359,18 +1384,20 @@ public class BigDecimalMath {
for (int i = 1;; i++) { for (int i = 1;; i++) {
ifacN = ifacN.multiply(new BigInteger("" + (2 * i - 1))); ifacN = ifacN.multiply(new BigInteger("" + (2 * i - 1)));
ifacD = ifacD.multiply(new BigInteger("" + i)); ifacD = ifacD.multiply(new BigInteger("" + i));
if (i == 1) if (i == 1) {
xpowi = xhighprV; xpowi = xhighprV;
else } else {
xpowi = BigDecimalMath.multiplyRound(xpowi, xhighprV); xpowi = BigDecimalMath.multiplyRound(xpowi, xhighprV);
}
final BigDecimal c = BigDecimalMath.divideRound(BigDecimalMath.multiplyRound(xpowi, ifacN), ifacD.multiply(new BigInteger("" + (2 * i + 1)))); final BigDecimal c = BigDecimalMath.divideRound(BigDecimalMath.multiplyRound(xpowi, ifacN), ifacD.multiply(new BigInteger("" + (2 * i + 1))));
resul = resul.add(c); resul = resul.add(c);
/* /*
* series started 1+x/12+... which yields an estimate of the * series started 1+x/12+... which yields an estimate of the
* sum's error * sum's error
*/ */
if (Math.abs(c.doubleValue()) < xUlpDbl / 120.) if (Math.abs(c.doubleValue()) < xUlpDbl / 120.) {
break; break;
}
} }
/* /*
* sqrt(2*z)*(1+...) * sqrt(2*z)*(1+...)
@ -1410,8 +1437,9 @@ public class BigDecimalMath {
xpowi = BigDecimalMath.multiplyRound(xpowi, xhighprSq); xpowi = BigDecimalMath.multiplyRound(xpowi, xhighprSq);
final BigDecimal c = BigDecimalMath.divideRound(BigDecimalMath.multiplyRound(xpowi, ifacN), ifacD.multiply(new BigInteger("" + (2 * i + 1)))); final BigDecimal c = BigDecimalMath.divideRound(BigDecimalMath.multiplyRound(xpowi, ifacN), ifacD.multiply(new BigInteger("" + (2 * i + 1))));
resul = resul.add(c); resul = resul.add(c);
if (Math.abs(c.doubleValue()) < 0.1 * eps) if (Math.abs(c.doubleValue()) < 0.1 * eps) {
break; break;
}
} }
final MathContext mc = SafeMathContext.newMathContext(BigDecimalMath.err2prec(resul.doubleValue(), eps)); final MathContext mc = SafeMathContext.newMathContext(BigDecimalMath.err2prec(resul.doubleValue(), eps));
return resul.round(mc); return resul.round(mc);
@ -1462,11 +1490,11 @@ public class BigDecimalMath {
* @since 2009-08-03 * @since 2009-08-03
*/ */
static public BigDecimal atan(final BigDecimal x) throws Error { static public BigDecimal atan(final BigDecimal x) throws Error {
if (x.compareTo(BigDecimal.ZERO) < 0) if (x.compareTo(BigDecimal.ZERO) < 0) {
return BigDecimalMath.atan(x.negate()).negate(); return BigDecimalMath.atan(x.negate()).negate();
else if (x.compareTo(BigDecimal.ZERO) == 0) } else if (x.compareTo(BigDecimal.ZERO) == 0) {
return BigDecimal.ZERO; return BigDecimal.ZERO;
else if (x.doubleValue() > 0.7 && x.doubleValue() < 3.0) { } else if (x.doubleValue() > 0.7 && x.doubleValue() < 3.0) {
/* /*
* Abramowitz-Stegun 4.4.34 convergence acceleration * Abramowitz-Stegun 4.4.34 convergence acceleration
* 2*arctan(x) = arctan(2x/(1-x^2)) = arctan(y). x=(sqrt(1+y^2)-1)/y * 2*arctan(x) = arctan(2x/(1-x^2)) = arctan(y). x=(sqrt(1+y^2)-1)/y
@ -1508,8 +1536,9 @@ public class BigDecimalMath {
final BigDecimal c = BigDecimalMath.divideRound(xpowi, 2 * i + 1); final BigDecimal c = BigDecimalMath.divideRound(xpowi, 2 * i + 1);
resul = resul.add(c); resul = resul.add(c);
if (Math.abs(c.doubleValue()) < 0.1 * eps) if (Math.abs(c.doubleValue()) < 0.1 * eps) {
break; break;
}
} }
final MathContext mc = SafeMathContext.newMathContext(BigDecimalMath.err2prec(resul.doubleValue(), eps)); final MathContext mc = SafeMathContext.newMathContext(BigDecimalMath.err2prec(resul.doubleValue(), eps));
return resul.round(mc); return resul.round(mc);
@ -1540,8 +1569,9 @@ public class BigDecimalMath {
final BigDecimal c = BigDecimalMath.divideRound(xpowi, 2 * i + 1); final BigDecimal c = BigDecimalMath.divideRound(xpowi, 2 * i + 1);
resul = resul.add(c); resul = resul.add(c);
if (Math.abs(c.doubleValue()) < 0.1 * eps) if (Math.abs(c.doubleValue()) < 0.1 * eps) {
break; break;
}
xpowi = BigDecimalMath.multiplyRound(xpowi, xhighprSq); xpowi = BigDecimalMath.multiplyRound(xpowi, xhighprSq);
} }
mc = SafeMathContext.newMathContext(BigDecimalMath.err2prec(resul.doubleValue(), eps)); mc = SafeMathContext.newMathContext(BigDecimalMath.err2prec(resul.doubleValue(), eps));
@ -1560,16 +1590,16 @@ public class BigDecimalMath {
* @since 2009-08-19 * @since 2009-08-19
*/ */
static public BigDecimal cosh(final BigDecimal x) throws Error { static public BigDecimal cosh(final BigDecimal x) throws Error {
if (x.compareTo(BigDecimal.ZERO) < 0) if (x.compareTo(BigDecimal.ZERO) < 0) {
return BigDecimalMath.cos(x.negate()); return BigDecimalMath.cos(x.negate());
else if (x.compareTo(BigDecimal.ZERO) == 0) } else if (x.compareTo(BigDecimal.ZERO) == 0) {
return BigDecimal.ONE; return BigDecimal.ONE;
else if (x.doubleValue() > 1.5) } else if (x.doubleValue() > 1.5) {
/* /*
* cosh^2(x) = 1+ sinh^2(x). * cosh^2(x) = 1+ sinh^2(x).
*/ */
return BigDecimalMath.hypot(1, BigDecimalMath.sinh(x)); return BigDecimalMath.hypot(1, BigDecimalMath.sinh(x));
else { } else {
final BigDecimal xhighpr = BigDecimalMath.scalePrec(x, 2); final BigDecimal xhighpr = BigDecimalMath.scalePrec(x, 2);
/* Simple Taylor expansion, sum_{0=1..infinity} x^(2i)/(2i)! */ /* Simple Taylor expansion, sum_{0=1..infinity} x^(2i)/(2i)! */
BigDecimal resul = BigDecimal.ONE; BigDecimal resul = BigDecimal.ONE;
@ -1611,8 +1641,9 @@ public class BigDecimalMath {
xpowi = xpowi.multiply(xhighpr).multiply(xhighpr); xpowi = xpowi.multiply(xhighpr).multiply(xhighpr);
final BigDecimal corr = xpowi.divide(new BigDecimal(ifac), mcTay); final BigDecimal corr = xpowi.divide(new BigDecimal(ifac), mcTay);
resul = resul.add(corr); resul = resul.add(corr);
if (corr.abs().doubleValue() < 0.5 * xUlpDbl) if (corr.abs().doubleValue() < 0.5 * xUlpDbl) {
break; break;
}
} }
/* /*
* The error in the result is governed by the error in x itself. * The error in the result is governed by the error in x itself.
@ -1633,11 +1664,11 @@ public class BigDecimalMath {
* @since 2009-08-19 * @since 2009-08-19
*/ */
static public BigDecimal sinh(final BigDecimal x) throws Error { static public BigDecimal sinh(final BigDecimal x) throws Error {
if (x.compareTo(BigDecimal.ZERO) < 0) if (x.compareTo(BigDecimal.ZERO) < 0) {
return BigDecimalMath.sinh(x.negate()).negate(); return BigDecimalMath.sinh(x.negate()).negate();
else if (x.compareTo(BigDecimal.ZERO) == 0) } else if (x.compareTo(BigDecimal.ZERO) == 0) {
return BigDecimal.ZERO; return BigDecimal.ZERO;
else if (x.doubleValue() > 2.4) { } else if (x.doubleValue() > 2.4) {
/* /*
* Move closer to zero with sinh(2x)= 2*sinh(x)*cosh(x). * Move closer to zero with sinh(2x)= 2*sinh(x)*cosh(x).
*/ */
@ -1691,8 +1722,9 @@ public class BigDecimalMath {
xpowi = xpowi.multiply(xhighpr).multiply(xhighpr); xpowi = xpowi.multiply(xhighpr).multiply(xhighpr);
final BigDecimal corr = xpowi.divide(new BigDecimal(ifac), mcTay); final BigDecimal corr = xpowi.divide(new BigDecimal(ifac), mcTay);
resul = resul.add(corr); resul = resul.add(corr);
if (corr.abs().doubleValue() < 0.5 * xUlpDbl) if (corr.abs().doubleValue() < 0.5 * xUlpDbl) {
break; break;
}
} }
/* /*
* The error in the result is set by the error in x itself. * The error in the result is set by the error in x itself.
@ -1712,11 +1744,11 @@ public class BigDecimalMath {
* @since 2009-08-20 * @since 2009-08-20
*/ */
static public BigDecimal tanh(final BigDecimal x) { static public BigDecimal tanh(final BigDecimal x) {
if (x.compareTo(BigDecimal.ZERO) < 0) if (x.compareTo(BigDecimal.ZERO) < 0) {
return BigDecimalMath.tanh(x.negate()).negate(); return BigDecimalMath.tanh(x.negate()).negate();
else if (x.compareTo(BigDecimal.ZERO) == 0) } else if (x.compareTo(BigDecimal.ZERO) == 0) {
return BigDecimal.ZERO; return BigDecimal.ZERO;
else { } else {
final BigDecimal xhighpr = BigDecimalMath.scalePrec(x, 2); final BigDecimal xhighpr = BigDecimalMath.scalePrec(x, 2);
/* /*
@ -1743,9 +1775,9 @@ public class BigDecimalMath {
* @since 2009-08-20 * @since 2009-08-20
*/ */
static public BigDecimal asinh(final BigDecimal x) { static public BigDecimal asinh(final BigDecimal x) {
if (x.compareTo(BigDecimal.ZERO) == 0) if (x.compareTo(BigDecimal.ZERO) == 0) {
return BigDecimal.ZERO; return BigDecimal.ZERO;
else { } else {
final BigDecimal xhighpr = BigDecimalMath.scalePrec(x, 2); final BigDecimal xhighpr = BigDecimalMath.scalePrec(x, 2);
/* /*
@ -1773,11 +1805,11 @@ public class BigDecimalMath {
* @since 2009-08-20 * @since 2009-08-20
*/ */
static public BigDecimal acosh(final BigDecimal x) { static public BigDecimal acosh(final BigDecimal x) {
if (x.compareTo(BigDecimal.ONE) < 0) if (x.compareTo(BigDecimal.ONE) < 0) {
throw new ArithmeticException("Out of range argument cosh " + x.toString()); throw new ArithmeticException("Out of range argument cosh " + x.toString());
else if (x.compareTo(BigDecimal.ONE) == 0) } else if (x.compareTo(BigDecimal.ONE) == 0) {
return BigDecimal.ZERO; return BigDecimal.ZERO;
else { } else {
final BigDecimal xhighpr = BigDecimalMath.scalePrec(x, 2); final BigDecimal xhighpr = BigDecimalMath.scalePrec(x, 2);
/* /*
@ -1809,9 +1841,9 @@ public class BigDecimalMath {
* reduce to interval near 1.0 with the functional relation, * reduce to interval near 1.0 with the functional relation,
* Abramowitz-Stegun 6.1.33 * Abramowitz-Stegun 6.1.33
*/ */
if (x.compareTo(BigDecimal.ZERO) < 0) if (x.compareTo(BigDecimal.ZERO) < 0) {
return BigDecimalMath.divideRound(BigDecimalMath.Gamma(x.add(BigDecimal.ONE)), x); return BigDecimalMath.divideRound(BigDecimalMath.Gamma(x.add(BigDecimal.ONE)), x);
else if (x.doubleValue() > 1.5) { } else if (x.doubleValue() > 1.5) {
/* /*
* Gamma(x) = Gamma(xmin+n) = Gamma(xmin)*Pochhammer(xmin,n). * Gamma(x) = Gamma(xmin+n) = Gamma(xmin)*Pochhammer(xmin,n).
*/ */
@ -1868,24 +1900,27 @@ public class BigDecimalMath {
* error in zeta, because zeta is * error in zeta, because zeta is
* of the order of 1. * of the order of 1.
*/ */
if (eps / 100. / c.doubleValue() < 0.01) if (eps / 100. / c.doubleValue() < 0.01) {
m = SafeMathContext.newMathContext(BigDecimalMath.err2prec(eps / 100. / c.doubleValue())); m = SafeMathContext.newMathContext(BigDecimalMath.err2prec(eps / 100. / c.doubleValue()));
else } else {
m = SafeMathContext.newMathContext(2); m = SafeMathContext.newMathContext(2);
}
/* zeta(n) -1 */ /* zeta(n) -1 */
final BigDecimal zetm1 = BigDecimalMath.zeta(n, m).subtract(BigDecimal.ONE); final BigDecimal zetm1 = BigDecimalMath.zeta(n, m).subtract(BigDecimal.ONE);
c = BigDecimalMath.multiplyRound(c, zetm1); c = BigDecimalMath.multiplyRound(c, zetm1);
if (n % 2 == 0) if (n % 2 == 0) {
resul = resul.add(c); resul = resul.add(c);
else } else {
resul = resul.subtract(c); resul = resul.subtract(c);
}
/* /*
* alternating sum, so truncating as eps is reached suffices * alternating sum, so truncating as eps is reached suffices
*/ */
if (Math.abs(c.doubleValue()) < eps) if (Math.abs(c.doubleValue()) < eps) {
break; break;
}
} }
} }
@ -1913,9 +1948,9 @@ public class BigDecimalMath {
*/ */
static public BigDecimal Gamma(final Rational q, final MathContext mc) throws Error { static public BigDecimal Gamma(final Rational q, final MathContext mc) throws Error {
if (q.isBigInteger()) { if (q.isBigInteger()) {
if (q.compareTo(Rational.ZERO) <= 0) if (q.compareTo(Rational.ZERO) <= 0) {
throw new ArithmeticException("Gamma at " + q.toString()); throw new ArithmeticException("Gamma at " + q.toString());
else { } else {
/* Gamma(n) = (n-1)! */ /* Gamma(n) = (n-1)! */
final Factorial f = new Factorial(); final Factorial f = new Factorial();
final BigInteger g = f.at(q.trunc().intValue() - 1); final BigInteger g = f.at(q.trunc().intValue() - 1);
@ -1975,11 +2010,11 @@ public class BigDecimalMath {
* reduce to interval near 1.0 with the functional relation, * reduce to interval near 1.0 with the functional relation,
* Abramowitz-Stegun 6.1.33 * Abramowitz-Stegun 6.1.33
*/ */
if (n < 0) if (n < 0) {
throw new ProviderException("Not implemented: pochhammer with negative index " + n); throw new ProviderException("Not implemented: pochhammer with negative index " + n);
else if (n == 0) } else if (n == 0) {
return BigDecimal.ONE; return BigDecimal.ONE;
else { } else {
/* /*
* internally two safety digits * internally two safety digits
*/ */
@ -2028,10 +2063,11 @@ public class BigDecimalMath {
* with two safety digits * with two safety digits
*/ */
double err2pi; double err2pi;
if (k != 0) if (k != 0) {
err2pi = 0.25 * Math.abs(x.ulp().doubleValue() / k); err2pi = 0.25 * Math.abs(x.ulp().doubleValue() / k);
else } else {
err2pi = 0.5 * Math.abs(x.ulp().doubleValue()); err2pi = 0.5 * Math.abs(x.ulp().doubleValue());
}
MathContext mc = SafeMathContext.newMathContext(2 + BigDecimalMath.err2prec(6.283, err2pi)); MathContext mc = SafeMathContext.newMathContext(2 + BigDecimalMath.err2prec(6.283, err2pi));
final BigDecimal twopi = BigDecimalMath.pi(mc).multiply(new BigDecimal(2)); final BigDecimal twopi = BigDecimalMath.pi(mc).multiply(new BigDecimal(2));
@ -2041,8 +2077,9 @@ public class BigDecimalMath {
* a negative value of x was negative . * a negative value of x was negative .
*/ */
BigDecimal res = x.remainder(twopi); BigDecimal res = x.remainder(twopi);
if (res.compareTo(BigDecimal.ZERO) < 0) if (res.compareTo(BigDecimal.ZERO) < 0) {
res = res.add(twopi); res = res.add(twopi);
}
/* /*
* The actual precision is set by the input value, its absolute value of * The actual precision is set by the input value, its absolute value of
@ -2077,10 +2114,11 @@ public class BigDecimalMath {
* two safety digits * two safety digits
*/ */
double errpi; double errpi;
if (k != 0) if (k != 0) {
errpi = 0.5 * Math.abs(x.ulp().doubleValue() / k); errpi = 0.5 * Math.abs(x.ulp().doubleValue() / k);
else } else {
errpi = 0.5 * Math.abs(x.ulp().doubleValue()); errpi = 0.5 * Math.abs(x.ulp().doubleValue());
}
MathContext mc = SafeMathContext.newMathContext(2 + BigDecimalMath.err2prec(3.1416, errpi)); MathContext mc = SafeMathContext.newMathContext(2 + BigDecimalMath.err2prec(3.1416, errpi));
final BigDecimal onepi = BigDecimalMath.pi(mc); final BigDecimal onepi = BigDecimalMath.pi(mc);
final BigDecimal pihalf = onepi.divide(new BigDecimal(2)); final BigDecimal pihalf = onepi.divide(new BigDecimal(2));
@ -2091,10 +2129,11 @@ public class BigDecimalMath {
* a negative value of x was negative . * a negative value of x was negative .
*/ */
BigDecimal res = x.remainder(onepi); BigDecimal res = x.remainder(onepi);
if (res.compareTo(pihalf) > 0) if (res.compareTo(pihalf) > 0) {
res = res.subtract(onepi); res = res.subtract(onepi);
else if (res.compareTo(pihalf.negate()) < 0) } else if (res.compareTo(pihalf.negate()) < 0) {
res = res.add(onepi); res = res.add(onepi);
}
/* /*
* The actual precision is set by the input value, its absolute value of * The actual precision is set by the input value, its absolute value of
@ -2116,10 +2155,12 @@ public class BigDecimalMath {
* @since 2009-08-05 * @since 2009-08-05
*/ */
static public BigDecimal zeta(final int n, final MathContext mc) throws Error { static public BigDecimal zeta(final int n, final MathContext mc) throws Error {
if (n <= 0) if (n <= 0) {
throw new ProviderException("Not implemented: zeta at negative argument " + n); throw new ProviderException("Not implemented: zeta at negative argument " + n);
if (n == 1) }
if (n == 1) {
throw new ArithmeticException("Pole at zeta(1) "); throw new ArithmeticException("Pole at zeta(1) ");
}
if (n % 2 == 0) { if (n % 2 == 0) {
/* /*
@ -2186,10 +2227,11 @@ public class BigDecimalMath {
Rational b = bern.at(2 * npr).multiply(bern.at(n + 1 - 2 * npr)); Rational b = bern.at(2 * npr).multiply(bern.at(n + 1 - 2 * npr));
b = b.divide(fact.at(2 * npr)).divide(fact.at(n + 1 - 2 * npr)); b = b.divide(fact.at(2 * npr)).divide(fact.at(n + 1 - 2 * npr));
b = b.multiply(1 - 2 * npr); b = b.multiply(1 - 2 * npr);
if (npr % 2 == 0) if (npr % 2 == 0) {
betsum = betsum.add(b); betsum = betsum.add(b);
else } else {
betsum = betsum.subtract(b); betsum = betsum.subtract(b);
}
} }
betsum = betsum.divide(n - 1); betsum = betsum.divide(n - 1);
/* /*
@ -2303,15 +2345,17 @@ public class BigDecimalMath {
* precomputed static table in double precision * precomputed static table in double precision
*/ */
final double[] zmin1 = { 0., 0., 6.449340668482264364724151666e-01, 2.020569031595942853997381615e-01, 8.232323371113819151600369654e-02, 3.692775514336992633136548646e-02, 1.734306198444913971451792979e-02, 8.349277381922826839797549850e-03, 4.077356197944339378685238509e-03, 2.008392826082214417852769232e-03, 9.945751278180853371459589003e-04, 4.941886041194645587022825265e-04, 2.460865533080482986379980477e-04, 1.227133475784891467518365264e-04, 6.124813505870482925854510514e-05, 3.058823630702049355172851064e-05, 1.528225940865187173257148764e-05, 7.637197637899762273600293563e-06, 3.817293264999839856461644622e-06, 1.908212716553938925656957795e-06, 9.539620338727961131520386834e-07, 4.769329867878064631167196044e-07, 2.384505027277329900036481868e-07, 1.192199259653110730677887189e-07, 5.960818905125947961244020794e-08, 2.980350351465228018606370507e-08, 1.490155482836504123465850663e-08, 7.450711789835429491981004171e-09, 3.725334024788457054819204018e-09, 1.862659723513049006403909945e-09, 9.313274324196681828717647350e-10, 4.656629065033784072989233251e-10, 2.328311833676505492001455976e-10, 1.164155017270051977592973835e-10, 5.820772087902700889243685989e-11, 2.910385044497099686929425228e-11, 1.455192189104198423592963225e-11, 7.275959835057481014520869012e-12, 3.637979547378651190237236356e-12, 1.818989650307065947584832101e-12, 9.094947840263889282533118387e-13, 4.547473783042154026799112029e-13, 2.273736845824652515226821578e-13, 1.136868407680227849349104838e-13, 5.684341987627585609277182968e-14, 2.842170976889301855455073705e-14, 1.421085482803160676983430714e-14, 7.105427395210852712877354480e-15, 3.552713691337113673298469534e-15, 1.776356843579120327473349014e-15, 8.881784210930815903096091386e-16, 4.440892103143813364197770940e-16, 2.220446050798041983999320094e-16, 1.110223025141066133720544570e-16, 5.551115124845481243723736590e-17, 2.775557562136124172581632454e-17, 1.387778780972523276283909491e-17, 6.938893904544153697446085326e-18, 3.469446952165922624744271496e-18, 1.734723476047576572048972970e-18, 8.673617380119933728342055067e-19, 4.336808690020650487497023566e-19, 2.168404344997219785013910168e-19, 1.084202172494241406301271117e-19, 5.421010862456645410918700404e-20, 2.710505431223468831954621312e-20, 1.355252715610116458148523400e-20, 6.776263578045189097995298742e-21, 3.388131789020796818085703100e-21, 1.694065894509799165406492747e-21, 8.470329472546998348246992609e-22, 4.235164736272833347862270483e-22, 2.117582368136194731844209440e-22, 1.058791184068023385226500154e-22, 5.293955920339870323813912303e-23, 2.646977960169852961134116684e-23, 1.323488980084899080309451025e-23, 6.617444900424404067355245332e-24, 3.308722450212171588946956384e-24, 1.654361225106075646229923677e-24, 8.271806125530344403671105617e-25, 4.135903062765160926009382456e-25, 2.067951531382576704395967919e-25, 1.033975765691287099328409559e-25, 5.169878828456431320410133217e-26, 2.584939414228214268127761771e-26, 1.292469707114106670038112612e-26, 6.462348535570531803438002161e-27, 3.231174267785265386134814118e-27, 1.615587133892632521206011406e-27, 8.077935669463162033158738186e-28, 4.038967834731580825622262813e-28, 2.019483917365790349158762647e-28, 1.009741958682895153361925070e-28, 5.048709793414475696084771173e-29, 2.524354896707237824467434194e-29, 1.262177448353618904375399966e-29, 6.310887241768094495682609390e-30, 3.155443620884047239109841220e-30, 1.577721810442023616644432780e-30, 7.888609052210118073520537800e-31 }; final double[] zmin1 = { 0., 0., 6.449340668482264364724151666e-01, 2.020569031595942853997381615e-01, 8.232323371113819151600369654e-02, 3.692775514336992633136548646e-02, 1.734306198444913971451792979e-02, 8.349277381922826839797549850e-03, 4.077356197944339378685238509e-03, 2.008392826082214417852769232e-03, 9.945751278180853371459589003e-04, 4.941886041194645587022825265e-04, 2.460865533080482986379980477e-04, 1.227133475784891467518365264e-04, 6.124813505870482925854510514e-05, 3.058823630702049355172851064e-05, 1.528225940865187173257148764e-05, 7.637197637899762273600293563e-06, 3.817293264999839856461644622e-06, 1.908212716553938925656957795e-06, 9.539620338727961131520386834e-07, 4.769329867878064631167196044e-07, 2.384505027277329900036481868e-07, 1.192199259653110730677887189e-07, 5.960818905125947961244020794e-08, 2.980350351465228018606370507e-08, 1.490155482836504123465850663e-08, 7.450711789835429491981004171e-09, 3.725334024788457054819204018e-09, 1.862659723513049006403909945e-09, 9.313274324196681828717647350e-10, 4.656629065033784072989233251e-10, 2.328311833676505492001455976e-10, 1.164155017270051977592973835e-10, 5.820772087902700889243685989e-11, 2.910385044497099686929425228e-11, 1.455192189104198423592963225e-11, 7.275959835057481014520869012e-12, 3.637979547378651190237236356e-12, 1.818989650307065947584832101e-12, 9.094947840263889282533118387e-13, 4.547473783042154026799112029e-13, 2.273736845824652515226821578e-13, 1.136868407680227849349104838e-13, 5.684341987627585609277182968e-14, 2.842170976889301855455073705e-14, 1.421085482803160676983430714e-14, 7.105427395210852712877354480e-15, 3.552713691337113673298469534e-15, 1.776356843579120327473349014e-15, 8.881784210930815903096091386e-16, 4.440892103143813364197770940e-16, 2.220446050798041983999320094e-16, 1.110223025141066133720544570e-16, 5.551115124845481243723736590e-17, 2.775557562136124172581632454e-17, 1.387778780972523276283909491e-17, 6.938893904544153697446085326e-18, 3.469446952165922624744271496e-18, 1.734723476047576572048972970e-18, 8.673617380119933728342055067e-19, 4.336808690020650487497023566e-19, 2.168404344997219785013910168e-19, 1.084202172494241406301271117e-19, 5.421010862456645410918700404e-20, 2.710505431223468831954621312e-20, 1.355252715610116458148523400e-20, 6.776263578045189097995298742e-21, 3.388131789020796818085703100e-21, 1.694065894509799165406492747e-21, 8.470329472546998348246992609e-22, 4.235164736272833347862270483e-22, 2.117582368136194731844209440e-22, 1.058791184068023385226500154e-22, 5.293955920339870323813912303e-23, 2.646977960169852961134116684e-23, 1.323488980084899080309451025e-23, 6.617444900424404067355245332e-24, 3.308722450212171588946956384e-24, 1.654361225106075646229923677e-24, 8.271806125530344403671105617e-25, 4.135903062765160926009382456e-25, 2.067951531382576704395967919e-25, 1.033975765691287099328409559e-25, 5.169878828456431320410133217e-26, 2.584939414228214268127761771e-26, 1.292469707114106670038112612e-26, 6.462348535570531803438002161e-27, 3.231174267785265386134814118e-27, 1.615587133892632521206011406e-27, 8.077935669463162033158738186e-28, 4.038967834731580825622262813e-28, 2.019483917365790349158762647e-28, 1.009741958682895153361925070e-28, 5.048709793414475696084771173e-29, 2.524354896707237824467434194e-29, 1.262177448353618904375399966e-29, 6.310887241768094495682609390e-30, 3.155443620884047239109841220e-30, 1.577721810442023616644432780e-30, 7.888609052210118073520537800e-31 };
if (n <= 0) if (n <= 0) {
throw new ProviderException("Not implemented: zeta at negative argument " + n); throw new ProviderException("Not implemented: zeta at negative argument " + n);
if (n == 1) }
if (n == 1) {
throw new ArithmeticException("Pole at zeta(1) "); throw new ArithmeticException("Pole at zeta(1) ");
}
if (n < zmin1.length) if (n < zmin1.length) {
/* look it up if available */ /* look it up if available */
return zmin1[n]; return zmin1[n];
else { } else {
/* /*
* Result is roughly 2^(-n), desired accuracy 18 digits. If zeta(n) * Result is roughly 2^(-n), desired accuracy 18 digits. If zeta(n)
* is computed, the equivalent accuracy * is computed, the equivalent accuracy
@ -2358,8 +2402,9 @@ public class BigDecimalMath {
final int m = (int) (x - 0.5); final int m = (int) (x - 0.5);
final double xmin1 = x - m; final double xmin1 = x - m;
double resul = 0.; double resul = 0.;
for (int i = 1; i <= m; i++) for (int i = 1; i <= m; i++) {
resul += 1. / (x - i); resul += 1. / (x - i);
}
return resul + BigDecimalMath.psi(xmin1); return resul + BigDecimalMath.psi(xmin1);
} else if (Math.abs(x - psi0) < 0.55) { } else if (Math.abs(x - psi0) < 0.55) {
/* /*
@ -2368,8 +2413,9 @@ public class BigDecimalMath {
final double[] psiT0 = { 9.67672245447621170427e-01, -4.42763168983592106093e-01, 2.58499760955651010624e-01, -1.63942705442406527504e-01, 1.07824050691262365757e-01, -7.21995612564547109261e-02, 4.88042881641431072251e-02, -3.31611264748473592923e-02, 2.25976482322181046596e-02, -1.54247659049489591388e-02, 1.05387916166121753881e-02, -7.20453438635686824097e-03, 4.92678139572985344635e-03, -3.36980165543932808279e-03, 2.30512632673492783694e-03, -1.57693677143019725927e-03, 1.07882520191629658069e-03, -7.38070938996005129566e-04, 5.04953265834602035177e-04, -3.45468025106307699556e-04, 2.36356015640270527924e-04, -1.61706220919748034494e-04, 1.10633727687474109041e-04, -7.56917958219506591924e-05, 5.17857579522208086899e-05, -3.54300709476596063157e-05, 2.42400661186013176527e-05, -1.65842422718541333752e-05, 1.13463845846638498067e-05, -7.76281766846209442527e-06, 5.31106092088986338732e-06, -3.63365078980104566837e-06, 2.48602273312953794890e-06, -1.70085388543326065825e-06, 1.16366753635488427029e-06, -7.96142543124197040035e-07, 5.44694193066944527850e-07, -3.72661612834382295890e-07, 2.54962655202155425666e-07, -1.74436951177277452181e-07, 1.19343948298302427790e-07, -8.16511518948840884084e-08, 5.58629968353217144428e-08, -3.82196006191749421243e-08, 2.61485769519618662795e-08, -1.78899848649114926515e-08, 1.22397314032336619391e-08, -8.37401629767179054290e-09, 5.72922285984999377160e-09 }; final double[] psiT0 = { 9.67672245447621170427e-01, -4.42763168983592106093e-01, 2.58499760955651010624e-01, -1.63942705442406527504e-01, 1.07824050691262365757e-01, -7.21995612564547109261e-02, 4.88042881641431072251e-02, -3.31611264748473592923e-02, 2.25976482322181046596e-02, -1.54247659049489591388e-02, 1.05387916166121753881e-02, -7.20453438635686824097e-03, 4.92678139572985344635e-03, -3.36980165543932808279e-03, 2.30512632673492783694e-03, -1.57693677143019725927e-03, 1.07882520191629658069e-03, -7.38070938996005129566e-04, 5.04953265834602035177e-04, -3.45468025106307699556e-04, 2.36356015640270527924e-04, -1.61706220919748034494e-04, 1.10633727687474109041e-04, -7.56917958219506591924e-05, 5.17857579522208086899e-05, -3.54300709476596063157e-05, 2.42400661186013176527e-05, -1.65842422718541333752e-05, 1.13463845846638498067e-05, -7.76281766846209442527e-06, 5.31106092088986338732e-06, -3.63365078980104566837e-06, 2.48602273312953794890e-06, -1.70085388543326065825e-06, 1.16366753635488427029e-06, -7.96142543124197040035e-07, 5.44694193066944527850e-07, -3.72661612834382295890e-07, 2.54962655202155425666e-07, -1.74436951177277452181e-07, 1.19343948298302427790e-07, -8.16511518948840884084e-08, 5.58629968353217144428e-08, -3.82196006191749421243e-08, 2.61485769519618662795e-08, -1.78899848649114926515e-08, 1.22397314032336619391e-08, -8.37401629767179054290e-09, 5.72922285984999377160e-09 };
final double xdiff = x - psi0; final double xdiff = x - psi0;
double resul = 0.; double resul = 0.;
for (int i = psiT0.length - 1; i >= 0; i--) for (int i = psiT0.length - 1; i >= 0; i--) {
resul = resul * xdiff + psiT0[i]; resul = resul * xdiff + psiT0[i];
}
return resul * xdiff; return resul * xdiff;
} else if (x < 0.) { } else if (x < 0.) {
/* Reflection formula */ /* Reflection formula */
@ -2406,8 +2452,9 @@ public class BigDecimalMath {
* estimate. * estimate.
*/ */
double x = 0.0; double x = 0.0;
for (int k = 1; k < 10; k++) for (int k = 1; k < 10; k++) {
x += a[(k - 1) % 8] / Math.pow(2., p * (k + 1) / 2) / Math.pow(k, n); x += a[(k - 1) % 8] / Math.pow(2., p * (k + 1) / 2) / Math.pow(k, n);
}
/* /*
* Convert the relative precision and estimate of the result into an * Convert the relative precision and estimate of the result into an
@ -2441,8 +2488,9 @@ public class BigDecimalMath {
r = r.add(tmp); r = r.add(tmp);
} }
if (Math.abs(r.doubleValue()) < eps) if (Math.abs(r.doubleValue()) < eps) {
break; break;
}
final MathContext mcloc = SafeMathContext.newMathContext(1 + BigDecimalMath.err2prec(r.doubleValue(), eps)); final MathContext mcloc = SafeMathContext.newMathContext(1 + BigDecimalMath.err2prec(r.doubleValue(), eps));
res = res.add(r.BigDecimalValue(mcloc)); res = res.add(r.BigDecimalValue(mcloc));
} }
@ -2481,8 +2529,9 @@ public class BigDecimalMath {
*/ */
final double errR = Math.abs(y.ulp().doubleValue() / 2.) + Math.abs(x.ulp().doubleValue() / 2.); final double errR = Math.abs(y.ulp().doubleValue() / 2.) + Math.abs(x.ulp().doubleValue() / 2.);
int err2prec = BigDecimalMath.err2prec(resul.doubleValue(), errR); int err2prec = BigDecimalMath.err2prec(resul.doubleValue(), errR);
if (err2prec < 0) if (err2prec < 0) {
err2prec = 0; err2prec = 0;
}
final MathContext mc = SafeMathContext.newMathContext(err2prec); final MathContext mc = SafeMathContext.newMathContext(err2prec);
return resul.round(mc); return resul.round(mc);
} /* addRound */ } /* addRound */
@ -2619,9 +2668,9 @@ public class BigDecimalMath {
* @since 2009-07-30 * @since 2009-07-30
*/ */
static public BigDecimal multiplyRound(final BigDecimal x, final Rational f) { static public BigDecimal multiplyRound(final BigDecimal x, final Rational f) {
if (f.compareTo(BigInteger.ZERO) == 0) if (f.compareTo(BigInteger.ZERO) == 0) {
return BigDecimal.ZERO; return BigDecimal.ZERO;
else { } else {
/* /*
* Convert the rational value with two digits of extra precision * Convert the rational value with two digits of extra precision
*/ */
@ -2817,10 +2866,11 @@ public class BigDecimalMath {
/* /*
* catch case of real-valued denominator first * catch case of real-valued denominator first
*/ */
if (x.im.compareTo(BigDecimal.ZERO) == 0) if (x.im.compareTo(BigDecimal.ZERO) == 0) {
return new BigComplex(BigDecimalMath.divideRound(n, x.re), BigDecimal.ZERO); return new BigComplex(BigDecimalMath.divideRound(n, x.re), BigDecimal.ZERO);
else if (x.re.compareTo(BigDecimal.ZERO) == 0) } else if (x.re.compareTo(BigDecimal.ZERO) == 0) {
return new BigComplex(BigDecimal.ZERO, BigDecimalMath.divideRound(n, x.im).negate()); return new BigComplex(BigDecimal.ZERO, BigDecimalMath.divideRound(n, x.im).negate());
}
final BigComplex z = BigDecimalMath.invertRound(x); final BigComplex z = BigDecimalMath.invertRound(x);
/* /*
@ -2897,10 +2947,11 @@ public class BigDecimalMath {
*/ */
static public BigDecimal scalePrec(final BigDecimal x, final MathContext mc) { static public BigDecimal scalePrec(final BigDecimal x, final MathContext mc) {
final int diffPr = mc.getPrecision() - x.precision(); final int diffPr = mc.getPrecision() - x.precision();
if (diffPr > 0) if (diffPr > 0) {
return BigDecimalMath.scalePrec(x, diffPr); return BigDecimalMath.scalePrec(x, diffPr);
else } else {
return x; return x;
}
} /* BigDecimalMath.scalePrec */ } /* BigDecimalMath.scalePrec */
/** /**

View File

@ -23,14 +23,17 @@ public class BigIntegerMath {
* @return The binomial coefficient * @return The binomial coefficient
*/ */
static public BigInteger binomial(final int n, final int k) { static public BigInteger binomial(final int n, final int k) {
if (k == 0) if (k == 0) {
return BigInteger.ONE; return BigInteger.ONE;
}
BigInteger bin = new BigInteger("" + n); BigInteger bin = new BigInteger("" + n);
final BigInteger n2 = bin; final BigInteger n2 = bin;
for (BigInteger i = new BigInteger("" + (k - 1)); i.compareTo(BigInteger.ONE) >= 0; i = i.subtract(BigInteger.ONE)) for (BigInteger i = new BigInteger("" + (k - 1)); i.compareTo(BigInteger.ONE) >= 0; i = i.subtract(BigInteger.ONE)) {
bin = bin.multiply(n2.subtract(i)); bin = bin.multiply(n2.subtract(i));
for (BigInteger i = new BigInteger("" + k); i.compareTo(BigInteger.ONE) == 1; i = i.subtract(BigInteger.ONE)) }
for (BigInteger i = new BigInteger("" + k); i.compareTo(BigInteger.ONE) == 1; i = i.subtract(BigInteger.ONE)) {
bin = bin.divide(i); bin = bin.divide(i);
}
return bin; return bin;
} /* binomial */ } /* binomial */
@ -48,8 +51,9 @@ public class BigIntegerMath {
/* /*
* binomial(n,0) =1 * binomial(n,0) =1
*/ */
if (k.compareTo(BigInteger.ZERO) == 0) if (k.compareTo(BigInteger.ZERO) == 0) {
return BigInteger.ONE; return BigInteger.ONE;
}
BigInteger bin = new BigInteger("" + n); BigInteger bin = new BigInteger("" + n);
@ -78,8 +82,9 @@ public class BigIntegerMath {
* and in the integer domain. First replace C(n,k) by C(n,n-k) if n-k<k. * and in the integer domain. First replace C(n,k) by C(n,n-k) if n-k<k.
*/ */
BigInteger truek = new BigInteger(k.toString()); BigInteger truek = new BigInteger(k.toString());
if (n.subtract(k).compareTo(k) < 0) if (n.subtract(k).compareTo(k) < 0) {
truek = n.subtract(k); truek = n.subtract(k);
}
/* /*
* Calculate C(num,truek) where num=n and truek is the smaller of n-k * Calculate C(num,truek) where num=n and truek is the smaller of n-k
@ -170,8 +175,9 @@ public class BigIntegerMath {
* @author Richard J. Mathar * @author Richard J. Mathar
*/ */
static public int isqrt(final int n) { static public int isqrt(final int n) {
if (n < 0) if (n < 0) {
throw new ArithmeticException("Negative argument " + n); throw new ArithmeticException("Negative argument " + n);
}
final double resul = Math.sqrt(n); final double resul = Math.sqrt(n);
return (int) Math.round(resul); return (int) Math.round(resul);
} }
@ -187,8 +193,9 @@ public class BigIntegerMath {
* @author Richard J. Mathar * @author Richard J. Mathar
*/ */
static public long isqrt(final long n) { static public long isqrt(final long n) {
if (n < 0) if (n < 0) {
throw new ArithmeticException("Negative argument " + n); throw new ArithmeticException("Negative argument " + n);
}
final double resul = Math.sqrt(n); final double resul = Math.sqrt(n);
return Math.round(resul); return Math.round(resul);
} }
@ -204,16 +211,17 @@ public class BigIntegerMath {
* @author Richard J. Mathar * @author Richard J. Mathar
*/ */
static public BigInteger isqrt(final BigInteger n) { static public BigInteger isqrt(final BigInteger n) {
if (n.compareTo(BigInteger.ZERO) < 0) if (n.compareTo(BigInteger.ZERO) < 0) {
throw new ArithmeticException("Negative argument " + n.toString()); throw new ArithmeticException("Negative argument " + n.toString());
}
/* /*
* Start with an estimate from a floating point reduction. * Start with an estimate from a floating point reduction.
*/ */
BigInteger x; BigInteger x;
final int bl = n.bitLength(); final int bl = n.bitLength();
if (bl > 120) if (bl > 120) {
x = n.shiftRight(bl / 2 - 1); x = n.shiftRight(bl / 2 - 1);
else { } else {
final double resul = Math.sqrt(n.doubleValue()); final double resul = Math.sqrt(n.doubleValue());
x = new BigInteger("" + Math.round(resul)); x = new BigInteger("" + Math.round(resul));
} }
@ -225,11 +233,13 @@ public class BigIntegerMath {
*/ */
final BigInteger x2 = x.pow(2); final BigInteger x2 = x.pow(2);
BigInteger xplus2 = x.add(BigInteger.ONE).pow(2); BigInteger xplus2 = x.add(BigInteger.ONE).pow(2);
if (x2.compareTo(n) <= 0 && xplus2.compareTo(n) > 0) if (x2.compareTo(n) <= 0 && xplus2.compareTo(n) > 0) {
return x; return x;
}
xplus2 = xplus2.subtract(x.shiftLeft(2)); xplus2 = xplus2.subtract(x.shiftLeft(2));
if (xplus2.compareTo(n) <= 0 && x2.compareTo(n) > 0) if (xplus2.compareTo(n) <= 0 && x2.compareTo(n) > 0) {
return x.subtract(BigInteger.ONE); return x.subtract(BigInteger.ONE);
}
/* /*
* Newton algorithm. This correction is on the * Newton algorithm. This correction is on the
* low side caused by the integer divisions. So the value required * low side caused by the integer divisions. So the value required
@ -253,8 +263,9 @@ public class BigIntegerMath {
* @author Richard J. Mathar * @author Richard J. Mathar
*/ */
static public BigInteger core(final BigInteger n) { static public BigInteger core(final BigInteger n) {
if (n.compareTo(BigInteger.ZERO) < 0) if (n.compareTo(BigInteger.ZERO) < 0) {
throw new ArithmeticException("Negative argument " + n); throw new ArithmeticException("Negative argument " + n);
}
final Ifactor i = new Ifactor(n); final Ifactor i = new Ifactor(n);
return i.core(); return i.core();
} }
@ -280,28 +291,34 @@ public class BigIntegerMath {
static public BigInteger[][] minor(final BigInteger[][] A, final int r, final int c) throws ArithmeticException { static public BigInteger[][] minor(final BigInteger[][] A, final int r, final int c) throws ArithmeticException {
/* original row count */ /* original row count */
final int rL = A.length; final int rL = A.length;
if (rL == 0) if (rL == 0) {
throw new ArithmeticException("zero row count in matrix"); throw new ArithmeticException("zero row count in matrix");
if (r < 0 || r >= rL) }
if (r < 0 || r >= rL) {
throw new ArithmeticException("row number " + r + " out of range 0.." + (rL - 1)); throw new ArithmeticException("row number " + r + " out of range 0.." + (rL - 1));
}
/* original column count */ /* original column count */
final int cL = A[0].length; final int cL = A[0].length;
if (cL == 0) if (cL == 0) {
throw new ArithmeticException("zero column count in matrix"); throw new ArithmeticException("zero column count in matrix");
if (c < 0 || c >= cL) }
if (c < 0 || c >= cL) {
throw new ArithmeticException("column number " + c + " out of range 0.." + (cL - 1)); throw new ArithmeticException("column number " + c + " out of range 0.." + (cL - 1));
}
final BigInteger M[][] = new BigInteger[rL - 1][cL - 1]; final BigInteger M[][] = new BigInteger[rL - 1][cL - 1];
int imrow = 0; int imrow = 0;
for (int row = 0; row < rL; row++) for (int row = 0; row < rL; row++) {
if (row != r) { if (row != r) {
int imcol = 0; int imcol = 0;
for (int col = 0; col < cL; col++) for (int col = 0; col < cL; col++) {
if (col != c) { if (col != c) {
M[imrow][imcol] = A[row][col]; M[imrow][imcol] = A[row][col];
imcol++; imcol++;
} }
}
imrow++; imrow++;
} }
}
return M; return M;
} }
@ -327,26 +344,32 @@ public class BigIntegerMath {
throws ArithmeticException { throws ArithmeticException {
/* original row count */ /* original row count */
final int rL = A.length; final int rL = A.length;
if (rL == 0) if (rL == 0) {
throw new ArithmeticException("zero row count in matrix"); throw new ArithmeticException("zero row count in matrix");
}
/* original column count */ /* original column count */
final int cL = A[0].length; final int cL = A[0].length;
if (cL == 0) if (cL == 0) {
throw new ArithmeticException("zero column count in matrix"); throw new ArithmeticException("zero column count in matrix");
if (c < 0 || c >= cL) }
if (c < 0 || c >= cL) {
throw new ArithmeticException("column number " + c + " out of range 0.." + (cL - 1)); throw new ArithmeticException("column number " + c + " out of range 0.." + (cL - 1));
}
final BigInteger M[][] = new BigInteger[rL][cL]; final BigInteger M[][] = new BigInteger[rL][cL];
for (int row = 0; row < rL; row++) for (int row = 0; row < rL; row++) {
for (int col = 0; col < cL; col++) for (int col = 0; col < cL; col++) {
/* /*
* currently, v may just be longer than the row count, and * currently, v may just be longer than the row count, and
* surplus * surplus
* elements will be ignored. Shorter v lead to an exception. * elements will be ignored. Shorter v lead to an exception.
*/ */
if (col != c) if (col != c) {
M[row][col] = A[row][col]; M[row][col] = A[row][col];
else } else {
M[row][col] = v[row]; M[row][col] = v[row];
}
}
}
return M; return M;
} }
@ -365,24 +388,26 @@ public class BigIntegerMath {
BigInteger d = BigInteger.ZERO; BigInteger d = BigInteger.ZERO;
/* row size */ /* row size */
final int rL = A.length; final int rL = A.length;
if (rL == 0) if (rL == 0) {
throw new ArithmeticException("zero row count in matrix"); throw new ArithmeticException("zero row count in matrix");
}
/* column size */ /* column size */
final int cL = A[0].length; final int cL = A[0].length;
if (cL != rL) if (cL != rL) {
throw new ArithmeticException("Non-square matrix dim " + rL + " by " + cL); throw new ArithmeticException("Non-square matrix dim " + rL + " by " + cL);
}
/* /*
* Compute the low-order cases directly. * Compute the low-order cases directly.
*/ */
if (rL == 1) if (rL == 1) {
return A[0][0]; return A[0][0];
else if (rL == 2) { } else if (rL == 2) {
d = A[0][0].multiply(A[1][1]); d = A[0][0].multiply(A[1][1]);
return d.subtract(A[0][1].multiply(A[1][0])); return d.subtract(A[0][1].multiply(A[1][0]));
} else } else {
/* Work arbitrarily along the first column of the matrix */ /* Work arbitrarily along the first column of the matrix */
for (int r = 0; r < rL; r++) for (int r = 0; r < rL; r++) {
/* /*
* Do not consider minors that do no contribute anyway * Do not consider minors that do no contribute anyway
*/ */
@ -390,11 +415,14 @@ public class BigIntegerMath {
final BigInteger M[][] = BigIntegerMath.minor(A, r, 0); final BigInteger M[][] = BigIntegerMath.minor(A, r, 0);
final BigInteger m = A[r][0].multiply(BigIntegerMath.det(M)); final BigInteger m = A[r][0].multiply(BigIntegerMath.det(M));
/* recursive call */ /* recursive call */
if (r % 2 == 0) if (r % 2 == 0) {
d = d.add(m); d = d.add(m);
else } else {
d = d.subtract(m); d = d.subtract(m);
}
} }
}
}
return d; return d;
} }
@ -416,15 +444,18 @@ public class BigIntegerMath {
static public Rational[] solve(final BigInteger[][] A, final BigInteger[] rhs) throws ArithmeticException, Error { static public Rational[] solve(final BigInteger[][] A, final BigInteger[] rhs) throws ArithmeticException, Error {
final int rL = A.length; final int rL = A.length;
if (rL == 0) if (rL == 0) {
throw new ArithmeticException("zero row count in matrix"); throw new ArithmeticException("zero row count in matrix");
}
/* column size */ /* column size */
final int cL = A[0].length; final int cL = A[0].length;
if (cL != rL) if (cL != rL) {
throw new ArithmeticException("Non-square matrix dim " + rL + " by " + cL); throw new ArithmeticException("Non-square matrix dim " + rL + " by " + cL);
if (rhs.length != rL) }
if (rhs.length != rL) {
throw new ArithmeticException("Right hand side dim " + rhs.length + " unequal matrix dim " + rL); throw new ArithmeticException("Right hand side dim " + rhs.length + " unequal matrix dim " + rL);
}
/* /*
* Gauss elimination * Gauss elimination
@ -434,8 +465,9 @@ public class BigIntegerMath {
/* /*
* copy of r.h.s ito a mutable Rationalright hand side * copy of r.h.s ito a mutable Rationalright hand side
*/ */
for (int c = 0; c < cL; c++) for (int c = 0; c < cL; c++) {
x[c] = new Rational(rhs[c]); x[c] = new Rational(rhs[c]);
}
/* /*
* Create zeros downwards column c by linear combination of row c and * Create zeros downwards column c by linear combination of row c and
@ -448,7 +480,7 @@ public class BigIntegerMath {
*/ */
if (A[c][c].compareTo(BigInteger.ZERO) == 0) { if (A[c][c].compareTo(BigInteger.ZERO) == 0) {
boolean swpd = false; boolean swpd = false;
for (int r = c + 1; r < rL; r++) for (int r = c + 1; r < rL; r++) {
if (A[r][c].compareTo(BigInteger.ZERO) != 0) { if (A[r][c].compareTo(BigInteger.ZERO) != 0) {
for (int cpr = c; cpr < cL; cpr++) { for (int cpr = c; cpr < cL; cpr++) {
final BigInteger tmp = A[c][cpr]; final BigInteger tmp = A[c][cpr];
@ -461,12 +493,14 @@ public class BigIntegerMath {
swpd = true; swpd = true;
break; break;
} }
}
/* /*
* not swapped with a non-zero row: determinant zero and no * not swapped with a non-zero row: determinant zero and no
* solution * solution
*/ */
if (!swpd) if (!swpd) {
throw new ArithmeticException("Zero determinant of main matrix"); throw new ArithmeticException("Zero determinant of main matrix");
}
} }
/* create zero at A[c+1..cL-1][c] */ /* create zero at A[c+1..cL-1][c] */
for (int r = c + 1; r < rL; r++) { for (int r = c + 1; r < rL; r++) {
@ -482,13 +516,15 @@ public class BigIntegerMath {
x[r] = tmp; x[r] = tmp;
} }
} }
if (A[cL - 1][cL - 1].compareTo(BigInteger.ZERO) == 0) if (A[cL - 1][cL - 1].compareTo(BigInteger.ZERO) == 0) {
throw new ArithmeticException("Zero determinant of main matrix"); throw new ArithmeticException("Zero determinant of main matrix");
}
/* backward elimination */ /* backward elimination */
for (int r = cL - 1; r >= 0; r--) { for (int r = cL - 1; r >= 0; r--) {
x[r] = x[r].divide(A[r][r]); x[r] = x[r].divide(A[r][r]);
for (int rpr = r - 1; rpr >= 0; rpr--) for (int rpr = r - 1; rpr >= 0; rpr--) {
x[rpr] = x[rpr].subtract(x[r].multiply(A[rpr][r])); x[rpr] = x[rpr].subtract(x[r].multiply(A[rpr][r]));
}
} }
return x; return x;
@ -523,11 +559,13 @@ public class BigIntegerMath {
* @author Richard J. Mathar * @author Richard J. Mathar
*/ */
static public BigInteger valueOf(final Vector<BigInteger> c, final BigInteger x) { static public BigInteger valueOf(final Vector<BigInteger> c, final BigInteger x) {
if (c.size() == 0) if (c.size() == 0) {
return BigInteger.ZERO; return BigInteger.ZERO;
}
BigInteger res = c.lastElement(); BigInteger res = c.lastElement();
for (int i = c.size() - 2; i >= 0; i--) for (int i = c.size() - 2; i >= 0; i--) {
res = res.multiply(x).add(c.elementAt(i)); res = res.multiply(x).add(c.elementAt(i));
}
return res; return res;
} }
@ -546,11 +584,11 @@ public class BigIntegerMath {
* et al, Num. Funct. Anal. Opt. 10 (5)( 1989) 419-488</a> * et al, Num. Funct. Anal. Opt. 10 (5)( 1989) 419-488</a>
*/ */
static public Rational centrlFactNumt(final int n, final int k) throws Error { static public Rational centrlFactNumt(final int n, final int k) throws Error {
if (k > n || k < 0 || k % 2 != n % 2) if (k > n || k < 0 || k % 2 != n % 2) {
return Rational.ZERO; return Rational.ZERO;
else if (k == n) } else if (k == n) {
return Rational.ONE; return Rational.ONE;
else { } else {
/* Proposition 6.2.6 */ /* Proposition 6.2.6 */
final Factorial f = new Factorial(); final Factorial f = new Factorial();
Rational jsum = new Rational(0, 1); Rational jsum = new Rational(0, 1);
@ -561,17 +599,19 @@ public class BigIntegerMath {
Rational t = new Rational(j - 2 * nu, 2); Rational t = new Rational(j - 2 * nu, 2);
t = t.pow(kprime + j); t = t.pow(kprime + j);
t = t.multiply(BigIntegerMath.binomial(j, nu)); t = t.multiply(BigIntegerMath.binomial(j, nu));
if (nu % 2 != 0) if (nu % 2 != 0) {
nusum = nusum.subtract(t); nusum = nusum.subtract(t);
else } else {
nusum = nusum.add(t); nusum = nusum.add(t);
}
} }
nusum = nusum.divide(f.at(j)).divide(n + j); nusum = nusum.divide(f.at(j)).divide(n + j);
nusum = nusum.multiply(BigIntegerMath.binomial(2 * kprime, kprime - j)); nusum = nusum.multiply(BigIntegerMath.binomial(2 * kprime, kprime - j));
if (j % 2 != 0) if (j % 2 != 0) {
jsum = jsum.subtract(nusum); jsum = jsum.subtract(nusum);
else } else {
jsum = jsum.add(nusum); jsum = jsum.add(nusum);
}
} }
return jsum.multiply(k).multiply(BigIntegerMath.binomial(n + kprime, k)); return jsum.multiply(k).multiply(BigIntegerMath.binomial(n + kprime, k));
} }
@ -591,13 +631,14 @@ public class BigIntegerMath {
* et al, Num. Funct. Anal. Opt. 10 (5)( 1989) 419-488</a> * et al, Num. Funct. Anal. Opt. 10 (5)( 1989) 419-488</a>
*/ */
static public Rational centrlFactNumT(final int n, final int k) { static public Rational centrlFactNumT(final int n, final int k) {
if (k > n || k < 0 || k % 2 != n % 2) if (k > n || k < 0 || k % 2 != n % 2) {
return Rational.ZERO; return Rational.ZERO;
else if (k == n) } else if (k == n) {
return Rational.ONE; return Rational.ONE;
else } else {
/* Proposition 2.1 */ /* Proposition 2.1 */
return BigIntegerMath.centrlFactNumT(n - 2, k - 2).add(BigIntegerMath.centrlFactNumT(n - 2, k).multiply(new Rational(k * k, 4))); return BigIntegerMath.centrlFactNumT(n - 2, k - 2).add(BigIntegerMath.centrlFactNumT(n - 2, k).multiply(new Rational(k * k, 4)));
}
} /* CentralFactNumT */ } /* CentralFactNumT */
} /* BigIntegerMath */ } /* BigIntegerMath */

View File

@ -41,8 +41,9 @@ public class BigIntegerPoly implements Cloneable {
a = new Vector<>(); a = new Vector<>();
final Scanner sc = new Scanner(L); final Scanner sc = new Scanner(L);
sc.useDelimiter(","); sc.useDelimiter(",");
while (sc.hasNextBigInteger()) while (sc.hasNextBigInteger()) {
a.add(sc.nextBigInteger()); a.add(sc.nextBigInteger());
}
simplify(); simplify();
sc.close(); sc.close();
} /* ctor */ } /* ctor */
@ -66,8 +67,9 @@ public class BigIntegerPoly implements Cloneable {
* The coefficients a0, a1, a2 etc in a0+a1*x+a2*x^2+... * The coefficients a0, a1, a2 etc in a0+a1*x+a2*x^2+...
*/ */
public BigIntegerPoly(final BigInteger[] c) { public BigIntegerPoly(final BigInteger[] c) {
for (final BigInteger element : c) for (final BigInteger element : c) {
a.add(element.add(BigInteger.ZERO)); a.add(element.add(BigInteger.ZERO));
}
simplify(); simplify();
} /* ctor */ } /* ctor */
@ -88,8 +90,9 @@ public class BigIntegerPoly implements Cloneable {
*/ */
public RatPoly toRatPoly() { public RatPoly toRatPoly() {
final RatPoly bd = new RatPoly(); final RatPoly bd = new RatPoly();
for (int i = 0; i < a.size(); i++) for (int i = 0; i < a.size(); i++) {
bd.set(i, a.elementAt(i)); bd.set(i, a.elementAt(i));
}
return bd; return bd;
} /* toRatPoly */ } /* toRatPoly */
@ -102,10 +105,11 @@ public class BigIntegerPoly implements Cloneable {
* @return the polynomial coefficient in front of x^n. * @return the polynomial coefficient in front of x^n.
*/ */
public BigInteger at(final int n) { public BigInteger at(final int n) {
if (n < a.size()) if (n < a.size()) {
return a.elementAt(n); return a.elementAt(n);
else } else {
return BigInteger.ZERO; return BigInteger.ZERO;
}
} /* at */ } /* at */
/** /**
@ -118,14 +122,16 @@ public class BigIntegerPoly implements Cloneable {
* @author Richard J. Mathar * @author Richard J. Mathar
*/ */
public BigInteger valueOf(final BigInteger x) { public BigInteger valueOf(final BigInteger x) {
if (a.size() == 0) if (a.size() == 0) {
return BigInteger.ZERO; return BigInteger.ZERO;
}
BigInteger res = a.lastElement(); BigInteger res = a.lastElement();
/* /*
* Heron casted form * Heron casted form
*/ */
for (int i = a.size() - 2; i >= 0; i--) for (int i = a.size() - 2; i >= 0; i--) {
res = res.multiply(x).add(a.elementAt(i)); res = res.multiply(x).add(a.elementAt(i));
}
return res; return res;
} /* valueOf */ } /* valueOf */
@ -154,14 +160,15 @@ public class BigIntegerPoly implements Cloneable {
* the new value of the coefficient. * the new value of the coefficient.
*/ */
public void set(final int n, final BigInteger value) { public void set(final int n, final BigInteger value) {
if (n < a.size()) if (n < a.size()) {
a.set(n, value); a.set(n, value);
else { } else {
/* /*
* fill intermediate powers with coefficients of zero * fill intermediate powers with coefficients of zero
*/ */
while (a.size() < n) while (a.size() < n) {
a.add(BigInteger.ZERO); a.add(BigInteger.ZERO);
}
a.add(value); a.add(value);
} }
} /* set */ } /* set */
@ -209,9 +216,11 @@ public class BigIntegerPoly implements Cloneable {
* If the polynomial is identical to 0, 0 is returned. * If the polynomial is identical to 0, 0 is returned.
*/ */
public int ldegree() { public int ldegree() {
for (int n = 0; n < a.size(); n++) for (int n = 0; n < a.size(); n++) {
if (a.elementAt(n).compareTo(BigInteger.ZERO) != 0) if (a.elementAt(n).compareTo(BigInteger.ZERO) != 0) {
return n; return n;
}
}
return 0; return 0;
} /* ldegree */ } /* ldegree */
@ -227,9 +236,11 @@ public class BigIntegerPoly implements Cloneable {
*/ */
public BigIntegerPoly multiply(final BigInteger val) { public BigIntegerPoly multiply(final BigInteger val) {
final BigIntegerPoly resul = new BigIntegerPoly(); final BigIntegerPoly resul = new BigIntegerPoly();
if (val.compareTo(BigInteger.ZERO) != 0) if (val.compareTo(BigInteger.ZERO) != 0) {
for (int n = 0; n < a.size(); n++) for (int n = 0; n < a.size(); n++) {
resul.set(n, a.elementAt(n).multiply(val)); resul.set(n, a.elementAt(n).multiply(val));
}
}
return resul; return resul;
} /* multiply */ } /* multiply */
@ -248,8 +259,9 @@ public class BigIntegerPoly implements Cloneable {
final int nmax = degree() + val.degree(); final int nmax = degree() + val.degree();
for (int n = 0; n <= nmax; n++) { for (int n = 0; n <= nmax; n++) {
BigInteger coef = BigInteger.ZERO; BigInteger coef = BigInteger.ZERO;
for (int nleft = 0; nleft <= n; nleft++) for (int nleft = 0; nleft <= n; nleft++) {
coef = coef.add(at(nleft).multiply(val.at(n - nleft))); coef = coef.add(at(nleft).multiply(val.at(n - nleft)));
}
resul.set(n, coef); resul.set(n, coef);
} }
resul.simplify(); resul.simplify();
@ -265,11 +277,12 @@ public class BigIntegerPoly implements Cloneable {
*/ */
public BigIntegerPoly pow(final int n) throws ArithmeticException { public BigIntegerPoly pow(final int n) throws ArithmeticException {
BigIntegerPoly resul = new BigIntegerPoly("1"); BigIntegerPoly resul = new BigIntegerPoly("1");
if (n < 0) if (n < 0) {
throw new ArithmeticException("negative polynomial power " + n); throw new ArithmeticException("negative polynomial power " + n);
else { } else {
for (int i = 1; i <= n; i++) for (int i = 1; i <= n; i++) {
resul = resul.multiply(this); resul = resul.multiply(this);
}
resul.simplify(); resul.simplify();
return resul; return resul;
} }
@ -344,8 +357,9 @@ public class BigIntegerPoly implements Cloneable {
/* /*
* catch the case with val equal to zero * catch the case with val equal to zero
*/ */
if (valSimpl.degree() == 0 && valSimpl.a.firstElement().compareTo(BigInteger.ZERO) == 0) if (valSimpl.degree() == 0 && valSimpl.a.firstElement().compareTo(BigInteger.ZERO) == 0) {
throw new ArithmeticException("Division through zero polynomial"); throw new ArithmeticException("Division through zero polynomial");
}
/* /*
* degree of this smaller than degree of val: remainder is this * degree of this smaller than degree of val: remainder is this
*/ */
@ -363,8 +377,9 @@ public class BigIntegerPoly implements Cloneable {
*/ */
ret[0] = new BigIntegerPoly(); ret[0] = new BigIntegerPoly();
final BigInteger[] newc = thisSimpl.a.lastElement().divideAndRemainder(valSimpl.a.lastElement()); final BigInteger[] newc = thisSimpl.a.lastElement().divideAndRemainder(valSimpl.a.lastElement());
if (newc[1].compareTo(BigInteger.ZERO) != 0) if (newc[1].compareTo(BigInteger.ZERO) != 0) {
throw new ArithmeticException("Incompatible leading term in " + this + " / " + val); throw new ArithmeticException("Incompatible leading term in " + this + " / " + val);
}
ret[0].set(thisSimpl.degree() - valSimpl.degree(), newc[0]); ret[0].set(thisSimpl.degree() - valSimpl.degree(), newc[0]);
/* /*
@ -377,9 +392,9 @@ public class BigIntegerPoly implements Cloneable {
/* /*
* any remainder left ? * any remainder left ?
*/ */
if (ret[1].degree() < valSimpl.degree()) if (ret[1].degree() < valSimpl.degree()) {
; ;
else { } else {
final BigIntegerPoly rem[] = ret[1].divideAndRemainder(val); final BigIntegerPoly rem[] = ret[1].divideAndRemainder(val);
ret[0] = ret[0].add(rem[0]); ret[0] = ret[0].add(rem[0]);
ret[1] = rem[1]; ret[1] = rem[1];
@ -397,13 +412,16 @@ public class BigIntegerPoly implements Cloneable {
@Override @Override
public String toString() { public String toString() {
String str = new String(); String str = new String();
for (int n = 0; n < a.size(); n++) for (int n = 0; n < a.size(); n++) {
if (n == 0) if (n == 0) {
str += a.elementAt(n).toString(); str += a.elementAt(n).toString();
else } else {
str += "," + a.elementAt(n).toString(); str += "," + a.elementAt(n).toString();
if (str.length() == 0) }
}
if (str.length() == 0) {
str = "0"; str = "0";
}
return str; return str;
} /* toString */ } /* toString */
@ -420,18 +438,21 @@ public class BigIntegerPoly implements Cloneable {
final BigInteger num = a.elementAt(n); final BigInteger num = a.elementAt(n);
if (num.compareTo(BigInteger.ZERO) != 0) { if (num.compareTo(BigInteger.ZERO) != 0) {
str += " "; str += " ";
if (num.compareTo(BigInteger.ZERO) > 0 && n > 0) if (num.compareTo(BigInteger.ZERO) > 0 && n > 0) {
str += "+"; str += "+";
}
str += a.elementAt(n).toString(); str += a.elementAt(n).toString();
if (n > 0) { if (n > 0) {
str += "*x"; str += "*x";
if (n > 1) if (n > 1) {
str += "^" + n; str += "^" + n;
}
} }
} }
} }
if (str.length() == 0) if (str.length() == 0) {
str = "0"; str = "0";
}
return str; return str;
} /* toPString */ } /* toPString */
@ -441,12 +462,14 @@ public class BigIntegerPoly implements Cloneable {
*/ */
protected void simplify() { protected void simplify() {
int n = a.size() - 1; int n = a.size() - 1;
if (n >= 0) if (n >= 0) {
while (a.elementAt(n).compareTo(BigInteger.ZERO) == 0) { while (a.elementAt(n).compareTo(BigInteger.ZERO) == 0) {
a.removeElementAt(n); a.removeElementAt(n);
if (--n < 0) if (--n < 0) {
break; break;
}
} }
}
} /* simplify */ } /* simplify */
/** /**
@ -456,12 +479,12 @@ public class BigIntegerPoly implements Cloneable {
* @since 2008-10-26 * @since 2008-10-26
*/ */
public BigIntegerPoly derive() { public BigIntegerPoly derive() {
if (a.size() <= 1) if (a.size() <= 1) {
/* /*
* derivative of the constant is just zero * derivative of the constant is just zero
*/ */
return new BigIntegerPoly(); return new BigIntegerPoly();
else { } else {
final BigIntegerPoly d = new BigIntegerPoly(); final BigIntegerPoly d = new BigIntegerPoly();
for (int i = 1; i <= degree(); i++) { for (int i = 1; i <= degree(); i++) {
final BigInteger c = a.elementAt(i).multiply(new BigInteger("" + i)); final BigInteger c = a.elementAt(i).multiply(new BigInteger("" + i));
@ -479,8 +502,9 @@ public class BigIntegerPoly implements Cloneable {
*/ */
public BigIntegerPoly trunc(final int newdeg) { public BigIntegerPoly trunc(final int newdeg) {
final BigIntegerPoly t = new BigIntegerPoly(); final BigIntegerPoly t = new BigIntegerPoly();
for (int i = 0; i <= newdeg; i++) for (int i = 0; i <= newdeg; i++) {
t.set(i, at(i)); t.set(i, at(i));
}
t.simplify(); t.simplify();
return t; return t;
} /* trunc */ } /* trunc */
@ -498,11 +522,13 @@ public class BigIntegerPoly implements Cloneable {
final BigIntegerPoly r = new BigIntegerPoly(); final BigIntegerPoly r = new BigIntegerPoly();
for (int i = 0; i <= maxdeg; i++) { for (int i = 0; i <= maxdeg; i++) {
BigInteger c = BigInteger.ZERO; BigInteger c = BigInteger.ZERO;
for (int j = 0; j <= i && j < a.size(); j++) for (int j = 0; j <= i && j < a.size(); j++) {
if ((j + i) % 2 != 0) if ((j + i) % 2 != 0) {
c = c.subtract(a.elementAt(j).multiply(BigIntegerMath.binomial(i, j))); c = c.subtract(a.elementAt(j).multiply(BigIntegerMath.binomial(i, j)));
else } else {
c = c.add(a.elementAt(j).multiply(BigIntegerMath.binomial(i, j))); c = c.add(a.elementAt(j).multiply(BigIntegerMath.binomial(i, j)));
}
}
r.set(i, c); r.set(i, c);
} }
r.simplify(); r.simplify();
@ -540,8 +566,9 @@ public class BigIntegerPoly implements Cloneable {
/* /*
* collect the zero * collect the zero
*/ */
if (a.firstElement().compareTo(BigInteger.ZERO) == 0) if (a.firstElement().compareTo(BigInteger.ZERO) == 0) {
res.add(BigInteger.ZERO); res.add(BigInteger.ZERO);
}
/* /*
* collect the divisors of the constant element (or the reduced * collect the divisors of the constant element (or the reduced
@ -555,12 +582,14 @@ public class BigIntegerPoly implements Cloneable {
/* check the divisors (both signs) */ /* check the divisors (both signs) */
for (int i = 0; i < cand.size(); i++) { for (int i = 0; i < cand.size(); i++) {
BigInteger roo = valueOf(cand.elementAt(i)); BigInteger roo = valueOf(cand.elementAt(i));
if (roo.compareTo(BigInteger.ZERO) == 0) if (roo.compareTo(BigInteger.ZERO) == 0) {
/* found a root cand[i] */ /* found a root cand[i] */
res.add(cand.elementAt(i)); res.add(cand.elementAt(i));
}
roo = valueOf(cand.elementAt(i).negate()); roo = valueOf(cand.elementAt(i).negate());
if (roo.compareTo(BigInteger.ZERO) == 0) if (roo.compareTo(BigInteger.ZERO) == 0) {
res.add(cand.elementAt(i).negate()); res.add(cand.elementAt(i).negate());
}
} }
} }
return res; return res;
@ -582,8 +611,9 @@ public class BigIntegerPoly implements Cloneable {
*/ */
final Vector<BigIntegerPoly> res = new Vector<>(); final Vector<BigIntegerPoly> res = new Vector<>();
if (degree() < 2) if (degree() < 2) {
return res; return res;
}
final BigInteger bsco = a.firstElement().abs(); final BigInteger bsco = a.firstElement().abs();
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@ -614,16 +644,16 @@ public class BigIntegerPoly implements Cloneable {
* coefficient. * coefficient.
* Solve z*(c*z+a)=-b or c*z+a = -b/z or -b/z-c*z = some integer a. * Solve z*(c*z+a)=-b or c*z+a = -b/z or -b/z-c*z = some integer a.
*/ */
for (final BigComplex z : roo) for (final BigComplex z : roo) {
for (final BigInteger bco : b) for (final BigInteger bco : b) {
for (final BigInteger cco : c) for (final BigInteger cco : c) {
/* /*
* the major reason to avoid the case b=0 is that this would * the major reason to avoid the case b=0 is that this would
* require precaution of double counting below. Note that * require precaution of double counting below. Note that
* this * this
* case is already covered by using iroots(). * case is already covered by using iroots().
*/ */
if (bco.signum() != 0) if (bco.signum() != 0) {
for (int sig = -1; sig <= 1; sig += 2) { for (int sig = -1; sig <= 1; sig += 2) {
final BigInteger bcosig = sig > 0 ? bco : bco.negate(); final BigInteger bcosig = sig > 0 ? bco : bco.negate();
/* /*
@ -645,10 +675,15 @@ public class BigIntegerPoly implements Cloneable {
final BigIntegerPoly dtst = new BigIntegerPoly("" + bcosig + "," + a + "," + cco); final BigIntegerPoly dtst = new BigIntegerPoly("" + bcosig + "," + a + "," + cco);
try { try {
final BigIntegerPoly[] rm = divideAndRemainder(dtst); final BigIntegerPoly[] rm = divideAndRemainder(dtst);
if (rm[1].isZero()) if (rm[1].isZero()) {
res.add(dtst); res.add(dtst);
}
} catch (final ArithmeticException ex) {} } catch (final ArithmeticException ex) {}
} }
}
}
}
}
return res; return res;
} /* i2roots */ } /* i2roots */
@ -697,28 +732,32 @@ public class BigIntegerPoly implements Cloneable {
* collect factors which are polynomials of degree 2 * collect factors which are polynomials of degree 2
*/ */
final Vector<BigIntegerPoly> pol2 = i2roots(); final Vector<BigIntegerPoly> pol2 = i2roots();
for (final BigIntegerPoly i : pol2) for (final BigIntegerPoly i : pol2) {
/* /*
* the internal loop catches cases with higher * the internal loop catches cases with higher
* powers of individual polynomials (of actual degree 2 or 4...) * powers of individual polynomials (of actual degree 2 or 4...)
*/ */
while (res[0].degree() >= 2) while (res[0].degree() >= 2) {
try { try {
final BigIntegerPoly[] dtst = res[0].divideAndRemainder(i); final BigIntegerPoly[] dtst = res[0].divideAndRemainder(i);
if (dtst[1].isZero()) { if (dtst[1].isZero()) {
fac.add(i); fac.add(i);
res = dtst; res = dtst;
} else } else {
break; break;
}
} catch (final ArithmeticException ex) { } catch (final ArithmeticException ex) {
break; break;
} }
}
}
/* /*
* add remaining factor, if not equal to 1 * add remaining factor, if not equal to 1
*/ */
if (res[0].degree() > 0 || res[0].a.firstElement().compareTo(BigInteger.ONE) != 0) if (res[0].degree() > 0 || res[0].a.firstElement().compareTo(BigInteger.ONE) != 0) {
fac.add(res[0]); fac.add(res[0]);
}
return fac; return fac;
} /* ifactor */ } /* ifactor */

View File

@ -64,8 +64,9 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
/* /*
* reject attempts to use a negative b * reject attempts to use a negative b
*/ */
if (b.signum() < 0) if (b.signum() < 0) {
throw new ProviderException("Not implemented: imaginary surds"); throw new ProviderException("Not implemented: imaginary surds");
}
disc = b; disc = b;
try { try {
normalize(); normalize();
@ -136,13 +137,14 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
public BigSurdVec add(final BigSurd val) { public BigSurdVec add(final BigSurd val) {
// zero plus somethings yields something // zero plus somethings yields something
if (signum() == 0) if (signum() == 0) {
return new BigSurdVec(val); return new BigSurdVec(val);
else if (val.signum() == 0) } else if (val.signum() == 0) {
return new BigSurdVec(this); return new BigSurdVec(this);
else } else {
// let the ctor of BigSurdVec to the work // let the ctor of BigSurdVec to the work
return new BigSurdVec(this, val); return new BigSurdVec(this, val);
}
} /* BigSurd.add */ } /* BigSurd.add */
/** /**
@ -216,8 +218,9 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
* @since 2011-02-12 * @since 2011-02-12
*/ */
public BigSurd divide(final BigSurd val) throws Error { public BigSurd divide(final BigSurd val) throws Error {
if (val.signum() == 0) if (val.signum() == 0) {
throw new ArithmeticException("Dividing " + toFancyString() + " through zero."); throw new ArithmeticException("Dividing " + toFancyString() + " through zero.");
}
return new BigSurd(pref.divide(val.pref), disc.divide(val.disc)); return new BigSurd(pref.divide(val.pref), disc.divide(val.disc));
} /* BigSurd.divide */ } /* BigSurd.divide */
@ -225,13 +228,14 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
final BigSurd bs = this; final BigSurd bs = this;
final BigInteger denominator = pref.b; final BigInteger denominator = pref.b;
String s = ""; String s = "";
if (denominator.compareTo(BigInteger.ONE) != 0) if (denominator.compareTo(BigInteger.ONE) != 0) {
s += "("; s += "(";
if (bs.isBigInteger()) }
if (bs.isBigInteger()) {
s += bs.BigDecimalValue(new MathContext(Utils.scale, Utils.scaleMode2)).toBigInteger().toString(); s += bs.BigDecimalValue(new MathContext(Utils.scale, Utils.scaleMode2)).toBigInteger().toString();
else if (bs.isRational()) } else if (bs.isRational()) {
s += bs.toRational().toString(); s += bs.toRational().toString();
else { } else {
final BigInteger numerator = bs.pref.a; final BigInteger numerator = bs.pref.a;
if (numerator.compareTo(BigInteger.ONE) != 0) { if (numerator.compareTo(BigInteger.ONE) != 0) {
s += numerator.toString(); s += numerator.toString();
@ -239,12 +243,14 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
s += "("; s += "(";
} }
s += "2√"; s += "2√";
if (bs.disc.isInteger()) if (bs.disc.isInteger()) {
s += bs.disc.toString(); s += bs.disc.toString();
else } else {
s += "(" + bs.disc.toString() + ")"; s += "(" + bs.disc.toString() + ")";
if (numerator.compareTo(BigInteger.ONE) != 0) }
if (numerator.compareTo(BigInteger.ONE) != 0) {
s += ")"; s += ")";
}
} }
return s; return s;
} }
@ -259,8 +265,9 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
* @since 2011-02-12 * @since 2011-02-12
*/ */
public BigSurd divide(final BigInteger val) throws Error { public BigSurd divide(final BigInteger val) throws Error {
if (val.signum() == 0) if (val.signum() == 0) {
throw new ArithmeticException("Dividing " + toFancyString() + " through zero."); throw new ArithmeticException("Dividing " + toFancyString() + " through zero.");
}
return new BigSurd(pref.divide(val), disc); return new BigSurd(pref.divide(val), disc);
} /* BigSurd.divide */ } /* BigSurd.divide */
@ -274,8 +281,9 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
* @since 2011-02-12 * @since 2011-02-12
*/ */
public BigSurd divide(final int val) throws Error { public BigSurd divide(final int val) throws Error {
if (val == 0) if (val == 0) {
throw new ArithmeticException("Dividing " + toFancyString() + " through zero."); throw new ArithmeticException("Dividing " + toFancyString() + " through zero.");
}
return new BigSurd(pref.divide(val), disc); return new BigSurd(pref.divide(val), disc);
} /* BigSurd.divide */ } /* BigSurd.divide */
@ -322,16 +330,21 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
*/ */
final int sig = signum(); final int sig = signum();
final int sigv = val.signum(); final int sigv = val.signum();
if (sig < 0 && sigv >= 0) if (sig < 0 && sigv >= 0) {
return -1; return -1;
if (sig > 0 && sigv <= 0) }
if (sig > 0 && sigv <= 0) {
return 1; return 1;
if (sig == 0 && sigv == 0) }
if (sig == 0 && sigv == 0) {
return 0; return 0;
if (sig == 0 && sigv > 0) }
if (sig == 0 && sigv > 0) {
return -1; return -1;
if (sig == 0 && sigv < 0) }
if (sig == 0 && sigv < 0) {
return 1; return 1;
}
/* /*
* Work out the cases of equal sign. Compare absolute values by * Work out the cases of equal sign. Compare absolute values by
@ -342,12 +355,13 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
final Rational this2 = sqr(); final Rational this2 = sqr();
final Rational val2 = val.sqr(); final Rational val2 = val.sqr();
final int c = this2.compareTo(val2); final int c = this2.compareTo(val2);
if (c == 0) if (c == 0) {
return 0; return 0;
else if (sig > 0 && c > 0 || sig < 0 && c < 0) } else if (sig > 0 && c > 0 || sig < 0 && c < 0) {
return 1; return 1;
else } else {
return -1; return -1;
}
} /* BigSurd.compareTo */ } /* BigSurd.compareTo */
/** /**
@ -359,10 +373,11 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
*/ */
@Override @Override
public String toString() { public String toString() {
if (disc.compareTo(Rational.ONE) != 0 && disc.compareTo(Rational.ZERO) != 0) if (disc.compareTo(Rational.ONE) != 0 && disc.compareTo(Rational.ZERO) != 0) {
return "(" + pref.toString() + ")*(" + disc.toString() + ")^(1/2)"; return "(" + pref.toString() + ")*(" + disc.toString() + ")^(1/2)";
else } else {
return pref.toString(); return pref.toString();
}
} /* BigSurd.toString */ } /* BigSurd.toString */
/** /**
@ -421,10 +436,11 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
* @since 2012-02-15 * @since 2012-02-15
*/ */
public Rational toRational() { public Rational toRational() {
if (isRational()) if (isRational()) {
return pref; return pref;
else } else {
throw new ArithmeticException("Undefined conversion " + toFancyString() + " to Rational."); throw new ArithmeticException("Undefined conversion " + toFancyString() + " to Rational.");
}
} /* BigSurd.toRational */ } /* BigSurd.toRational */
/** /**
@ -477,8 +493,9 @@ public class BigSurd implements Cloneable, Comparable<BigSurd> {
pref = pref.divide(sqf); pref = pref.divide(sqf);
disc = new Rational(numC, denC); disc = new Rational(numC, denC);
} else } else {
pref = Rational.ZERO; pref = Rational.ZERO;
}
} /* BigSurd.normalize */ } /* BigSurd.normalize */
/** /**

View File

@ -87,8 +87,9 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
/* /*
* nothing to be done if at most one term * nothing to be done if at most one term
*/ */
if (terms.size() <= 1) if (terms.size() <= 1) {
return; return;
}
final Vector<BigSurd> newter = new Vector<>(); final Vector<BigSurd> newter = new Vector<>();
newter.add(terms.firstElement()); newter.add(terms.firstElement());
@ -112,9 +113,9 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
/* /*
* eliminate accidental zeros; overwrite with v*(1+r). * eliminate accidental zeros; overwrite with v*(1+r).
*/ */
if (newpref.compareTo(Rational.ZERO) == 0) if (newpref.compareTo(Rational.ZERO) == 0) {
newter.removeElementAt(ex); newter.removeElementAt(ex);
else { } else {
v = v.multiply(newpref); v = v.multiply(newpref);
newter.setElementAt(v, ex); newter.setElementAt(v, ex);
} }
@ -125,8 +126,9 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
/* /*
* append if none of the existing elements matched * append if none of the existing elements matched
*/ */
if (!merged) if (!merged) {
newter.add(todo); newter.add(todo);
}
} }
/* overwrite old version */ /* overwrite old version */
@ -168,14 +170,16 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
* the case of zero is unique, because no (reduced) vector of surds * the case of zero is unique, because no (reduced) vector of surds
* other than the one element 0 itself can add/subtract to zero. * other than the one element 0 itself can add/subtract to zero.
*/ */
if (terms.size() == 0) if (terms.size() == 0) {
return 0; return 0;
}
/* /*
* if there is one term: forward to the signum function of BigSurd * if there is one term: forward to the signum function of BigSurd
*/ */
if (terms.size() == 1) if (terms.size() == 1) {
return terms.firstElement().signum(); return terms.firstElement().signum();
}
/* /*
* if all terms have a common sign: take that one offsig is the index of * if all terms have a common sign: take that one offsig is the index of
@ -184,18 +188,22 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
*/ */
final int sig0 = terms.elementAt(0).signum(); final int sig0 = terms.elementAt(0).signum();
int offsig = 1; int offsig = 1;
for (; offsig < terms.size(); offsig++) for (; offsig < terms.size(); offsig++) {
if (terms.elementAt(offsig).signum() != sig0) if (terms.elementAt(offsig).signum() != sig0) {
break; break;
if (offsig >= terms.size()) }
}
if (offsig >= terms.size()) {
return sig0; return sig0;
}
/* /*
* if there are two terms (now known to have different sign): forward to * if there are two terms (now known to have different sign): forward to
* the comparison of the two elements as BigSurds * the comparison of the two elements as BigSurds
*/ */
if (terms.size() == 2) if (terms.size() == 2) {
return terms.elementAt(0).compareTo(terms.elementAt(1).negate()); return terms.elementAt(0).compareTo(terms.elementAt(1).negate());
}
/* /*
* if there are three terms, move the one with the offending sign to the * if there are three terms, move the one with the offending sign to the
@ -206,10 +214,11 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
*/ */
if (terms.size() == 3) { if (terms.size() == 3) {
BigSurdVec lhs; BigSurdVec lhs;
if (offsig == 2) if (offsig == 2) {
lhs = new BigSurdVec(terms.elementAt(0), terms.elementAt(1)); lhs = new BigSurdVec(terms.elementAt(0), terms.elementAt(1));
else } else {
lhs = new BigSurdVec(terms.elementAt(0), terms.elementAt(2)); lhs = new BigSurdVec(terms.elementAt(0), terms.elementAt(2));
}
lhs = lhs.sqr(); lhs = lhs.sqr();
/* /*
* Strange line: this line isn't used, but it's present in this * Strange line: this line isn't used, but it's present in this
@ -223,13 +232,14 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
* *
* *
*/ */
if (lhs.compareTo(lhs) > 0) if (lhs.compareTo(lhs) > 0) {
/* /*
* dominating sign was t(0)+t(offbar) * dominating sign was t(0)+t(offbar)
*/ */
return terms.elementAt(0).signum(); return terms.elementAt(0).signum();
else } else {
return terms.elementAt(offsig).signum(); return terms.elementAt(offsig).signum();
}
} }
/* /*
@ -252,10 +262,11 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
/* /*
* simple cases with one term forwarded to the BigSurd class * simple cases with one term forwarded to the BigSurd class
*/ */
if (terms.size() == 0) if (terms.size() == 0) {
return BigDecimal.ZERO; return BigDecimal.ZERO;
else if (terms.size() == 1) } else if (terms.size() == 1) {
return terms.firstElement().BigDecimalValue(mc); return terms.firstElement().BigDecimalValue(mc);
}
/* /*
* To reduce cancellation errors, loop over increasing local precision * To reduce cancellation errors, loop over increasing local precision
@ -267,13 +278,15 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
for (int addpr = 1;; addpr += 3) { for (int addpr = 1;; addpr += 3) {
final MathContext locmc = new MathContext(mc.getPrecision() + addpr, mc.getRoundingMode()); final MathContext locmc = new MathContext(mc.getPrecision() + addpr, mc.getRoundingMode());
res[1] = BigDecimal.ZERO; res[1] = BigDecimal.ZERO;
for (final BigSurd j : terms) for (final BigSurd j : terms) {
res[1] = BigDecimalMath.addRound(res[1], j.BigDecimalValue(locmc)); res[1] = BigDecimalMath.addRound(res[1], j.BigDecimalValue(locmc));
}
if (addpr > 1) { if (addpr > 1) {
final BigDecimal err = res[1].subtract(res[0]).abs(); final BigDecimal err = res[1].subtract(res[0]).abs();
final int prec = BigDecimalMath.err2prec(res[1], err); final int prec = BigDecimalMath.err2prec(res[1], err);
if (prec > mc.getPrecision()) if (prec > mc.getPrecision()) {
break; break;
}
} }
res[0] = res[1]; res[0] = res[1];
} }
@ -314,12 +327,16 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
/* /*
* concatenate the vectors and eliminate common overlaps * concatenate the vectors and eliminate common overlaps
*/ */
for (final BigSurd term : terms) for (final BigSurd term : terms) {
if (term.compareTo(BigSurd.ZERO) != 0) if (term.compareTo(BigSurd.ZERO) != 0) {
sum.terms.add(term); sum.terms.add(term);
for (final BigSurd term : val.terms) }
if (term.compareTo(BigSurd.ZERO) != 0) }
for (final BigSurd term : val.terms) {
if (term.compareTo(BigSurd.ZERO) != 0) {
sum.terms.add(term); sum.terms.add(term);
}
}
sum.normalize(); sum.normalize();
return sum; return sum;
} /* add */ } /* add */
@ -357,8 +374,9 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
* concatenate the vectors and eliminate common overlaps * concatenate the vectors and eliminate common overlaps
*/ */
sum.terms.addAll(terms); sum.terms.addAll(terms);
for (final BigSurd s : val.terms) for (final BigSurd s : val.terms) {
sum.terms.add(s.negate()); sum.terms.add(s.negate());
}
sum.normalize(); sum.normalize();
return sum; return sum;
} /* subtract */ } /* subtract */
@ -393,8 +411,9 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
* accumulate the negated elements of term one by one * accumulate the negated elements of term one by one
*/ */
final BigSurdVec resul = new BigSurdVec(); final BigSurdVec resul = new BigSurdVec();
for (final BigSurd s : terms) for (final BigSurd s : terms) {
resul.terms.add(s.negate()); resul.terms.add(s.negate());
}
/* /*
* no normalization step here, because the negation of all terms does * no normalization step here, because the negation of all terms does
* not introduce new common factors * not introduce new common factors
@ -415,11 +434,14 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
* the mixed products. * the mixed products.
*/ */
final BigSurdVec resul = new BigSurdVec(); final BigSurdVec resul = new BigSurdVec();
for (int i = 0; i < terms.size(); i++) for (int i = 0; i < terms.size(); i++) {
resul.terms.add(new BigSurd(terms.elementAt(i).sqr(), Rational.ONE)); resul.terms.add(new BigSurd(terms.elementAt(i).sqr(), Rational.ONE));
for (int i = 0; i < terms.size() - 1; i++) }
for (int j = i + 1; j < terms.size(); j++) for (int i = 0; i < terms.size() - 1; i++) {
for (int j = i + 1; j < terms.size(); j++) {
resul.terms.add(terms.elementAt(i).multiply(terms.elementAt(j)).multiply(2)); resul.terms.add(terms.elementAt(i).multiply(terms.elementAt(j)).multiply(2));
}
}
resul.normalize(); resul.normalize();
return resul; return resul;
} /* sqr */ } /* sqr */
@ -435,25 +457,29 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
*/ */
public BigSurdVec multiply(final BigSurd val) throws Error { public BigSurdVec multiply(final BigSurd val) throws Error {
final BigSurdVec resul = new BigSurdVec(); final BigSurdVec resul = new BigSurdVec();
for (final BigSurd s : terms) for (final BigSurd s : terms) {
resul.terms.add(s.multiply(val)); resul.terms.add(s.multiply(val));
}
resul.normalize(); resul.normalize();
return resul; return resul;
} /* multiply */ } /* multiply */
public BigSurdVec multiply(final BigSurdVec val) throws Error { public BigSurdVec multiply(final BigSurdVec val) throws Error {
BigSurdVec resul = new BigSurdVec(); BigSurdVec resul = new BigSurdVec();
for (final BigSurd s : terms) for (final BigSurd s : terms) {
resul.terms.add(s); resul.terms.add(s);
for (final BigSurd s : val.terms) }
for (final BigSurd s : val.terms) {
resul = resul.multiply(s); resul = resul.multiply(s);
}
return resul; return resul;
} /* multiply */ } /* multiply */
public BigSurdVec divide(final BigSurd val) throws Error { public BigSurdVec divide(final BigSurd val) throws Error {
final BigSurdVec resul = new BigSurdVec(); final BigSurdVec resul = new BigSurdVec();
for (final BigSurd s : terms) for (final BigSurd s : terms) {
resul.terms.add(s.divide(val)); resul.terms.add(s.divide(val));
}
resul.normalize(); resul.normalize();
return resul; return resul;
} /* multiply */ } /* multiply */
@ -461,8 +487,9 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
public BigSurdVec divide(final BigSurdVec val) throws Error { public BigSurdVec divide(final BigSurdVec val) throws Error {
BigSurdVec resul = new BigSurdVec(); BigSurdVec resul = new BigSurdVec();
resul.terms = terms; resul.terms = terms;
for (final BigSurd s : val.terms) for (final BigSurd s : val.terms) {
resul = resul.divide(s); resul = resul.divide(s);
}
return resul; return resul;
} /* divide */ } /* divide */
@ -476,8 +503,9 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
boolean val = false; boolean val = false;
for (final BigSurd s : terms) { for (final BigSurd s : terms) {
val = s.isRational(); val = s.isRational();
if (val == false) if (val == false) {
break; break;
}
} }
return val; return val;
} /* BigSurdVec.isRational */ } /* BigSurdVec.isRational */
@ -492,8 +520,9 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
boolean val = false; boolean val = false;
for (final BigSurd s : terms) { for (final BigSurd s : terms) {
val = s.isBigInteger(); val = s.isBigInteger();
if (val == false) if (val == false) {
break; break;
}
} }
return val; return val;
} /* BigSurdVec.isRational */ } /* BigSurdVec.isRational */
@ -505,10 +534,12 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
*/ */
public Rational toRational() { public Rational toRational() {
Rational rat = Rational.ZERO; Rational rat = Rational.ZERO;
if (isRational() == false) if (isRational() == false) {
throw new ArithmeticException("Undefined conversion " + toString() + " to Rational."); throw new ArithmeticException("Undefined conversion " + toString() + " to Rational.");
for (final BigSurd s : terms) }
for (final BigSurd s : terms) {
rat = rat.add(s.pref); rat = rat.add(s.pref);
}
return rat; return rat;
} /* BigSurd.toRational */ } /* BigSurd.toRational */
@ -519,10 +550,12 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
*/ */
public BigInteger toBigInteger() { public BigInteger toBigInteger() {
BigDecimal tmp = BigDecimal.ZERO.setScale(Utils.scale, Utils.scaleMode); BigDecimal tmp = BigDecimal.ZERO.setScale(Utils.scale, Utils.scaleMode);
if (isBigInteger() == false) if (isBigInteger() == false) {
throw new ArithmeticException("Undefined conversion " + toString() + " to Rational."); throw new ArithmeticException("Undefined conversion " + toString() + " to Rational.");
for (final BigSurd s : terms) }
for (final BigSurd s : terms) {
tmp = BigDecimalMath.addRound(tmp, s.pref.BigDecimalValue(new MathContext(Utils.scale, Utils.scaleMode2))); tmp = BigDecimalMath.addRound(tmp, s.pref.BigDecimalValue(new MathContext(Utils.scale, Utils.scaleMode2)));
}
return tmp.toBigInteger(); return tmp.toBigInteger();
} /* BigSurd.toRational */ } /* BigSurd.toRational */
@ -533,8 +566,9 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
*/ */
public BigDecimal toBigDecimal() { public BigDecimal toBigDecimal() {
BigDecimal tmp = BigDecimal.ZERO.setScale(Utils.scale, Utils.scaleMode); BigDecimal tmp = BigDecimal.ZERO.setScale(Utils.scale, Utils.scaleMode);
for (final BigSurd s : terms) for (final BigSurd s : terms) {
tmp = BigDecimalMath.addRound(tmp, s.BigDecimalValue(new MathContext(Utils.scale, Utils.scaleMode2))); tmp = BigDecimalMath.addRound(tmp, s.BigDecimalValue(new MathContext(Utils.scale, Utils.scaleMode2)));
}
return tmp; return tmp;
} /* BigSurd.toBigDecimal */ } /* BigSurd.toBigDecimal */
@ -550,14 +584,15 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
/* /*
* simple cases with one term forwarded to the BigSurd class * simple cases with one term forwarded to the BigSurd class
*/ */
if (terms.size() == 0) if (terms.size() == 0) {
return new String("0"); return new String("0");
else { } else {
String s = new String(); String s = new String();
for (int t = 0; t < terms.size(); t++) { for (int t = 0; t < terms.size(); t++) {
final BigSurd bs = terms.elementAt(t); final BigSurd bs = terms.elementAt(t);
if (bs.signum() > 0) if (bs.signum() > 0) {
s += "+"; s += "+";
}
s += bs.toString(); s += bs.toString();
} }
return s; return s;
@ -565,24 +600,27 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
} /* toString */ } /* toString */
public String toFancyString() { public String toFancyString() {
if (terms.size() == 0) if (terms.size() == 0) {
return new String("0"); return new String("0");
else { } else {
BigInteger denominator = BigInteger.ONE; BigInteger denominator = BigInteger.ONE;
for (int i = 0; i < terms.size(); i++) for (int i = 0; i < terms.size(); i++) {
denominator = denominator.multiply(terms.elementAt(i).pref.b); denominator = denominator.multiply(terms.elementAt(i).pref.b);
}
String s = ""; String s = "";
if (denominator.compareTo(BigInteger.ONE) != 0) if (denominator.compareTo(BigInteger.ONE) != 0) {
s += "("; s += "(";
}
for (int t = 0; t < terms.size(); t++) { for (int t = 0; t < terms.size(); t++) {
final BigSurd bs = terms.elementAt(t); final BigSurd bs = terms.elementAt(t);
if (bs.signum() > 0 && t > 0) if (bs.signum() > 0 && t > 0) {
s += "+"; s += "+";
if (bs.isBigInteger()) }
if (bs.isBigInteger()) {
s += bs.BigDecimalValue(new MathContext(Utils.scale, Utils.scaleMode2)).toBigInteger().toString(); s += bs.BigDecimalValue(new MathContext(Utils.scale, Utils.scaleMode2)).toBigInteger().toString();
else if (bs.isRational()) } else if (bs.isRational()) {
s += bs.toRational().toString(); s += bs.toRational().toString();
else { } else {
final BigInteger numerator = bs.pref.multiply(denominator).numer(); final BigInteger numerator = bs.pref.multiply(denominator).numer();
if (numerator.compareTo(BigInteger.ONE) != 0) { if (numerator.compareTo(BigInteger.ONE) != 0) {
s += numerator.toString(); s += numerator.toString();
@ -590,10 +628,11 @@ public class BigSurdVec implements Comparable<BigSurdVec> {
// s += "("; Radice quadrata. non servono le parentesi. // s += "("; Radice quadrata. non servono le parentesi.
} }
s += ""; s += "";
if (bs.disc.isInteger()) if (bs.disc.isInteger()) {
s += bs.disc.toString(); s += bs.disc.toString();
else } else {
s += "(" + bs.disc.toString() + ")"; s += "(" + bs.disc.toString() + ")";
}
if (numerator.compareTo(BigInteger.ONE) != 0) { if (numerator.compareTo(BigInteger.ONE) != 0) {
// s += ")"; Radice quadrata. non servono le parentesi. // s += ")"; Radice quadrata. non servono le parentesi.
} }

View File

@ -42,16 +42,18 @@ public class Euler {
for (int i = thisn - 1; i > 0; i--) { for (int i = thisn - 1; i > 0; i--) {
BigInteger f = new BigInteger("" + Euler.a.elementAt(i).toString()); BigInteger f = new BigInteger("" + Euler.a.elementAt(i).toString());
f = f.multiply(BigIntegerMath.binomial(2 * thisn, 2 * i)); f = f.multiply(BigIntegerMath.binomial(2 * thisn, 2 * i));
if (sigPos) if (sigPos) {
val = val.add(f); val = val.add(f);
else } else {
val = val.subtract(f); val = val.subtract(f);
}
sigPos = !sigPos; sigPos = !sigPos;
} }
if (thisn % 2 == 0) if (thisn % 2 == 0) {
val = val.subtract(BigInteger.ONE); val = val.subtract(BigInteger.ONE);
else } else {
val = val.add(BigInteger.ONE); val = val.add(BigInteger.ONE);
}
Euler.a.add(val); Euler.a.add(val);
} }
} }

View File

@ -36,16 +36,18 @@ public class EulerPhi {
* @return phi(n) * @return phi(n)
*/ */
public BigInteger at(final BigInteger n) { public BigInteger at(final BigInteger n) {
if (n.compareTo(BigInteger.ZERO) <= 0) if (n.compareTo(BigInteger.ZERO) <= 0) {
throw new ArithmeticException("negative argument " + n + " of EulerPhi"); throw new ArithmeticException("negative argument " + n + " of EulerPhi");
}
final Ifactor prFact = new Ifactor(n); final Ifactor prFact = new Ifactor(n);
BigInteger phi = n; BigInteger phi = n;
if (n.compareTo(BigInteger.ONE) > 0) if (n.compareTo(BigInteger.ONE) > 0) {
for (int i = 0; i < prFact.primeexp.size(); i += 2) { for (int i = 0; i < prFact.primeexp.size(); i += 2) {
final BigInteger p = new BigInteger(prFact.primeexp.elementAt(i).toString()); final BigInteger p = new BigInteger(prFact.primeexp.elementAt(i).toString());
final BigInteger p_1 = p.subtract(BigInteger.ONE); final BigInteger p_1 = p.subtract(BigInteger.ONE);
phi = phi.multiply(p_1).divide(p); phi = phi.multiply(p_1).divide(p);
} }
}
return phi; return phi;
} /* at */ } /* at */

View File

@ -23,9 +23,9 @@ public class Harmonic {
* For values of n less than 1, zero is returned. * For values of n less than 1, zero is returned.
*/ */
public Rational at(final int n) { public Rational at(final int n) {
if (n < 1) if (n < 1) {
return new Rational(0, 1); return new Rational(0, 1);
else { } else {
/* /*
* start with 1 as the result * start with 1 as the result
*/ */
@ -34,8 +34,9 @@ public class Harmonic {
/* /*
* add 1/i for i=2..n * add 1/i for i=2..n
*/ */
for (int i = 2; i <= n; i++) for (int i = 2; i <= n; i++) {
a = a.add(new Rational(1, i)); a = a.add(new Rational(1, i));
}
return a; return a;
} }
} }

View File

@ -61,8 +61,9 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
while (number % p == 0) { while (number % p == 0) {
ex++; ex++;
number /= p; number /= p;
if (number == 1) if (number == 1) {
break; break;
}
} }
if (ex > 0) { if (ex > 0) {
primeexp.add(new Integer(p)); primeexp.add(new Integer(p));
@ -102,8 +103,9 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
while (number.remainder(p).compareTo(BigInteger.ZERO) == 0) { while (number.remainder(p).compareTo(BigInteger.ZERO) == 0) {
ex++; ex++;
number = number.divide(p); number = number.divide(p);
if (number.compareTo(BigInteger.ONE) == 0) if (number.compareTo(BigInteger.ONE) == 0) {
break; break;
}
} }
if (ex > 0) { if (ex > 0) {
primeexp.add(new Integer(p.intValue())); primeexp.add(new Integer(p.intValue()));
@ -139,8 +141,9 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
primeexp.add(new Integer(p.intValue())); primeexp.add(new Integer(p.intValue()));
primeexp.add(new Integer(ex)); primeexp.add(new Integer(ex));
} }
} else } else {
n = BigInteger.ZERO; n = BigInteger.ZERO;
}
} /* Ifactor */ } /* Ifactor */
/** /**
@ -272,25 +275,25 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
* skip the case where 0*something =0, falling thru to the empty * skip the case where 0*something =0, falling thru to the empty
* representation for 0 * representation for 0
*/ */
if (primeexp.size() != 0 && oth.primeexp.size() != 0) if (primeexp.size() != 0 && oth.primeexp.size() != 0) {
/* /*
* Cases of 1 times something return something. * Cases of 1 times something return something.
* Cases of lcm(1, something) return something. * Cases of lcm(1, something) return something.
* Cases of gcd(1, something) return 1. * Cases of gcd(1, something) return 1.
*/ */
if (primeexp.firstElement().intValue() == 1 && type == 0) if (primeexp.firstElement().intValue() == 1 && type == 0) {
return oth; return oth;
else if (primeexp.firstElement().intValue() == 1 && type == 2) } else if (primeexp.firstElement().intValue() == 1 && type == 2) {
return oth; return oth;
else if (primeexp.firstElement().intValue() == 1 && type == 1) } else if (primeexp.firstElement().intValue() == 1 && type == 1) {
return this; return this;
else if (oth.primeexp.firstElement().intValue() == 1 && type == 0) } else if (oth.primeexp.firstElement().intValue() == 1 && type == 0) {
return this; return this;
else if (oth.primeexp.firstElement().intValue() == 1 && type == 2) } else if (oth.primeexp.firstElement().intValue() == 1 && type == 2) {
return this; return this;
else if (oth.primeexp.firstElement().intValue() == 1 && type == 1) } else if (oth.primeexp.firstElement().intValue() == 1 && type == 1) {
return oth; return oth;
else { } else {
int idxThis = 0; int idxThis = 0;
int idxOth = 0; int idxOth = 0;
switch (type) { switch (type) {
@ -312,7 +315,7 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
* scan both representations left to right, increasing prime * scan both representations left to right, increasing prime
* powers * powers
*/ */
while (idxOth < oth.primeexp.size() || idxThis < primeexp.size()) while (idxOth < oth.primeexp.size() || idxThis < primeexp.size()) {
if (idxOth >= oth.primeexp.size()) { if (idxOth >= oth.primeexp.size()) {
/* /*
* exhausted the list in oth.primeexp; copy over the * exhausted the list in oth.primeexp; copy over the
@ -383,7 +386,9 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
idxThis += 2; idxThis += 2;
} }
} }
}
} }
}
return prod; return prod;
} /* Ifactor.multGcdLcm */ } /* Ifactor.multGcdLcm */
@ -415,10 +420,11 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
/* /*
* avoid refactorization if oth is zero... * avoid refactorization if oth is zero...
*/ */
if (oth.compareTo(BigInteger.ZERO) != 0) if (oth.compareTo(BigInteger.ZERO) != 0) {
return new Ifactor(n.add(oth)); return new Ifactor(n.add(oth));
else } else {
return this; return this;
}
} /* Ifactor.add */ } /* Ifactor.add */
/** /**
@ -432,12 +438,13 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
/* /*
* three simple cases first * three simple cases first
*/ */
if (exponent < 0) if (exponent < 0) {
throw new ArithmeticException("Cannot raise " + toString() + " to negative " + exponent); throw new ArithmeticException("Cannot raise " + toString() + " to negative " + exponent);
else if (exponent == 0) } else if (exponent == 0) {
return new Ifactor(1); return new Ifactor(1);
else if (exponent == 1) } else if (exponent == 1) {
return this; return this;
}
/* /*
* general case, the vector with the prime factor powers, which are * general case, the vector with the prime factor powers, which are
@ -467,9 +474,9 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
* @since 2009-05-18 * @since 2009-05-18
*/ */
public Rational root(final int r) throws ArithmeticException, Error { public Rational root(final int r) throws ArithmeticException, Error {
if (r == 0) if (r == 0) {
throw new ArithmeticException("Cannot pull zeroth root of " + toString()); throw new ArithmeticException("Cannot pull zeroth root of " + toString());
else if (r < 0) { } else if (r < 0) {
/* /*
* a^(-1/b)= 1/(a^(1/b)) * a^(-1/b)= 1/(a^(1/b))
*/ */
@ -483,8 +490,9 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
* stay in the range of rational results). * stay in the range of rational results).
*/ */
final int ex = primeexp.elementAt(i + 1).intValue(); final int ex = primeexp.elementAt(i + 1).intValue();
if (ex % r != 0) if (ex % r != 0) {
throw new ArithmeticException("Cannot pull " + r + "th root of " + toString()); throw new ArithmeticException("Cannot pull " + r + "th root of " + toString());
}
pows.multiply(new BigInteger("" + primeexp.elementAt(i)).pow(ex / r)); pows.multiply(new BigInteger("" + primeexp.elementAt(i)).pow(ex / r));
} }
@ -511,8 +519,9 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
* by 1 or by a product that contains the factors p1..py. * by 1 or by a product that contains the factors p1..py.
*/ */
final Vector<BigInteger> d = new Vector<>(); final Vector<BigInteger> d = new Vector<>();
if (n.compareTo(BigInteger.ZERO) == 0) if (n.compareTo(BigInteger.ZERO) == 0) {
return d; return d;
}
d.add(BigInteger.ONE); d.add(BigInteger.ONE);
if (n.compareTo(BigInteger.ONE) > 0) { if (n.compareTo(BigInteger.ONE) > 0) {
/* Computes sigmaIncopml(p1^e*p2^e2...*py^ey) */ /* Computes sigmaIncopml(p1^e*p2^e2...*py^ey) */
@ -530,12 +539,14 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
* the output contains all products of the form partd[]*pz^ez, ez>0, * the output contains all products of the form partd[]*pz^ez, ez>0,
* and with the exception of the 1, all these are appended. * and with the exception of the 1, all these are appended.
*/ */
for (int i = 1; i < partd.size(); i++) for (int i = 1; i < partd.size(); i++) {
d.add(partd.elementAt(i)); d.add(partd.elementAt(i));
}
for (int e = 1; e <= ez; e++) { for (int e = 1; e <= ez; e++) {
final BigInteger pzez = pz.pow(e); final BigInteger pzez = pz.pow(e);
for (int i = 0; i < partd.size(); i++) for (int i = 0; i < partd.size(); i++) {
d.add(partd.elementAt(i).multiply(pzez)); d.add(partd.elementAt(i).multiply(pzez));
}
} }
} }
Collections.sort(d); Collections.sort(d);
@ -561,11 +572,11 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
* the question is whether keeping a factorization is worth the effort * the question is whether keeping a factorization is worth the effort
* or whether one should simply multiply these to return a BigInteger... * or whether one should simply multiply these to return a BigInteger...
*/ */
if (n.compareTo(BigInteger.ONE) == 0) if (n.compareTo(BigInteger.ONE) == 0) {
return Ifactor.ONE; return Ifactor.ONE;
else if (n.compareTo(BigInteger.ZERO) == 0) } else if (n.compareTo(BigInteger.ZERO) == 0) {
return Ifactor.ZERO; return Ifactor.ZERO;
else { } else {
/* /*
* multiplicative: sigma_k(p^e) = [p^(k*(e+1))-1]/[p^k-1] * multiplicative: sigma_k(p^e) = [p^(k*(e+1))-1]/[p^k-1]
* sigma_0(p^e) = e+1. * sigma_0(p^e) = e+1.
@ -573,9 +584,9 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
Ifactor resul = Ifactor.ONE; Ifactor resul = Ifactor.ONE;
for (int i = 0; i < primeexp.size(); i += 2) { for (int i = 0; i < primeexp.size(); i += 2) {
final int ex = primeexp.elementAt(i + 1).intValue(); final int ex = primeexp.elementAt(i + 1).intValue();
if (k == 0) if (k == 0) {
resul = resul.multiply(ex + 1); resul = resul.multiply(ex + 1);
else { } else {
final Integer p = primeexp.elementAt(i); final Integer p = primeexp.elementAt(i);
final BigInteger num = new BigInteger(p.toString()).pow(k * (ex + 1)).subtract(BigInteger.ONE); final BigInteger num = new BigInteger(p.toString()).pow(k * (ex + 1)).subtract(BigInteger.ONE);
final BigInteger deno = new BigInteger(p.toString()).pow(k).subtract(BigInteger.ONE); final BigInteger deno = new BigInteger(p.toString()).pow(k).subtract(BigInteger.ONE);
@ -606,8 +617,9 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
/* /*
* the cases n==1 or n ==0 * the cases n==1 or n ==0
*/ */
if (n.compareTo(BigInteger.ONE) <= 0) if (n.compareTo(BigInteger.ONE) <= 0) {
return this; return this;
}
/* /*
* The cases n>1 * The cases n>1
@ -636,9 +648,11 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
/* /*
* check the exponents, located at the odd-indexed positions * check the exponents, located at the odd-indexed positions
*/ */
for (int i = 1; i < primeexp.size(); i += 2) for (int i = 1; i < primeexp.size(); i += 2) {
if (primeexp.elementAt(i).intValue() % 2 != 0) if (primeexp.elementAt(i).intValue() % 2 != 0) {
return false; return false;
}
}
return true; return true;
} /* Ifactor.issquare */ } /* Ifactor.issquare */
@ -649,8 +663,9 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
*/ */
public int bigomega() { public int bigomega() {
int resul = 0; int resul = 0;
for (int i = 1; i < primeexp.size(); i += 2) for (int i = 1; i < primeexp.size(); i += 2) {
resul += primeexp.elementAt(i).intValue(); resul += primeexp.elementAt(i).intValue();
}
return resul; return resul;
} /* Ifactor.bigomega */ } /* Ifactor.bigomega */
@ -672,9 +687,11 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
*/ */
public BigInteger core() { public BigInteger core() {
BigInteger resul = BigInteger.ONE; BigInteger resul = BigInteger.ONE;
for (int i = 0; i < primeexp.size(); i += 2) for (int i = 0; i < primeexp.size(); i += 2) {
if (primeexp.elementAt(i + 1).intValue() % 2 != 0) if (primeexp.elementAt(i + 1).intValue() % 2 != 0) {
resul = resul.multiply(new BigInteger(primeexp.elementAt(i).toString())); resul = resul.multiply(new BigInteger(primeexp.elementAt(i).toString()));
}
}
return resul; return resul;
} /* Ifactor.core */ } /* Ifactor.core */
@ -687,17 +704,19 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
* @return the moebius function. * @return the moebius function.
*/ */
public int moebius() { public int moebius() {
if (n.compareTo(BigInteger.ONE) <= 0) if (n.compareTo(BigInteger.ONE) <= 0) {
return 1; return 1;
}
/* accumulate number of different primes in k */ /* accumulate number of different primes in k */
int k = 1; int k = 1;
for (int i = 0; i < primeexp.size(); i += 2) { for (int i = 0; i < primeexp.size(); i += 2) {
final int e = primeexp.elementAt(i + 1).intValue(); final int e = primeexp.elementAt(i + 1).intValue();
if (e > 1) if (e > 1) {
return 0; return 0;
else if (e == 1) } else if (e == 1) {
/* accumulates (-1)^k */ /* accumulates (-1)^k */
k *= -1; k *= -1;
}
} }
return k; return k;
@ -711,10 +730,11 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
* @return the larger of the two values. * @return the larger of the two values.
*/ */
public Ifactor max(final Ifactor oth) { public Ifactor max(final Ifactor oth) {
if (n.compareTo(oth.n) >= 0) if (n.compareTo(oth.n) >= 0) {
return this; return this;
else } else {
return oth; return oth;
}
} /* Ifactor.max */ } /* Ifactor.max */
/** /**
@ -725,10 +745,11 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
* @return the smaller of the two values. * @return the smaller of the two values.
*/ */
public Ifactor min(final Ifactor oth) { public Ifactor min(final Ifactor oth) {
if (n.compareTo(oth.n) <= 0) if (n.compareTo(oth.n) <= 0) {
return this; return this;
else } else {
return oth; return oth;
}
} /* Ifactor.min */ } /* Ifactor.min */
/** /**
@ -740,8 +761,9 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
*/ */
public static Ifactor max(final Vector<Ifactor> set) { public static Ifactor max(final Vector<Ifactor> set) {
Ifactor resul = set.elementAt(0); Ifactor resul = set.elementAt(0);
for (int i = 1; i < set.size(); i++) for (int i = 1; i < set.size(); i++) {
resul = resul.max(set.elementAt(i)); resul = resul.max(set.elementAt(i));
}
return resul; return resul;
} /* Ifactor.max */ } /* Ifactor.max */
@ -754,8 +776,9 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
*/ */
public static Ifactor min(final Vector<Ifactor> set) { public static Ifactor min(final Vector<Ifactor> set) {
Ifactor resul = set.elementAt(0); Ifactor resul = set.elementAt(0);
for (int i = 1; i < set.size(); i++) for (int i = 1; i < set.size(); i++) {
resul = resul.min(set.elementAt(i)); resul = resul.min(set.elementAt(i));
}
return resul; return resul;
} /* Ifactor.min */ } /* Ifactor.min */
@ -781,17 +804,19 @@ public class Ifactor implements Cloneable, Comparable<Ifactor> {
@Override @Override
public String toString() { public String toString() {
String resul = new String(n.toString() + ":"); String resul = new String(n.toString() + ":");
if (n.compareTo(BigInteger.ONE) == 0) if (n.compareTo(BigInteger.ONE) == 0) {
resul += "1"; resul += "1";
else { } else {
boolean firstMul = true; boolean firstMul = true;
for (int i = 0; i < primeexp.size(); i += 2) { for (int i = 0; i < primeexp.size(); i += 2) {
if (!firstMul) if (!firstMul) {
resul += "*"; resul += "*";
if (primeexp.elementAt(i + 1).intValue() > 1) }
if (primeexp.elementAt(i + 1).intValue() > 1) {
resul += primeexp.elementAt(i).toString() + "^" + primeexp.elementAt(i + 1).toString(); resul += primeexp.elementAt(i).toString() + "^" + primeexp.elementAt(i + 1).toString();
else } else {
resul += primeexp.elementAt(i).toString(); resul += primeexp.elementAt(i).toString();
}
firstMul = false; firstMul = false;
} }
} }

View File

@ -48,8 +48,9 @@ public class PartitionsP {
* If the current list is too small, increase in intervals * If the current list is too small, increase in intervals
* of 3 until the list has at least i elements. * of 3 until the list has at least i elements.
*/ */
while (i > PartitionsP.nMax.intValue()) while (i > PartitionsP.nMax.intValue()) {
growto(PartitionsP.nMax.add(new BigInteger("" + 3))); growto(PartitionsP.nMax.add(new BigInteger("" + 3)));
}
return PartitionsP.a.elementAt(i); return PartitionsP.a.elementAt(i);
} /* at */ } /* at */

View File

@ -86,13 +86,13 @@ public class Prime {
/* /*
* numbers less than 2 are not prime * numbers less than 2 are not prime
*/ */
if (n.compareTo(two) == -1) if (n.compareTo(two) == -1) {
return false; return false;
else if (n.compareTo(two) == 0) } else if (n.compareTo(two) == 0) {
return true; return true;
else if (n.remainder(two).compareTo(BigInteger.ZERO) == 0) } else if (n.remainder(two).compareTo(BigInteger.ZERO) == 0) {
return false; return false;
else { } else {
/* /*
* q= n- 1 = d *2^s with d odd * q= n- 1 = d *2^s with d odd
*/ */
@ -103,15 +103,18 @@ public class Prime {
/* /*
* test whether a^d = 1 (mod n) * test whether a^d = 1 (mod n)
*/ */
if (a.modPow(d, n).compareTo(BigInteger.ONE) == 0) if (a.modPow(d, n).compareTo(BigInteger.ONE) == 0) {
return true; return true;
}
/* /*
* test whether a^(d*2^r) = -1 (mod n), 0<=r<s * test whether a^(d*2^r) = -1 (mod n), 0<=r<s
*/ */
for (int r = 0; r < s; r++) for (int r = 0; r < s; r++) {
if (a.modPow(d.shiftLeft(r), n).compareTo(q) == 0) if (a.modPow(d.shiftLeft(r), n).compareTo(q) == 0) {
return true; return true;
}
}
return false; return false;
} }
} }
@ -134,24 +137,28 @@ public class Prime {
int mrLim = 0; int mrLim = 0;
while (mrLim < mr.length) { while (mrLim < mr.length) {
final int l = n.compareTo(new BigInteger(mr[mrLim])); final int l = n.compareTo(new BigInteger(mr[mrLim]));
if (l < 0) if (l < 0) {
break; break;
else if (l == 0) } else if (l == 0) {
return -1; return -1;
}
mrLim++; mrLim++;
} }
/* /*
* cannot test candidates larger than the last in the mr list * cannot test candidates larger than the last in the mr list
*/ */
if (mrLim == mr.length) if (mrLim == mr.length) {
return 0; return 0;
}
/* /*
* test the bases prime(1), prime(2) up to prime(mrLim+1) * test the bases prime(1), prime(2) up to prime(mrLim+1)
*/ */
for (int p = 0; p <= mrLim; p++) for (int p = 0; p <= mrLim; p++) {
if (isSPP(n, at(p)) == false) if (isSPP(n, at(p)) == false) {
return -1; return -1;
}
}
return 1; return 1;
} }
@ -167,8 +174,9 @@ public class Prime {
* If the current list is too small, increase in intervals * If the current list is too small, increase in intervals
* of 5 until the list has at least i elements. * of 5 until the list has at least i elements.
*/ */
while (i >= Prime.a.size()) while (i >= Prime.a.size()) {
growto(Prime.nMax.add(new BigInteger("" + 5))); growto(Prime.nMax.add(new BigInteger("" + 5)));
}
return Prime.a.elementAt(i); return Prime.a.elementAt(i);
} }
@ -186,9 +194,11 @@ public class Prime {
*/ */
growto(n); growto(n);
BigInteger r = new BigInteger("0"); BigInteger r = new BigInteger("0");
for (int i = 0; i < Prime.a.size(); i++) for (int i = 0; i < Prime.a.size(); i++) {
if (Prime.a.elementAt(i).compareTo(n) <= 0) if (Prime.a.elementAt(i).compareTo(n) <= 0) {
r = r.add(BigInteger.ONE); r = r.add(BigInteger.ONE);
}
}
return r; return r;
} }
@ -202,19 +212,23 @@ public class Prime {
*/ */
public BigInteger nextprime(final BigInteger n) { public BigInteger nextprime(final BigInteger n) {
/* if n <=1, return 2 */ /* if n <=1, return 2 */
if (n.compareTo(BigInteger.ONE) <= 0) if (n.compareTo(BigInteger.ONE) <= 0) {
return Prime.a.elementAt(0); return Prime.a.elementAt(0);
}
/* /*
* If the currently largest element in the list is too small, increase * If the currently largest element in the list is too small, increase
* in intervals * in intervals
* of 5 until the list has at least i elements. * of 5 until the list has at least i elements.
*/ */
while (Prime.a.lastElement().compareTo(n) <= 0) while (Prime.a.lastElement().compareTo(n) <= 0) {
growto(Prime.nMax.add(new BigInteger("" + 5))); growto(Prime.nMax.add(new BigInteger("" + 5)));
for (int i = 0; i < Prime.a.size(); i++) }
if (Prime.a.elementAt(i).compareTo(n) == 1) for (int i = 0; i < Prime.a.size(); i++) {
if (Prime.a.elementAt(i).compareTo(n) == 1) {
return Prime.a.elementAt(i); return Prime.a.elementAt(i);
}
}
return Prime.a.lastElement(); return Prime.a.lastElement();
} }
@ -228,20 +242,24 @@ public class Prime {
*/ */
public BigInteger prevprime(final BigInteger n) { public BigInteger prevprime(final BigInteger n) {
/* if n <=2, return 0 */ /* if n <=2, return 0 */
if (n.compareTo(BigInteger.ONE) <= 0) if (n.compareTo(BigInteger.ONE) <= 0) {
return BigInteger.ZERO; return BigInteger.ZERO;
}
/* /*
* If the currently largest element in the list is too small, increase * If the currently largest element in the list is too small, increase
* in intervals * in intervals
* of 5 until the list has at least i elements. * of 5 until the list has at least i elements.
*/ */
while (Prime.a.lastElement().compareTo(n) < 0) while (Prime.a.lastElement().compareTo(n) < 0) {
growto(Prime.nMax.add(new BigInteger("" + 5))); growto(Prime.nMax.add(new BigInteger("" + 5)));
}
for (int i = 0; i < Prime.a.size(); i++) for (int i = 0; i < Prime.a.size(); i++) {
if (Prime.a.elementAt(i).compareTo(n) >= 0) if (Prime.a.elementAt(i).compareTo(n) >= 0) {
return Prime.a.elementAt(i - 1); return Prime.a.elementAt(i - 1);
}
}
return Prime.a.lastElement(); return Prime.a.lastElement();
} }
@ -260,8 +278,9 @@ public class Prime {
/* /*
* Test the list of known primes only up to sqrt(n) * Test the list of known primes only up to sqrt(n)
*/ */
if (Prime.a.get(p).multiply(Prime.a.get(p)).compareTo(Prime.nMax) == 1) if (Prime.a.get(p).multiply(Prime.a.get(p)).compareTo(Prime.nMax) == 1) {
break; break;
}
/* /*
* The next case means that the p'th number in the list of known * The next case means that the p'th number in the list of known
@ -273,8 +292,9 @@ public class Prime {
break; break;
} }
} }
if (isp) if (isp) {
Prime.a.add(Prime.nMax); Prime.a.add(Prime.nMax);
}
} }
} }
@ -290,8 +310,9 @@ public class Prime {
final Prime a = new Prime(); final Prime a = new Prime();
final int n = new Integer(args[0]).intValue(); final int n = new Integer(args[0]).intValue();
if (n >= 1) { if (n >= 1) {
if (n >= 2) if (n >= 2) {
System.out.println("prime(" + (n - 1) + ") = " + a.at(n - 1)); System.out.println("prime(" + (n - 1) + ") = " + a.at(n - 1));
}
System.out.println("prime(" + n + ") = " + a.at(n)); System.out.println("prime(" + n + ") = " + a.at(n));
System.out.println("prime(" + (n + 1) + ") = " + a.at(n + 1)); System.out.println("prime(" + (n + 1) + ") = " + a.at(n + 1));
System.out.println("pi(" + n + ") = " + a.pi(new BigInteger("" + n))); System.out.println("pi(" + n + ") = " + a.pi(new BigInteger("" + n)));

View File

@ -43,8 +43,9 @@ class RatPoly {
*/ */
public RatPoly(final Vector<Rational> L) { public RatPoly(final Vector<Rational> L) {
a = new Vector<>(); a = new Vector<>();
for (int i = 0; i < L.size(); i++) for (int i = 0; i < L.size(); i++) {
a.add(L.elementAt(i).clone()); a.add(L.elementAt(i).clone());
}
simplify(); simplify();
} /* ctor */ } /* ctor */
@ -101,14 +102,18 @@ class RatPoly {
*/ */
public RatPoly(final Vector<BigInteger> A, final Vector<BigInteger> B) throws Error { public RatPoly(final Vector<BigInteger> A, final Vector<BigInteger> B) throws Error {
BigInteger Nmax = BigInteger.ONE.negate(); BigInteger Nmax = BigInteger.ONE.negate();
for (int j = 0; j < A.size(); j++) for (int j = 0; j < A.size(); j++) {
if (A.elementAt(j).compareTo(BigInteger.ZERO) <= 0) if (A.elementAt(j).compareTo(BigInteger.ZERO) <= 0) {
if (Nmax.compareTo(BigInteger.ZERO) < 0) if (Nmax.compareTo(BigInteger.ZERO) < 0) {
Nmax = A.elementAt(j).negate(); Nmax = A.elementAt(j).negate();
else } else {
Nmax = Nmax.min(A.elementAt(j).negate()); Nmax = Nmax.min(A.elementAt(j).negate());
if (Nmax.compareTo(BigInteger.ZERO) < 0) }
}
}
if (Nmax.compareTo(BigInteger.ZERO) < 0) {
throw new ArithmeticException("Infinite Number of Terms in Series " + Nmax.toString()); throw new ArithmeticException("Infinite Number of Terms in Series " + Nmax.toString());
}
final int nmax = Nmax.intValue() - 1; final int nmax = Nmax.intValue() - 1;
init(A, B, nmax); init(A, B, nmax);
@ -167,10 +172,11 @@ class RatPoly {
* @return the polynomial coefficient in front of x^n. * @return the polynomial coefficient in front of x^n.
*/ */
public Rational at(final int n) { public Rational at(final int n) {
if (n < a.size()) if (n < a.size()) {
return a.elementAt(n); return a.elementAt(n);
else } else {
return new Rational(0, 1); return new Rational(0, 1);
}
} /* at */ } /* at */
/** /**
@ -185,8 +191,9 @@ class RatPoly {
public BigComplex valueOf(final BigComplex x, final MathContext mc) { public BigComplex valueOf(final BigComplex x, final MathContext mc) {
/* result is initialized to zero */ /* result is initialized to zero */
BigComplex f = new BigComplex(); BigComplex f = new BigComplex();
for (int i = degree(); i >= 0; i--) for (int i = degree(); i >= 0; i--) {
f = f.multiply(x, mc).add(a.elementAt(i).BigDecimalValue(mc)); f = f.multiply(x, mc).add(a.elementAt(i).BigDecimalValue(mc));
}
return f; return f;
} /* valueOf */ } /* valueOf */
@ -200,8 +207,9 @@ class RatPoly {
public Rational valueOf(final Rational x) { public Rational valueOf(final Rational x) {
/* result is initialized to zero */ /* result is initialized to zero */
Rational f = new Rational(0, 1); Rational f = new Rational(0, 1);
for (int i = degree(); i >= 0; i--) for (int i = degree(); i >= 0; i--) {
f = f.multiply(x).add(a.elementAt(i)); f = f.multiply(x).add(a.elementAt(i));
}
return f; return f;
} /* valueOf */ } /* valueOf */
@ -238,14 +246,15 @@ class RatPoly {
* @param value the new value of the coefficient. * @param value the new value of the coefficient.
*/ */
public void set(final int n, final Rational value) { public void set(final int n, final Rational value) {
if (n < a.size()) if (n < a.size()) {
a.set(n, value); a.set(n, value);
else { } else {
/* /*
* fill intermediate powers with coefficients of zero * fill intermediate powers with coefficients of zero
*/ */
while (a.size() < n) while (a.size() < n) {
a.add(new Rational(0, 1)); a.add(new Rational(0, 1));
}
a.add(value); a.add(value);
} }
} /* set */ } /* set */
@ -292,8 +301,9 @@ class RatPoly {
public void setExp(final int nmax) { public void setExp(final int nmax) {
a.clear(); a.clear();
final Factorial factorial = new Factorial(); final Factorial factorial = new Factorial();
for (int n = 0; n <= nmax; n++) for (int n = 0; n <= nmax; n++) {
set(n, new Rational(BigInteger.ONE, factorial.at(n))); set(n, new Rational(BigInteger.ONE, factorial.at(n)));
}
} /* setExp */ } /* setExp */
/** /**
@ -334,9 +344,11 @@ class RatPoly {
* @since 2010-08-27 * @since 2010-08-27
*/ */
public int ldegree() { public int ldegree() {
for (int n = 0; n < a.size(); n++) for (int n = 0; n < a.size(); n++) {
if (a.elementAt(n).compareTo(BigInteger.ZERO) != 0) if (a.elementAt(n).compareTo(BigInteger.ZERO) != 0) {
return n; return n;
}
}
return 0; return 0;
} /* ldegree */ } /* ldegree */
@ -351,9 +363,11 @@ class RatPoly {
*/ */
public RatPoly multiply(final Rational val) { public RatPoly multiply(final Rational val) {
final RatPoly resul = new RatPoly(); final RatPoly resul = new RatPoly();
if (val.compareTo(BigInteger.ZERO) != 0) if (val.compareTo(BigInteger.ZERO) != 0) {
for (int n = 0; n < a.size(); n++) for (int n = 0; n < a.size(); n++) {
resul.set(n, a.elementAt(n).multiply(val)); resul.set(n, a.elementAt(n).multiply(val));
}
}
return resul; return resul;
} /* multiply */ } /* multiply */
@ -369,9 +383,11 @@ class RatPoly {
*/ */
public RatPoly multiply(final BigInteger val) { public RatPoly multiply(final BigInteger val) {
final RatPoly resul = new RatPoly(); final RatPoly resul = new RatPoly();
if (val.compareTo(BigInteger.ZERO) != 0) if (val.compareTo(BigInteger.ZERO) != 0) {
for (int n = 0; n < a.size(); n++) for (int n = 0; n < a.size(); n++) {
resul.set(n, a.elementAt(n).multiply(val)); resul.set(n, a.elementAt(n).multiply(val));
}
}
return resul; return resul;
} /* multiply */ } /* multiply */
@ -390,8 +406,9 @@ class RatPoly {
final int nmax = degree() + val.degree(); final int nmax = degree() + val.degree();
for (int n = 0; n <= nmax; n++) { for (int n = 0; n <= nmax; n++) {
Rational coef = new Rational(0, 1); Rational coef = new Rational(0, 1);
for (int nleft = 0; nleft <= n; nleft++) for (int nleft = 0; nleft <= n; nleft++) {
coef = coef.add(at(nleft).multiply(val.at(n - nleft))); coef = coef.add(at(nleft).multiply(val.at(n - nleft)));
}
resul.set(n, coef); resul.set(n, coef);
} }
resul.simplify(); resul.simplify();
@ -407,15 +424,16 @@ class RatPoly {
*/ */
public RatPoly pow(final int n) throws ArithmeticException { public RatPoly pow(final int n) throws ArithmeticException {
RatPoly resul = new RatPoly("1"); RatPoly resul = new RatPoly("1");
if (n < 0) if (n < 0) {
throw new ArithmeticException("negative polynomial power " + n); throw new ArithmeticException("negative polynomial power " + n);
else { } else {
/* /*
* this ought probably be done with some binary representation * this ought probably be done with some binary representation
* of the power and a smaller number of multiplications. * of the power and a smaller number of multiplications.
*/ */
for (int i = 1; i <= n; i++) for (int i = 1; i <= n; i++) {
resul = resul.multiply(this); resul = resul.multiply(this);
}
resul.simplify(); resul.simplify();
return resul; return resul;
} }
@ -523,11 +541,13 @@ class RatPoly {
public RatPoly divide(final Rational val) throws Error { public RatPoly divide(final Rational val) throws Error {
if (val.compareTo(Rational.ZERO) != 0) { if (val.compareTo(Rational.ZERO) != 0) {
final RatPoly resul = new RatPoly(); final RatPoly resul = new RatPoly();
for (int n = 0; n < a.size(); n++) for (int n = 0; n < a.size(); n++) {
resul.set(n, a.elementAt(n).divide(val)); resul.set(n, a.elementAt(n).divide(val));
}
return resul; return resul;
} else } else {
throw new ArithmeticException("Cannot divide " + toPString() + " through zero."); throw new ArithmeticException("Cannot divide " + toPString() + " through zero.");
}
} /* divide */ } /* divide */
/** /**
@ -550,8 +570,9 @@ class RatPoly {
while (num.at(0).compareTo(BigInteger.ZERO) == 0 && denom.at(0).compareTo(BigInteger.ZERO) == 0) { while (num.at(0).compareTo(BigInteger.ZERO) == 0 && denom.at(0).compareTo(BigInteger.ZERO) == 0) {
num.a.remove(0); num.a.remove(0);
denom.a.remove(0); denom.a.remove(0);
if (num.size() <= 1 || denom.size() <= 1) if (num.size() <= 1 || denom.size() <= 1) {
break; break;
}
} }
final RatPoly resul = new RatPoly(); final RatPoly resul = new RatPoly();
@ -561,8 +582,9 @@ class RatPoly {
*/ */
for (int n = 0; n <= nmax; n++) { for (int n = 0; n <= nmax; n++) {
Rational coef = num.at(n); Rational coef = num.at(n);
for (int nres = 0; nres < n; nres++) for (int nres = 0; nres < n; nres++) {
coef = coef.subtract(resul.at(nres).multiply(denom.at(n - nres))); coef = coef.subtract(resul.at(nres).multiply(denom.at(n - nres)));
}
coef = coef.divide(denom.at(0)); coef = coef.divide(denom.at(0));
resul.set(n, coef); resul.set(n, coef);
} }
@ -595,8 +617,9 @@ class RatPoly {
/* /*
* catch the case with val equal to zero * catch the case with val equal to zero
*/ */
if (valSimpl.degree() == 0 && valSimpl.a.firstElement().compareTo(Rational.ZERO) == 0) if (valSimpl.degree() == 0 && valSimpl.a.firstElement().compareTo(Rational.ZERO) == 0) {
throw new ArithmeticException("Division through zero polynomial"); throw new ArithmeticException("Division through zero polynomial");
}
/* /*
* degree of this smaller than degree of val: remainder is this * degree of this smaller than degree of val: remainder is this
*/ */
@ -624,9 +647,9 @@ class RatPoly {
/* /*
* any remainder left ? * any remainder left ?
*/ */
if (ret[1].degree() < valSimpl.degree()) if (ret[1].degree() < valSimpl.degree()) {
; ;
else { } else {
final RatPoly rem[] = ret[1].divideAndRemainder(val); final RatPoly rem[] = ret[1].divideAndRemainder(val);
ret[0] = ret[0].add(rem[0]); ret[0] = ret[0].add(rem[0]);
ret[1] = rem[1]; ret[1] = rem[1];
@ -646,16 +669,19 @@ class RatPoly {
@Override @Override
public String toString() { public String toString() {
String str = new String(); String str = new String();
for (int n = 0; n < a.size(); n++) for (int n = 0; n < a.size(); n++) {
if (n == 0) if (n == 0) {
str += a.elementAt(n).toString(); str += a.elementAt(n).toString();
else } else {
str += "," + a.elementAt(n).toString(); str += "," + a.elementAt(n).toString();
}
}
/* /*
* print at least a sole zero * print at least a sole zero
*/ */
if (str.length() == 0) if (str.length() == 0) {
str = "0"; str = "0";
}
return str; return str;
} /* toString */ } /* toString */
@ -672,21 +698,24 @@ class RatPoly {
final BigInteger num = a.elementAt(n).a; final BigInteger num = a.elementAt(n).a;
if (num.compareTo(BigInteger.ZERO) != 0) { if (num.compareTo(BigInteger.ZERO) != 0) {
str += " "; str += " ";
if (num.compareTo(BigInteger.ZERO) > 0) if (num.compareTo(BigInteger.ZERO) > 0) {
str += "+"; str += "+";
}
str += a.elementAt(n).toString(); str += a.elementAt(n).toString();
if (n > 0) { if (n > 0) {
str += "*x"; str += "*x";
if (n > 1) if (n > 1) {
str += "^" + n; str += "^" + n;
}
} }
} }
} }
/* /*
* print at least a sole zero * print at least a sole zero
*/ */
if (str.length() == 0) if (str.length() == 0) {
str = "0"; str = "0";
}
return str; return str;
} /* toPString */ } /* toPString */
@ -698,12 +727,14 @@ class RatPoly {
*/ */
private void simplify() { private void simplify() {
int n = a.size() - 1; int n = a.size() - 1;
if (n >= 0) if (n >= 0) {
while (a.elementAt(n).compareTo(BigInteger.ZERO) == 0) { while (a.elementAt(n).compareTo(BigInteger.ZERO) == 0) {
a.remove(n); a.remove(n);
if (--n < 0) if (--n < 0) {
break; break;
}
} }
}
} /* simplify */ } /* simplify */
/** /**
@ -713,12 +744,12 @@ class RatPoly {
* @since 2008-10-26 * @since 2008-10-26
*/ */
public RatPoly derive() { public RatPoly derive() {
if (a.size() <= 1) if (a.size() <= 1) {
/* /*
* derivative of the constant is just zero * derivative of the constant is just zero
*/ */
return new RatPoly(); return new RatPoly();
else { } else {
final RatPoly d = new RatPoly(); final RatPoly d = new RatPoly();
for (int i = 1; i <= degree(); i++) { for (int i = 1; i <= degree(); i++) {
final Rational c = a.elementAt(i).multiply(i); final Rational c = a.elementAt(i).multiply(i);
@ -762,11 +793,12 @@ class RatPoly {
final RatPoly r = new RatPoly(); final RatPoly r = new RatPoly();
for (int i = 1; i <= maxdeg; i++) { for (int i = 1; i <= maxdeg; i++) {
Rational c = new Rational(); Rational c = new Rational();
for (int d = 1; d <= i && d < a.size(); d++) for (int d = 1; d <= i && d < a.size(); d++) {
if (i % d == 0) { if (i % d == 0) {
final Ifactor m = new Ifactor(i / d); final Ifactor m = new Ifactor(i / d);
c = c.add(a.elementAt(d).multiply(m.moebius())); c = c.add(a.elementAt(d).multiply(m.moebius()));
} }
}
r.set(i, c); r.set(i, c);
} }
r.simplify(); r.simplify();
@ -789,9 +821,11 @@ class RatPoly {
final RatPoly r = new RatPoly(); final RatPoly r = new RatPoly();
for (int i = 1; i <= maxdeg; i++) { for (int i = 1; i <= maxdeg; i++) {
Rational c = new Rational(); Rational c = new Rational();
for (int d = 1; d <= i && d < a.size(); d++) for (int d = 1; d <= i && d < a.size(); d++) {
if (i % d == 0) if (i % d == 0) {
c = c.add(a.elementAt(d)); c = c.add(a.elementAt(d));
}
}
r.set(i, c); r.set(i, c);
} }
r.simplify(); r.simplify();
@ -811,8 +845,9 @@ class RatPoly {
final RatPoly r = new RatPoly(); final RatPoly r = new RatPoly();
for (int i = 0; i <= maxdeg; i++) { for (int i = 0; i <= maxdeg; i++) {
Rational c = new Rational(0, 1); Rational c = new Rational(0, 1);
for (int j = 0; j <= i && j < a.size(); j++) for (int j = 0; j <= i && j < a.size(); j++) {
c = c.add(a.elementAt(j).multiply(BigIntegerMath.binomial(i, j))); c = c.add(a.elementAt(j).multiply(BigIntegerMath.binomial(i, j)));
}
r.set(i, c); r.set(i, c);
} }
r.simplify(); r.simplify();
@ -832,11 +867,13 @@ class RatPoly {
final RatPoly r = new RatPoly(); final RatPoly r = new RatPoly();
for (int i = 0; i <= maxdeg; i++) { for (int i = 0; i <= maxdeg; i++) {
Rational c = new Rational(0, 1); Rational c = new Rational(0, 1);
for (int j = 0; j <= i && j < a.size(); j++) for (int j = 0; j <= i && j < a.size(); j++) {
if ((j + i) % 2 != 0) if ((j + i) % 2 != 0) {
c = c.subtract(a.elementAt(j).multiply(BigIntegerMath.binomial(i, j))); c = c.subtract(a.elementAt(j).multiply(BigIntegerMath.binomial(i, j)));
else } else {
c = c.add(a.elementAt(j).multiply(BigIntegerMath.binomial(i, j))); c = c.add(a.elementAt(j).multiply(BigIntegerMath.binomial(i, j)));
}
}
r.set(i, c); r.set(i, c);
} }
r.simplify(); r.simplify();
@ -859,8 +896,9 @@ class RatPoly {
*/ */
public RatPoly trunc(final int newdeg) { public RatPoly trunc(final int newdeg) {
final RatPoly t = new RatPoly(); final RatPoly t = new RatPoly();
for (int i = 0; i <= newdeg; i++) for (int i = 0; i <= newdeg; i++) {
t.set(i, at(i)); t.set(i, at(i));
}
t.simplify(); t.simplify();
return t; return t;
} /* trunc */ } /* trunc */
@ -888,8 +926,9 @@ class RatPoly {
for (int i = 0; i <= d; i++) { for (int i = 0; i <= d; i++) {
/* scale coefficient at maximum degree */ /* scale coefficient at maximum degree */
final double absi = Math.abs(mon.at(i).doubleValue()); final double absi = Math.abs(mon.at(i).doubleValue());
if (absi > randRad) if (absi > randRad) {
randRad = absi; randRad = absi;
}
} }
randRad += 1.0; randRad += 1.0;
@ -919,19 +958,23 @@ class RatPoly {
*/ */
BigComplex thisx = res.elementAt(v); BigComplex thisx = res.elementAt(v);
BigComplex nv = mon.valueOf(thisx, mc); BigComplex nv = mon.valueOf(thisx, mc);
for (int j = 0; j < d; j++) for (int j = 0; j < d; j++) {
if (j != v) if (j != v) {
nv = nv.divide(thisx.subtract(res.elementAt(j)), mc); nv = nv.divide(thisx.subtract(res.elementAt(j)), mc);
}
}
/* is this value converged ? */ /* is this value converged ? */
if (nv.abs(mc).doubleValue() > thisx.abs(mc).doubleValue() * Math.pow(10.0, -digits)) if (nv.abs(mc).doubleValue() > thisx.abs(mc).doubleValue() * Math.pow(10.0, -digits)) {
convr = false; convr = false;
}
thisx = thisx.subtract(nv); thisx = thisx.subtract(nv);
/* If unstable, start over */ /* If unstable, start over */
if (thisx.abs(MathContext.DECIMAL32).doubleValue() > randRad) if (thisx.abs(MathContext.DECIMAL32).doubleValue() > randRad) {
return roots(digits); return roots(digits);
}
resPlus.add(thisx); resPlus.add(thisx);
} }
@ -969,8 +1012,9 @@ class RatPoly {
* start with denominator of first non-zero coefficient. * start with denominator of first non-zero coefficient.
*/ */
BigInteger lcmDeno = a.elementAt(lowd).b; BigInteger lcmDeno = a.elementAt(lowd).b;
for (int i = lowd + 1; i < degree(); i++) for (int i = lowd + 1; i < degree(); i++) {
lcmDeno = BigIntegerMath.lcm(lcmDeno, a.elementAt(i).b); lcmDeno = BigIntegerMath.lcm(lcmDeno, a.elementAt(i).b);
}
/* /*
* and eventually get the integer polynomial by ignoring the * and eventually get the integer polynomial by ignoring the

View File

@ -214,15 +214,17 @@ public class Rational implements Cloneable, Comparable<Rational> {
* exponent is 0, the value 1 is returned. * exponent is 0, the value 1 is returned.
*/ */
public Rational pow(final int exponent) { public Rational pow(final int exponent) {
if (exponent == 0) if (exponent == 0) {
return new Rational(1, 1); return new Rational(1, 1);
}
final BigInteger num = a.pow(Math.abs(exponent)); final BigInteger num = a.pow(Math.abs(exponent));
final BigInteger deno = b.pow(Math.abs(exponent)); final BigInteger deno = b.pow(Math.abs(exponent));
if (exponent > 0) if (exponent > 0) {
return new Rational(num, deno); return new Rational(num, deno);
else } else {
return new Rational(deno, num); return new Rational(deno, num);
}
} /* Rational.pow */ } /* Rational.pow */
/** /**
@ -237,10 +239,12 @@ public class Rational implements Cloneable, Comparable<Rational> {
*/ */
public Rational pow(final BigInteger exponent) throws Error { public Rational pow(final BigInteger exponent) throws Error {
/* test for overflow */ /* test for overflow */
if (exponent.compareTo(Rational.MAX_INT) == 1) if (exponent.compareTo(Rational.MAX_INT) == 1) {
throw new Error(Errors.NUMBER_TOO_LARGE); throw new Error(Errors.NUMBER_TOO_LARGE);
if (exponent.compareTo(Rational.MIN_INT) == -1) }
if (exponent.compareTo(Rational.MIN_INT) == -1) {
throw new Error(Errors.NUMBER_TOO_SMALL); throw new Error(Errors.NUMBER_TOO_SMALL);
}
/* promote to the simpler interface above */ /* promote to the simpler interface above */
return pow(exponent.intValue()); return pow(exponent.intValue());
@ -259,15 +263,18 @@ public class Rational implements Cloneable, Comparable<Rational> {
*/ */
public Rational root(final BigInteger r) throws Error { public Rational root(final BigInteger r) throws Error {
/* test for overflow */ /* test for overflow */
if (r.compareTo(Rational.MAX_INT) == 1) if (r.compareTo(Rational.MAX_INT) == 1) {
throw new Error(Errors.NUMBER_TOO_LARGE); throw new Error(Errors.NUMBER_TOO_LARGE);
if (r.compareTo(Rational.MIN_INT) == -1) }
if (r.compareTo(Rational.MIN_INT) == -1) {
throw new Error(Errors.NUMBER_TOO_SMALL); throw new Error(Errors.NUMBER_TOO_SMALL);
}
final int rthroot = r.intValue(); final int rthroot = r.intValue();
/* cannot pull root of a negative value with even-valued root */ /* cannot pull root of a negative value with even-valued root */
if (compareTo(Rational.ZERO) == -1 && rthroot % 2 == 0) if (compareTo(Rational.ZERO) == -1 && rthroot % 2 == 0) {
throw new Error(Errors.NEGATIVE_PARAMETER); throw new Error(Errors.NEGATIVE_PARAMETER);
}
/* /*
* extract a sign such that we calculate |n|^(1/r), still r carrying any * extract a sign such that we calculate |n|^(1/r), still r carrying any
@ -281,10 +288,11 @@ public class Rational implements Cloneable, Comparable<Rational> {
final Ifactor num = new Ifactor(a.abs()); final Ifactor num = new Ifactor(a.abs());
final Ifactor deno = new Ifactor(b); final Ifactor deno = new Ifactor(b);
final Rational resul = num.root(rthroot).divide(deno.root(rthroot)); final Rational resul = num.root(rthroot).divide(deno.root(rthroot));
if (flipsign) if (flipsign) {
return resul.negate(); return resul.negate();
else } else {
return resul; return resul;
}
} /* Rational.root */ } /* Rational.root */
/** /**
@ -298,8 +306,9 @@ public class Rational implements Cloneable, Comparable<Rational> {
* @since 2009-05-18 * @since 2009-05-18
*/ */
public Rational pow(final Rational exponent) throws Error { public Rational pow(final Rational exponent) throws Error {
if (exponent.a.compareTo(BigInteger.ZERO) == 0) if (exponent.a.compareTo(BigInteger.ZERO) == 0) {
return new Rational(1, 1); return new Rational(1, 1);
}
/* /*
* calculate (a/b)^(exponent.a/exponent.b) as * calculate (a/b)^(exponent.a/exponent.b) as
@ -318,8 +327,9 @@ public class Rational implements Cloneable, Comparable<Rational> {
* @throws Error * @throws Error
*/ */
public Rational divide(final Rational val) throws Error { public Rational divide(final Rational val) throws Error {
if (val.compareTo(Rational.ZERO) == 0) if (val.compareTo(Rational.ZERO) == 0) {
throw new Error(Errors.DIVISION_BY_ZERO); throw new Error(Errors.DIVISION_BY_ZERO);
}
final BigInteger num = a.multiply(val.b); final BigInteger num = a.multiply(val.b);
final BigInteger deno = b.multiply(val.a); final BigInteger deno = b.multiply(val.a);
/* /*
@ -338,8 +348,9 @@ public class Rational implements Cloneable, Comparable<Rational> {
* @throws Error * @throws Error
*/ */
public Rational divide(final BigInteger val) throws Error { public Rational divide(final BigInteger val) throws Error {
if (val.compareTo(BigInteger.ZERO) == 0) if (val.compareTo(BigInteger.ZERO) == 0) {
throw new Error(Errors.DIVISION_BY_ZERO); throw new Error(Errors.DIVISION_BY_ZERO);
}
final Rational val2 = new Rational(val, BigInteger.ONE); final Rational val2 = new Rational(val, BigInteger.ONE);
return divide(val2); return divide(val2);
} /* Rational.divide */ } /* Rational.divide */
@ -353,8 +364,9 @@ public class Rational implements Cloneable, Comparable<Rational> {
* @throws Error * @throws Error
*/ */
public Rational divide(final int val) throws Error { public Rational divide(final int val) throws Error {
if (val == 0) if (val == 0) {
throw new Error(Errors.DIVISION_BY_ZERO); throw new Error(Errors.DIVISION_BY_ZERO);
}
final Rational val2 = new Rational(val, 1); final Rational val2 = new Rational(val, 1);
return divide(val2); return divide(val2);
} /* Rational.divide */ } /* Rational.divide */
@ -455,11 +467,13 @@ public class Rational implements Cloneable, Comparable<Rational> {
* @throws Error * @throws Error
*/ */
public static Rational binomial(final Rational n, final BigInteger m) throws Error { public static Rational binomial(final Rational n, final BigInteger m) throws Error {
if (m.compareTo(BigInteger.ZERO) == 0) if (m.compareTo(BigInteger.ZERO) == 0) {
return Rational.ONE; return Rational.ONE;
}
Rational bin = n; Rational bin = n;
for (BigInteger i = new BigInteger("2"); i.compareTo(m) != 1; i = i.add(BigInteger.ONE)) for (BigInteger i = new BigInteger("2"); i.compareTo(m) != 1; i = i.add(BigInteger.ONE)) {
bin = bin.multiply(n.subtract(i.subtract(BigInteger.ONE))).divide(i); bin = bin.multiply(n.subtract(i.subtract(BigInteger.ONE))).divide(i);
}
return bin; return bin;
} /* Rational.binomial */ } /* Rational.binomial */
@ -476,11 +490,13 @@ public class Rational implements Cloneable, Comparable<Rational> {
* @throws Error * @throws Error
*/ */
public static Rational binomial(final Rational n, final int m) throws Error { public static Rational binomial(final Rational n, final int m) throws Error {
if (m == 0) if (m == 0) {
return Rational.ONE; return Rational.ONE;
}
Rational bin = n; Rational bin = n;
for (int i = 2; i <= m; i++) for (int i = 2; i <= m; i++) {
bin = bin.multiply(n.subtract(i - 1)).divide(i); bin = bin.multiply(n.subtract(i - 1)).divide(i);
}
return bin; return bin;
} /* Rational.binomial */ } /* Rational.binomial */
@ -497,10 +513,11 @@ public class Rational implements Cloneable, Comparable<Rational> {
* @throws Error * @throws Error
*/ */
public static Rational hankelSymb(final Rational n, final int k) throws Error { public static Rational hankelSymb(final Rational n, final int k) throws Error {
if (k == 0) if (k == 0) {
return Rational.ONE; return Rational.ONE;
else if (k < 0) } else if (k < 0) {
throw new Error(Errors.NEGATIVE_PARAMETER); throw new Error(Errors.NEGATIVE_PARAMETER);
}
Rational nkhalf = n.subtract(k).add(Rational.HALF); Rational nkhalf = n.subtract(k).add(Rational.HALF);
nkhalf = nkhalf.Pochhammer(2 * k); nkhalf = nkhalf.Pochhammer(2 * k);
final Factorial f = new Factorial(); final Factorial f = new Factorial();
@ -543,12 +560,13 @@ public class Rational implements Cloneable, Comparable<Rational> {
/* /*
* is already integer: return the numerator * is already integer: return the numerator
*/ */
if (b.compareTo(BigInteger.ONE) == 0) if (b.compareTo(BigInteger.ONE) == 0) {
return a; return a;
else if (a.compareTo(BigInteger.ZERO) > 0) } else if (a.compareTo(BigInteger.ZERO) > 0) {
return a.divide(b); return a.divide(b);
else } else {
return a.divide(b).subtract(BigInteger.ONE); return a.divide(b).subtract(BigInteger.ONE);
}
} /* Rational.floor */ } /* Rational.floor */
/** /**
@ -561,12 +579,13 @@ public class Rational implements Cloneable, Comparable<Rational> {
/* /*
* is already integer: return the numerator * is already integer: return the numerator
*/ */
if (b.compareTo(BigInteger.ONE) == 0) if (b.compareTo(BigInteger.ONE) == 0) {
return a; return a;
else if (a.compareTo(BigInteger.ZERO) > 0) } else if (a.compareTo(BigInteger.ZERO) > 0) {
return a.divide(b).add(BigInteger.ONE); return a.divide(b).add(BigInteger.ONE);
else } else {
return a.divide(b); return a.divide(b);
}
} /* Rational.ceil */ } /* Rational.ceil */
/** /**
@ -578,10 +597,11 @@ public class Rational implements Cloneable, Comparable<Rational> {
/* /*
* is already integer: return the numerator * is already integer: return the numerator
*/ */
if (b.compareTo(BigInteger.ONE) == 0) if (b.compareTo(BigInteger.ONE) == 0) {
return a; return a;
else } else {
return a.divide(b); return a.divide(b);
}
} /* Rational.trunc */ } /* Rational.trunc */
/** /**
@ -624,10 +644,11 @@ public class Rational implements Cloneable, Comparable<Rational> {
*/ */
@Override @Override
public String toString() { public String toString() {
if (b.compareTo(BigInteger.ONE) != 0) if (b.compareTo(BigInteger.ONE) != 0) {
return a.toString() + "/" + b.toString(); return a.toString() + "/" + b.toString();
else } else {
return a.toString(); return a.toString();
}
} /* Rational.toString */ } /* Rational.toString */
/** /**
@ -693,8 +714,9 @@ public class Rational implements Cloneable, Comparable<Rational> {
final MathContext mc = new MathContext(digits, RoundingMode.DOWN); final MathContext mc = new MathContext(digits, RoundingMode.DOWN);
final BigDecimal f = new BigDecimal(a).divide(new BigDecimal(b), mc); final BigDecimal f = new BigDecimal(a).divide(new BigDecimal(b), mc);
return f.toString(); return f.toString();
} else } else {
return a.toString(); return a.toString();
}
} /* Rational.toFString */ } /* Rational.toFString */
/** /**
@ -706,10 +728,11 @@ public class Rational implements Cloneable, Comparable<Rational> {
* @since 2008-10-19 * @since 2008-10-19
*/ */
public Rational max(final Rational val) { public Rational max(final Rational val) {
if (compareTo(val) > 0) if (compareTo(val) > 0) {
return this; return this;
else } else {
return val; return val;
}
} /* Rational.max */ } /* Rational.max */
/** /**
@ -721,10 +744,11 @@ public class Rational implements Cloneable, Comparable<Rational> {
* @since 2008-10-19 * @since 2008-10-19
*/ */
public Rational min(final Rational val) { public Rational min(final Rational val) {
if (compareTo(val) < 0) if (compareTo(val) < 0) {
return this; return this;
else } else {
return val; return val;
}
} /* Rational.min */ } /* Rational.min */
/** /**
@ -736,18 +760,19 @@ public class Rational implements Cloneable, Comparable<Rational> {
* @since 2008-10-25 * @since 2008-10-25
*/ */
public Rational Pochhammer(final BigInteger n) { public Rational Pochhammer(final BigInteger n) {
if (n.compareTo(BigInteger.ZERO) < 0) if (n.compareTo(BigInteger.ZERO) < 0) {
return null; return null;
else if (n.compareTo(BigInteger.ZERO) == 0) } else if (n.compareTo(BigInteger.ZERO) == 0) {
return Rational.ONE; return Rational.ONE;
else { } else {
/* /*
* initialize results with the current value * initialize results with the current value
*/ */
Rational res = new Rational(a, b); Rational res = new Rational(a, b);
BigInteger i = BigInteger.ONE; BigInteger i = BigInteger.ONE;
for (; i.compareTo(n) < 0; i = i.add(BigInteger.ONE)) for (; i.compareTo(n) < 0; i = i.add(BigInteger.ONE)) {
res = res.multiply(add(i)); res = res.multiply(add(i));
}
return res; return res;
} }
} /* Rational.pochhammer */ } /* Rational.pochhammer */
@ -782,8 +807,9 @@ public class Rational implements Cloneable, Comparable<Rational> {
* @since 2010-05-26 * @since 2010-05-26
*/ */
public boolean isInteger() { public boolean isInteger() {
if (!isBigInteger()) if (!isBigInteger()) {
return false; return false;
}
return a.compareTo(Rational.MAX_INT) <= 0 && a.compareTo(Rational.MIN_INT) >= 0; return a.compareTo(Rational.MAX_INT) <= 0 && a.compareTo(Rational.MIN_INT) >= 0;
} /* Rational.isInteger */ } /* Rational.isInteger */
@ -795,8 +821,9 @@ public class Rational implements Cloneable, Comparable<Rational> {
* @since 2011-02-13 * @since 2011-02-13
*/ */
int intValue() throws Error { int intValue() throws Error {
if (!isInteger()) if (!isInteger()) {
throw new Error(Errors.CONVERSION_ERROR); throw new Error(Errors.CONVERSION_ERROR);
}
return a.intValue(); return a.intValue();
} }
@ -808,8 +835,9 @@ public class Rational implements Cloneable, Comparable<Rational> {
* @since 2012-03-02 * @since 2012-03-02
*/ */
BigInteger BigIntegerValue() throws Error { BigInteger BigIntegerValue() throws Error {
if (!isBigInteger()) if (!isBigInteger()) {
throw new Error(Errors.CONVERSION_ERROR); throw new Error(Errors.CONVERSION_ERROR);
}
return a; return a;
} }
@ -843,8 +871,9 @@ public class Rational implements Cloneable, Comparable<Rational> {
*/ */
static public BigInteger lcmDenom(final Rational[] vals) { static public BigInteger lcmDenom(final Rational[] vals) {
BigInteger l = BigInteger.ONE; BigInteger l = BigInteger.ONE;
for (final Rational val : vals) for (final Rational val : vals) {
l = BigIntegerMath.lcm(l, val.b); l = BigIntegerMath.lcm(l, val.b);
}
return l; return l;
} /* Rational.lcmDenom */ } /* Rational.lcmDenom */

View File

@ -35,33 +35,35 @@ public class Wigner3j {
* @throws Error * @throws Error
*/ */
static public void main(final String args[]) throws Error { static public void main(final String args[]) throws Error {
if (args[0].compareTo("6j") == 0) if (args[0].compareTo("6j") == 0) {
try { try {
final String m1 = "6"; final String m1 = "6";
final String t1 = "1 2 -3 -1 5 6"; final String t1 = "1 2 -3 -1 5 6";
final String t2 = "4 -5 3 -4 -2 -6"; final String t2 = "4 -5 3 -4 -2 -6";
String j = ""; String j = "";
for (int i = 1; i <= 6; i++) for (int i = 1; i <= 6; i++) {
j += args[i] + " "; j += args[i] + " ";
}
final BigSurdVec w = Wigner3j.wigner3j(m1, t1, t2, j); final BigSurdVec w = Wigner3j.wigner3j(m1, t1, t2, j);
System.out.println(w.toString()); System.out.println(w.toString());
} catch (final Exception e) { } catch (final Exception e) {
System.out.println(e.getMessage()); System.out.println(e.getMessage());
} }
else if (args[0].compareTo("9j") == 0) } else if (args[0].compareTo("9j") == 0) {
try { try {
final String m1 = "9"; final String m1 = "9";
final String t1 = "1 3 2 4 6 5 7 9 8"; final String t1 = "1 3 2 4 6 5 7 9 8";
final String t2 = "2 8 5 6 3 9 7 4 1"; final String t2 = "2 8 5 6 3 9 7 4 1";
String j = ""; String j = "";
for (int i = 1; i <= 9; i++) for (int i = 1; i <= 9; i++) {
j += args[i] + " "; j += args[i] + " ";
}
final BigSurdVec w = Wigner3j.wigner3j(m1, t1, t2, j); final BigSurdVec w = Wigner3j.wigner3j(m1, t1, t2, j);
System.out.println(w.toString()); System.out.println(w.toString());
} catch (final Exception e) { } catch (final Exception e) {
System.out.println(e.getMessage()); System.out.println(e.getMessage());
} }
else if (args[0].compareTo("3jm") == 0) { } else if (args[0].compareTo("3jm") == 0) {
final int j1 = new Integer(args[1]).intValue(); final int j1 = new Integer(args[1]).intValue();
final int j2 = new Integer(args[2]).intValue(); final int j2 = new Integer(args[2]).intValue();
final int j3 = new Integer(args[3]).intValue(); final int j3 = new Integer(args[3]).intValue();
@ -184,14 +186,16 @@ public class Wigner3j {
*/ */
s = new Scanner(t1); s = new Scanner(t1);
int ti = 0; int ti = 0;
while (s.hasNextInt()) while (s.hasNextInt()) {
tvec[ti++] = s.nextInt(); tvec[ti++] = s.nextInt();
}
s.close(); s.close();
s = new Scanner(t2); s = new Scanner(t2);
while (s.hasNextInt()) while (s.hasNextInt()) {
tvec[ti++] = s.nextInt(); tvec[ti++] = s.nextInt();
}
/* /*
* Basic sanity checks. All indices in the first two lines address a * Basic sanity checks. All indices in the first two lines address a
@ -207,8 +211,9 @@ public class Wigner3j {
} }
final int[] jfreq = new int[m]; final int[] jfreq = new int[m];
for (ji = 0; ji < jfreq.length; ji++) for (ji = 0; ji < jfreq.length; ji++) {
jfreq[ji] = 0; jfreq[ji] = 0;
}
/* /*
* maintain a 0-based index which shows where the j-value has its first * maintain a 0-based index which shows where the j-value has its first
@ -235,16 +240,18 @@ public class Wigner3j {
* one and divide through 2. * one and divide through 2.
*/ */
final Rational[] J = new Rational[jvec.length]; final Rational[] J = new Rational[jvec.length];
for (ji = 0; ji < jvec.length; ji++) for (ji = 0; ji < jvec.length; ji++) {
J[ji] = new Rational(jvec[ji] - 1, 2); J[ji] = new Rational(jvec[ji] - 1, 2);
}
/* /*
* Convert the 1-based indices to 0-based indices, loosing the sign * Convert the 1-based indices to 0-based indices, loosing the sign
* information. * information.
*/ */
final int[] triadidx = new int[tvec.length]; final int[] triadidx = new int[tvec.length];
for (ti = 0; ti < tvec.length; ti++) for (ti = 0; ti < tvec.length; ti++) {
triadidx[ti] = Math.abs(tvec[ti]) - 1; triadidx[ti] = Math.abs(tvec[ti]) - 1;
}
/* /*
* The M-values are all null (undetermined) at the start. * The M-values are all null (undetermined) at the start.
@ -286,10 +293,12 @@ public class Wigner3j {
*/ */
for (int t = 0; t < triadidx.length; t += 3) { for (int t = 0; t < triadidx.length; t += 3) {
/* Ensure |J[t]-J[t+1]| <= J[t+2] <= J[t]+J[t+1] */ /* Ensure |J[t]-J[t+1]| <= J[t+2] <= J[t]+J[t+1] */
if (J[triadidx[t]].subtract(J[triadidx[t + 1]]).abs().compareTo(J[triadidx[t + 2]]) > 0) if (J[triadidx[t]].subtract(J[triadidx[t + 1]]).abs().compareTo(J[triadidx[t + 2]]) > 0) {
return res; return res;
if (J[triadidx[t]].add(J[triadidx[t + 1]]).compareTo(J[triadidx[t + 2]]) < 0) }
if (J[triadidx[t]].add(J[triadidx[t + 1]]).compareTo(J[triadidx[t + 2]]) < 0) {
return res; return res;
}
} }
/* /*
@ -300,7 +309,7 @@ public class Wigner3j {
*/ */
int freeM = -1; int freeM = -1;
int freeMrank = -1; int freeMrank = -1;
for (int i = 0; i < triadidx.length; i++) for (int i = 0; i < triadidx.length; i++) {
/* /*
* found an m-value which has not yet been summed over. * found an m-value which has not yet been summed over.
*/ */
@ -331,10 +340,12 @@ public class Wigner3j {
* rough work load estimator: basically (2J1+1)*(2J2+1) * rough work load estimator: basically (2J1+1)*(2J2+1)
*/ */
Rational wt = J[triadidx[i]].multiply(2).add(1); Rational wt = J[triadidx[i]].multiply(2).add(1);
if (M[triadidx[nei1]] == null) if (M[triadidx[nei1]] == null) {
wt = wt.multiply(J[triadidx[nei1]].multiply(2).add(1)); wt = wt.multiply(J[triadidx[nei1]].multiply(2).add(1));
if (M[triadidx[nei2]] == null) }
if (M[triadidx[nei2]] == null) {
wt = wt.multiply(J[triadidx[nei2]].multiply(2).add(1)); wt = wt.multiply(J[triadidx[nei2]].multiply(2).add(1));
}
final int thiswt = wt.intValue(); final int thiswt = wt.intValue();
if (freeM < 0 || thiswt < freeMrank) { if (freeM < 0 || thiswt < freeMrank) {
freeM = i; freeM = i;
@ -342,16 +353,19 @@ public class Wigner3j {
} }
} }
} }
}
if (freeM >= 0) if (freeM >= 0) {
/* /*
* found an m-value which has not yet been summed over. * found an m-value which has not yet been summed over.
*/ */
if (M[triadidx[freeM]] == null) { if (M[triadidx[freeM]] == null) {
final Rational[] childM = new Rational[M.length]; final Rational[] childM = new Rational[M.length];
for (int ji = 0; ji < M.length; ji++) for (int ji = 0; ji < M.length; ji++) {
if (M[ji] != null) if (M[ji] != null) {
childM[ji] = M[ji]; childM[ji] = M[ji];
}
}
/* /*
* two cases: value is fixed implicitly because already two * two cases: value is fixed implicitly because already two
@ -389,10 +403,12 @@ public class Wigner3j {
* negate if these are the second occurrences of the J in * negate if these are the second occurrences of the J in
* the triads * the triads
*/ */
if (tvec[nei1] < 0) if (tvec[nei1] < 0) {
m1 = m1.negate(); m1 = m1.negate();
if (tvec[nei2] < 0) }
if (tvec[nei2] < 0) {
m2 = m2.negate(); m2 = m2.negate();
}
/* m3 = -(m1+m2) */ /* m3 = -(m1+m2) */
final Rational newm = tvec[freeM] > 0 ? m1.add(m2).negate() : m1.add(m2); final Rational newm = tvec[freeM] > 0 ? m1.add(m2).negate() : m1.add(m2);
/* /*
@ -413,6 +429,7 @@ public class Wigner3j {
} }
return res; return res;
} }
}
/* /*
* reached the bottom of the loop where all M-values are assigned. Build * reached the bottom of the loop where all M-values are assigned. Build
@ -427,34 +444,40 @@ public class Wigner3j {
* negate if these are associated with in-flowing vectors in the * negate if these are associated with in-flowing vectors in the
* triads * triads
*/ */
if (tvec[ji] < 0) if (tvec[ji] < 0) {
m1 = m1.negate(); m1 = m1.negate();
if (tvec[ji + 1] < 0) }
if (tvec[ji + 1] < 0) {
m2 = m2.negate(); m2 = m2.negate();
if (tvec[ji + 2] < 0) }
if (tvec[ji + 2] < 0) {
m3 = m3.negate(); m3 = m3.negate();
}
res = res.multiply(Wigner3j.wigner3jm(J[triadidx[ji]], J[triadidx[ji + 1]], J[triadidx[ji + 2]], m1, m2, m3)); res = res.multiply(Wigner3j.wigner3jm(J[triadidx[ji]], J[triadidx[ji + 1]], J[triadidx[ji + 2]], m1, m2, m3));
/* /*
* if a partial product yields zero, the total product is zero, too, * if a partial product yields zero, the total product is zero, too,
* and offers an early exit. * and offers an early exit.
*/ */
if (res.signum() == 0) if (res.signum() == 0) {
return BigSurdVec.ZERO; return BigSurdVec.ZERO;
}
} }
/* /*
* The overal sign is product_{J-Mpairs} (-1)^(J-M). This is an integer * The overal sign is product_{J-Mpairs} (-1)^(J-M). This is an integer
* because all the J-M are integer. * because all the J-M are integer.
*/ */
Rational sig = new Rational(); Rational sig = new Rational();
for (int ji = 0; ji < J.length; ji++) for (int ji = 0; ji < J.length; ji++) {
sig = sig.add(J[ji]).subtract(M[ji]); sig = sig.add(J[ji]).subtract(M[ji]);
}
/* /*
* sign depends on the sum being even or odd. We assume that "sig" is * sign depends on the sum being even or odd. We assume that "sig" is
* integer and look only at the numerator * integer and look only at the numerator
*/ */
if (sig.a.abs().testBit(0)) if (sig.a.abs().testBit(0)) {
res = res.negate(); res = res.negate();
}
return res; return res;
} /* wigner3j */ } /* wigner3j */
@ -485,36 +508,42 @@ public class Wigner3j {
/* /*
* Check that m1+m2+m3 = 0 * Check that m1+m2+m3 = 0
*/ */
if (m1.add(m2).add(m3).signum() != 0) if (m1.add(m2).add(m3).signum() != 0) {
return BigSurd.ZERO; return BigSurd.ZERO;
}
/* /*
* Check that j1+j2+j3 is integer * Check that j1+j2+j3 is integer
*/ */
if (j1.add(j2).add(j3).isBigInteger() == false) if (j1.add(j2).add(j3).isBigInteger() == false) {
return BigSurd.ZERO; return BigSurd.ZERO;
}
/* /*
* Check that |j1-j2|<=j3 <= |j1+j2| * Check that |j1-j2|<=j3 <= |j1+j2|
*/ */
final Rational j1m2 = j1.subtract(j2); final Rational j1m2 = j1.subtract(j2);
if (j1m2.abs().compareTo(j3) > 0) if (j1m2.abs().compareTo(j3) > 0) {
return BigSurd.ZERO; return BigSurd.ZERO;
}
final Rational j1p2 = j1.add(j2); final Rational j1p2 = j1.add(j2);
if (j1p2.abs().compareTo(j3) < 0) if (j1p2.abs().compareTo(j3) < 0) {
return BigSurd.ZERO; return BigSurd.ZERO;
}
/* /*
* Check that |m_i| <= j_i * Check that |m_i| <= j_i
*/ */
if (m1.abs().compareTo(j1) > 0 || m2.abs().compareTo(j2) > 0 || m3.abs().compareTo(j3) > 0) if (m1.abs().compareTo(j1) > 0 || m2.abs().compareTo(j2) > 0 || m3.abs().compareTo(j3) > 0) {
return BigSurd.ZERO; return BigSurd.ZERO;
}
/* /*
* Check that m_i-j_i are integer. * Check that m_i-j_i are integer.
*/ */
if (!m1.subtract(j1).isBigInteger() || !m2.subtract(j2).isBigInteger() || !m3.subtract(j3).isBigInteger()) if (!m1.subtract(j1).isBigInteger() || !m2.subtract(j2).isBigInteger() || !m3.subtract(j3).isBigInteger()) {
return BigSurd.ZERO; return BigSurd.ZERO;
}
/* /*
* (-)^(j1-j2-m3)*delta(-m3,m1+m2)*sqrt[ (j3+j1-j2)! (j3-j1+j2)! * (-)^(j1-j2-m3)*delta(-m3,m1+m2)*sqrt[ (j3+j1-j2)! (j3-j1+j2)!
@ -550,24 +579,27 @@ public class Wigner3j {
Rational sumk = new Rational(); Rational sumk = new Rational();
while (true) { while (true) {
final BigInteger d = f.at(k).multiply(f.at(j1j2jk)).multiply(f.at(j1m1k)).multiply(f.at(j2m2k)).multiply(f.at(jj2m1k)).multiply(f.at(jj1m2k)); final BigInteger d = f.at(k).multiply(f.at(j1j2jk)).multiply(f.at(j1m1k)).multiply(f.at(j2m2k)).multiply(f.at(jj2m1k)).multiply(f.at(jj1m2k));
if (k % 2 == 0) if (k % 2 == 0) {
sumk = sumk.add(new Rational(BigInteger.ONE, d)); sumk = sumk.add(new Rational(BigInteger.ONE, d));
else } else {
sumk = sumk.subtract(new Rational(BigInteger.ONE, d)); sumk = sumk.subtract(new Rational(BigInteger.ONE, d));
}
j1j2jk--; j1j2jk--;
j1m1k--; j1m1k--;
j2m2k--; j2m2k--;
jj2m1k++; jj2m1k++;
jj1m2k++; jj1m2k++;
if (j1j2jk < 0 || j1m1k < 0 || j2m2k < 0) if (j1j2jk < 0 || j1m1k < 0 || j2m2k < 0) {
break; break;
}
k++; k++;
} }
/* /*
* sign factor (-1)^(j1-j2-m3) * sign factor (-1)^(j1-j2-m3)
*/ */
if (j1m2.subtract(m3).intValue() % 2 != 0) if (j1m2.subtract(m3).intValue() % 2 != 0) {
sumk = sumk.negate(); sumk = sumk.negate();
}
k = j1m2.add(j3).intValue(); k = j1m2.add(j3).intValue();
BigInteger s = f.at(k); BigInteger s = f.at(k);

View File

@ -146,16 +146,18 @@ public class Wigner3jGUI implements ActionListener, ListSelectionListener {
* lines that start with a hash mark. * lines that start with a hash mark.
*/ */
Scanner s = new Scanner(tr); Scanner s = new Scanner(tr);
for (int l = 0; l < 3;) for (int l = 0; l < 3;) {
try { try {
trias[l] = s.nextLine().trim(); trias[l] = s.nextLine().trim();
if (!trias[l].startsWith("#")) if (!trias[l].startsWith("#")) {
l++; l++;
}
} catch (final Exception e) { } catch (final Exception e) {
s.close(); s.close();
outG.setText("ERROR: less than 3 lines in the triad definition"); outG.setText("ERROR: less than 3 lines in the triad definition");
return; return;
} }
}
s.close(); s.close();