Merge branch 'master' into rules-dsl
This commit is contained in:
commit
2ceca91acf
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -1,3 +1,6 @@
|
||||
[submodule "Flow"]
|
||||
path = Flow
|
||||
url = https://github.com/Cavallium/Flow
|
||||
[submodule "bigdecimal-math"]
|
||||
path = bigdecimal-math
|
||||
url = https://github.com/Cavallium/bigdecimal-math
|
||||
|
2
Flow
2
Flow
@ -1 +1 @@
|
||||
Subproject commit 4ec16b0e2d49da9771503e713604f5641ef6c414
|
||||
Subproject commit 59b89e9d165c3fc615ca44aa742b531caf13fcb6
|
2
LICENSE
2
LICENSE
@ -186,7 +186,7 @@
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
Copyright 2018 Andrea Cavalli
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,33 +0,0 @@
|
||||
package it.cavallium.warppi;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class MmapByteBuffer {
|
||||
private int fd;
|
||||
private int address;
|
||||
private int length;
|
||||
private ByteBuffer buffer;
|
||||
|
||||
public MmapByteBuffer(int fd, int address, int length, ByteBuffer buffer) {
|
||||
this.fd = fd;
|
||||
this.address = address;
|
||||
this.length = length;
|
||||
this.buffer = buffer;
|
||||
}
|
||||
|
||||
public int getFd() {
|
||||
return fd;
|
||||
}
|
||||
|
||||
public int getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public ByteBuffer getBuffer() {
|
||||
return buffer;
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
# WarpPI Calculator
|
||||
Step-by-step algebra calculator for Raspberry PI.
|
||||
|
||||
**This project is experimental and strictly related to my calculator, designed to run on an embedded hardware.
|
||||
It works but many fundamental features aren't complete.**<br>
|
||||
**This project is experimental and strictly related to my calculator, designed to run on a raspberry PI Zero.**<br>
|
||||
**Many fundamental features are missing, this project is still in its infancy.**<br>
|
||||
|
||||
**If you really want to build and test it on your computer take account of that.**
|
||||
|
||||
|
1
bigdecimal-math
Submodule
1
bigdecimal-math
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit b08a4a6aca41fbc6bf0c4bd252f716d518d368a5
|
27
core/pom.xml
27
core/pom.xml
@ -6,10 +6,9 @@
|
||||
<parent>
|
||||
<groupId>it.cavallium</groupId>
|
||||
<artifactId>warppi</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<version>0.9.0a3</version>
|
||||
</parent>
|
||||
<artifactId>warppi-core</artifactId>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<name>WarpPI Calculator Core</name>
|
||||
<description>WarpPI Calculator core project</description>
|
||||
@ -18,7 +17,17 @@
|
||||
<dependency>
|
||||
<groupId>it.cavallium</groupId>
|
||||
<artifactId>warppi-flow</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<version>0.9.0a3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>it.cavallium</groupId>
|
||||
<artifactId>warppi-util</artifactId>
|
||||
<version>0.9.0a3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>it.cavallium</groupId>
|
||||
<artifactId>bigdecimal-math</artifactId>
|
||||
<version>0.9.0a3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>it.unimi.dsi</groupId>
|
||||
@ -46,16 +55,8 @@
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Import-Package>*</Import-Package>
|
||||
<Export-Package>it.cavallium.warppi.*</Export-Package>
|
||||
<Bundle-SymbolicName>warppi-core</Bundle-SymbolicName>
|
||||
</instructions>
|
||||
</configuration>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
|
@ -89,14 +89,19 @@ public class Engine {
|
||||
}
|
||||
Engine.platform.getConsoleUtils().out().println(ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN, args);
|
||||
checkDeviceType();
|
||||
if (Engine.getPlatform().isRunningOnRaspberry() && args.isRaspberryModeAllowed()) {
|
||||
if (args.isRaspberryModeAllowed() == false) {
|
||||
Engine.getPlatform().setRunningOnRaspberry(false);
|
||||
}
|
||||
if (Engine.getPlatform().isRunningOnRaspberry()) {
|
||||
Engine.getPlatform().getGpio().wiringPiSetupPhys();
|
||||
Engine.getPlatform().getGpio().pinMode(12, Engine.getPlatform().getGpio().valuePwmOutput());
|
||||
} else {
|
||||
StaticVars.screenPos = new int[] { 0, 0 };
|
||||
if (Engine.getPlatform().isJavascript() == false) {
|
||||
Engine.getPlatform().getSettings().setDebugEnabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkDeviceType() {
|
||||
// TODO Auto-generated method stub
|
||||
|
@ -20,7 +20,7 @@ public interface Platform {
|
||||
|
||||
StorageUtils getStorageUtils();
|
||||
|
||||
PngUtils getPngUtils();
|
||||
ImageUtils getImageUtils();
|
||||
|
||||
Settings getSettings();
|
||||
|
||||
@ -36,6 +36,8 @@ public interface Platform {
|
||||
|
||||
boolean isJavascript();
|
||||
|
||||
void setRunningOnRaspberry(boolean b);
|
||||
|
||||
boolean isRunningOnRaspberry();
|
||||
|
||||
String getOsName();
|
||||
@ -170,18 +172,16 @@ public interface Platform {
|
||||
void close() throws IOException;
|
||||
}
|
||||
|
||||
public interface PngUtils {
|
||||
public interface ImageUtils {
|
||||
|
||||
PngReader load(InputStream resourceStream);
|
||||
ImageReader load(InputStream resourceStream) throws IOException;
|
||||
|
||||
public interface PngReader {
|
||||
public interface ImageReader {
|
||||
|
||||
int[] getImageMatrix();
|
||||
|
||||
int[] getSize();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public interface Settings {
|
||||
|
@ -1,7 +1,5 @@
|
||||
package it.cavallium.warppi.device;
|
||||
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
import it.cavallium.warppi.Engine;
|
||||
import it.cavallium.warppi.Platform.ConsoleUtils;
|
||||
import it.cavallium.warppi.StaticVars;
|
||||
@ -12,6 +10,7 @@ import it.cavallium.warppi.event.KeyPressedEvent;
|
||||
import it.cavallium.warppi.event.KeyReleasedEvent;
|
||||
import it.cavallium.warppi.event.KeyboardEventListener;
|
||||
import it.cavallium.warppi.extra.mario.MarioScreen;
|
||||
import it.cavallium.warppi.extra.tetris.TetrisScreen;
|
||||
import it.cavallium.warppi.gui.GUIErrorMessage;
|
||||
import it.cavallium.warppi.gui.screens.KeyboardDebugScreen;
|
||||
import it.cavallium.warppi.gui.screens.Screen;
|
||||
@ -41,15 +40,15 @@ public class Keyboard {
|
||||
|
||||
public synchronized void startKeyboard() {
|
||||
final Thread kt = new Thread(() -> {
|
||||
if (Engine.getPlatform().getSettings().isDebugEnabled()) {
|
||||
if (Engine.getPlatform().isRunningOnRaspberry() == false) {
|
||||
try {
|
||||
while (true) {
|
||||
if (Keyboard.debugKeyCode != -1) {
|
||||
Keyboard.debugKeyPressed(Keyboard.debugKeyCode);
|
||||
Keyboard.debugKey(Keyboard.debugKeyCode, false);
|
||||
Keyboard.debugKeyCode = -1;
|
||||
}
|
||||
if (Keyboard.debugKeyCodeRelease != -1) {
|
||||
Keyboard.debugKeyReleased(Keyboard.debugKeyCodeRelease);
|
||||
Keyboard.debugKey(Keyboard.debugKeyCodeRelease, true);
|
||||
Keyboard.debugKeyCodeRelease = -1;
|
||||
}
|
||||
Thread.sleep(50);
|
||||
@ -88,9 +87,9 @@ public class Keyboard {
|
||||
if (data[row] == true && Keyboard.precedentStates[row][col] == false) {
|
||||
// System.out.println("Pressed button at " + (row + 1) + ", " + (col + 1));
|
||||
// KeyboardDebugScreen.log("Pressed button at " + (row + 1) + ", " + (col + 1));
|
||||
Keyboard.keyPressedRaw(row, col);
|
||||
Keyboard.keyRaw(row, col, false);
|
||||
} else if (data[row] == false && Keyboard.precedentStates[row][col] == true) {
|
||||
Keyboard.keyReleasedRaw(row, col);
|
||||
Keyboard.keyRaw(row, col, true);
|
||||
}
|
||||
// KeyboardDebugScreen.log("Released button at " + (row + 1) + ", " + (col + 1));
|
||||
Keyboard.precedentStates[row][col] = data[row];
|
||||
@ -105,306 +104,324 @@ public class Keyboard {
|
||||
kt.start();
|
||||
}
|
||||
|
||||
public static void debugKeyPressed(final int keyCode) {
|
||||
/**
|
||||
*
|
||||
* @param k
|
||||
* @param released true: released, false: pressed
|
||||
*/
|
||||
private static void debugKey(Key k, boolean released) {
|
||||
if (released) {
|
||||
Keyboard.keyReleased(k);
|
||||
} else {
|
||||
Keyboard.keyPressed(k);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param keyCode
|
||||
* @param released true: released, false: pressed
|
||||
*/
|
||||
public static void debugKey(final int keyCode, boolean released) {
|
||||
switch (keyCode) {
|
||||
case KeyEvent.VK_ESCAPE:
|
||||
Keyboard.keyPressed(Key.BACK);
|
||||
case KeyboardAWTValues.VK_ESCAPE:
|
||||
debugKey(Key.BACK, released);
|
||||
break;
|
||||
case KeyEvent.VK_S:
|
||||
case KeyboardAWTValues.VK_S:
|
||||
if (Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.ARCSINE);
|
||||
debugKey(Key.ARCSINE, released);
|
||||
} else if (Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.LETTER_S);
|
||||
debugKey(Key.LETTER_S, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.SINE);
|
||||
debugKey(Key.SINE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_C:
|
||||
case KeyboardAWTValues.VK_C:
|
||||
if (Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.ARCCOSINE);
|
||||
debugKey(Key.ARCCOSINE, released);
|
||||
} else if (Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.LETTER_C);
|
||||
debugKey(Key.LETTER_C, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.COSINE);
|
||||
debugKey(Key.COSINE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_T:
|
||||
case KeyboardAWTValues.VK_T:
|
||||
if (Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.ARCTANGENT);
|
||||
debugKey(Key.ARCTANGENT, released);
|
||||
} else if (Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.LETTER_T);
|
||||
debugKey(Key.LETTER_T, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.TANGENT);
|
||||
debugKey(Key.TANGENT, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_D:
|
||||
case KeyboardAWTValues.VK_D:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.debug_DEG);
|
||||
debugKey(Key.debug_DEG, released);
|
||||
} else if (Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.LETTER_D);
|
||||
debugKey(Key.LETTER_D, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_R:
|
||||
case KeyboardAWTValues.VK_R:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.debug_RAD);
|
||||
debugKey(Key.debug_RAD, released);
|
||||
} else if (Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.LETTER_R);
|
||||
debugKey(Key.LETTER_R, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_G:
|
||||
case KeyboardAWTValues.VK_G:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.debug_GRA);
|
||||
debugKey(Key.debug_GRA, released);
|
||||
} else if (Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.LETTER_G);
|
||||
debugKey(Key.LETTER_G, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_X:
|
||||
case KeyboardAWTValues.VK_X:
|
||||
if (Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.LETTER_X);
|
||||
debugKey(Key.LETTER_X, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_P:
|
||||
case KeyboardAWTValues.VK_P:
|
||||
if (Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else if (Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.LETTER_P);
|
||||
debugKey(Key.LETTER_P, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.PI);
|
||||
debugKey(Key.PI, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_E:
|
||||
case KeyboardAWTValues.VK_E:
|
||||
if (Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else if (Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.LETTER_E);
|
||||
debugKey(Key.LETTER_E, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.EULER_NUMBER);
|
||||
debugKey(Key.EULER_NUMBER, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_Y:
|
||||
case KeyboardAWTValues.VK_Y:
|
||||
if (Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.LETTER_Y);
|
||||
debugKey(Key.LETTER_Y, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_B:
|
||||
case KeyboardAWTValues.VK_B:
|
||||
if (Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.BRIGHTNESS_CYCLE_REVERSE);
|
||||
debugKey(Key.BRIGHTNESS_CYCLE_REVERSE, released);
|
||||
} else if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.BRIGHTNESS_CYCLE);
|
||||
debugKey(Key.BRIGHTNESS_CYCLE, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.LETTER_B);
|
||||
debugKey(Key.LETTER_B, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_L:
|
||||
case KeyboardAWTValues.VK_L:
|
||||
if (Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.LOGARITHM);
|
||||
debugKey(Key.LOGARITHM, released);
|
||||
} else if (Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.LETTER_L);
|
||||
debugKey(Key.LETTER_L, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.LOGARITHM);
|
||||
debugKey(Key.LOGARITHM, released);
|
||||
}
|
||||
break;
|
||||
case KeyboardJogampValues.VK_ENTER:
|
||||
case KeyEvent.VK_ENTER:
|
||||
case KeyboardAWTValues.VK_ENTER:
|
||||
if (Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.STEP);
|
||||
debugKey(Key.STEP, released);
|
||||
} else if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.SIMPLIFY);
|
||||
debugKey(Key.SIMPLIFY, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
int row = 2;
|
||||
int col = 1;
|
||||
Keyboard.debugKeysDown[row - 1][col - 1] = true;
|
||||
break;
|
||||
case KeyEvent.VK_1:
|
||||
case KeyboardAWTValues.VK_1:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NUM1);
|
||||
debugKey(Key.NUM1, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_2:
|
||||
case KeyboardAWTValues.VK_2:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NUM2);
|
||||
debugKey(Key.NUM2, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_3:
|
||||
case KeyboardAWTValues.VK_3:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NUM3);
|
||||
debugKey(Key.NUM3, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_4:
|
||||
case KeyboardAWTValues.VK_4:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NUM4);
|
||||
debugKey(Key.NUM4, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_5:
|
||||
case KeyboardAWTValues.VK_5:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NUM5);
|
||||
debugKey(Key.NUM5, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_6:
|
||||
case KeyboardAWTValues.VK_6:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NUM6);
|
||||
debugKey(Key.NUM6, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_7:
|
||||
case KeyboardAWTValues.VK_7:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NUM7);
|
||||
debugKey(Key.NUM7, released);
|
||||
} else if (Keyboard.shift) {
|
||||
if (Engine.getPlatform().getSettings().isDebugEnabled()) {
|
||||
Keyboard.keyPressed(Key.DIVIDE);
|
||||
if (Engine.getPlatform().isRunningOnRaspberry() == false) {
|
||||
debugKey(Key.DIVIDE, released);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_8:
|
||||
case KeyboardAWTValues.VK_8:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NUM8);
|
||||
debugKey(Key.NUM8, released);
|
||||
} else if (Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.PARENTHESIS_OPEN);
|
||||
debugKey(Key.PARENTHESIS_OPEN, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_9:
|
||||
case KeyboardAWTValues.VK_9:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NUM9);
|
||||
debugKey(Key.NUM9, released);
|
||||
} else if (Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.PARENTHESIS_CLOSE);
|
||||
debugKey(Key.PARENTHESIS_CLOSE, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_0:
|
||||
case KeyboardAWTValues.VK_0:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NUM0);
|
||||
debugKey(Key.NUM0, released);
|
||||
} else if (Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.EQUAL);
|
||||
debugKey(Key.EQUAL, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_M:
|
||||
case KeyboardAWTValues.VK_M:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.SURD_MODE);
|
||||
debugKey(Key.SURD_MODE, released);
|
||||
} else if (Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.LETTER_M);
|
||||
debugKey(Key.LETTER_M, released);
|
||||
}
|
||||
break;
|
||||
case KeyboardJogampValues.VK_ADD:
|
||||
case KeyEvent.VK_ADD:
|
||||
case KeyboardAWTValues.VK_ADD:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.PLUS);
|
||||
debugKey(Key.PLUS, released);
|
||||
} else if (Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.PLUS_MINUS);
|
||||
debugKey(Key.PLUS_MINUS, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyboardJogampValues.VK_SUBTRACT:
|
||||
case KeyEvent.VK_SUBTRACT:
|
||||
case KeyboardAWTValues.VK_SUBTRACT:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.MINUS);
|
||||
debugKey(Key.MINUS, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyboardJogampValues.VK_MULTIPLY:
|
||||
case KeyEvent.VK_MULTIPLY:
|
||||
case KeyboardAWTValues.VK_MULTIPLY:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.MULTIPLY);
|
||||
debugKey(Key.MULTIPLY, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyboardJogampValues.VK_DIVIDE:
|
||||
case KeyEvent.VK_DIVIDE:
|
||||
case KeyboardAWTValues.VK_DIVIDE:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.DIVIDE);
|
||||
debugKey(Key.DIVIDE, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_BACK_SPACE:
|
||||
Keyboard.keyPressed(Key.DELETE);
|
||||
case KeyboardAWTValues.VK_BACK_SPACE:
|
||||
debugKey(Key.DELETE, released);
|
||||
break;
|
||||
case KeyboardJogampValues.VK_DELETE:
|
||||
case KeyEvent.VK_DELETE:
|
||||
case KeyboardAWTValues.VK_DELETE:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.RESET);
|
||||
debugKey(Key.RESET, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyboardJogampValues.VK_LEFT:
|
||||
case KeyEvent.VK_LEFT:
|
||||
case KeyboardAWTValues.VK_LEFT:
|
||||
//LEFT
|
||||
row = 2;
|
||||
col = 3;
|
||||
Keyboard.debugKeysDown[row - 1][col - 1] = true;
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.LEFT);
|
||||
debugKey(Key.LEFT, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyboardJogampValues.VK_RIGHT:
|
||||
case KeyEvent.VK_RIGHT:
|
||||
case KeyboardAWTValues.VK_RIGHT:
|
||||
//RIGHT
|
||||
row = 2;
|
||||
col = 5;
|
||||
Keyboard.debugKeysDown[row - 1][col - 1] = true;
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.RIGHT);
|
||||
debugKey(Key.RIGHT, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyboardJogampValues.VK_UP:
|
||||
case KeyEvent.VK_UP:
|
||||
case KeyboardAWTValues.VK_UP:
|
||||
//UP
|
||||
row = 1;
|
||||
col = 4;
|
||||
Keyboard.debugKeysDown[row - 1][col - 1] = true;
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.UP);
|
||||
debugKey(Key.UP, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyboardJogampValues.VK_DOWN:
|
||||
case KeyEvent.VK_DOWN:
|
||||
case KeyboardAWTValues.VK_DOWN:
|
||||
//DOWN
|
||||
row = 3;
|
||||
col = 4;
|
||||
Keyboard.debugKeysDown[row - 1][col - 1] = true;
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.DOWN);
|
||||
debugKey(Key.DOWN, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case (short) 12:
|
||||
@ -413,219 +430,219 @@ public class Keyboard {
|
||||
col = 4;
|
||||
Keyboard.debugKeysDown[row - 1][col - 1] = true;
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.OK);
|
||||
debugKey(Key.OK, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyboardJogampValues.VK_NUMPAD4:
|
||||
case KeyEvent.VK_NUMPAD4:
|
||||
case KeyboardAWTValues.VK_NUMPAD4:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.HISTORY_BACK);
|
||||
debugKey(Key.HISTORY_BACK, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyboardJogampValues.VK_NUMPAD6:
|
||||
case KeyEvent.VK_NUMPAD6:
|
||||
case KeyboardAWTValues.VK_NUMPAD6:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.HISTORY_FORWARD);
|
||||
debugKey(Key.HISTORY_FORWARD, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_PERIOD:
|
||||
case KeyboardAWTValues.VK_PERIOD:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.DOT);
|
||||
debugKey(Key.DOT, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_A:
|
||||
case KeyboardAWTValues.VK_A:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else if (Keyboard.alpha && !Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.LETTER_A);
|
||||
debugKey(Key.LETTER_A, released);
|
||||
} else if (Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_F:
|
||||
case KeyboardAWTValues.VK_F:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else if (Keyboard.alpha && !Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.LETTER_F);
|
||||
debugKey(Key.LETTER_F, released);
|
||||
} else if (Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_H:
|
||||
case KeyboardAWTValues.VK_H:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else if (Keyboard.alpha && !Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.LETTER_H);
|
||||
debugKey(Key.LETTER_H, released);
|
||||
} else if (Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_I:
|
||||
case KeyboardAWTValues.VK_I:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else if (Keyboard.alpha && !Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.LETTER_I);
|
||||
debugKey(Key.LETTER_I, released);
|
||||
} else if (Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_J:
|
||||
case KeyboardAWTValues.VK_J:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else if (Keyboard.alpha && !Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.LETTER_J);
|
||||
debugKey(Key.LETTER_J, released);
|
||||
} else if (Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_K:
|
||||
case KeyboardAWTValues.VK_K:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else if (Keyboard.alpha && !Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.LETTER_K);
|
||||
debugKey(Key.LETTER_K, released);
|
||||
} else if (Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_N:
|
||||
case KeyboardAWTValues.VK_N:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else if (Keyboard.alpha && !Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.LETTER_N);
|
||||
debugKey(Key.LETTER_N, released);
|
||||
} else if (Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_O:
|
||||
case KeyboardAWTValues.VK_O:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else if (Keyboard.alpha && !Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.LETTER_O);
|
||||
debugKey(Key.LETTER_O, released);
|
||||
} else if (Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_Q:
|
||||
case KeyboardAWTValues.VK_Q:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else if (Keyboard.alpha && !Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.LETTER_Q);
|
||||
debugKey(Key.LETTER_Q, released);
|
||||
} else if (Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_U:
|
||||
case KeyboardAWTValues.VK_U:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else if (Keyboard.alpha && !Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.LETTER_U);
|
||||
debugKey(Key.LETTER_U, released);
|
||||
} else if (Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_V:
|
||||
case KeyboardAWTValues.VK_V:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else if (Keyboard.alpha && !Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.LETTER_V);
|
||||
debugKey(Key.LETTER_V, released);
|
||||
} else if (Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_W:
|
||||
case KeyboardAWTValues.VK_W:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else if (Keyboard.alpha && !Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.LETTER_W);
|
||||
debugKey(Key.LETTER_W, released);
|
||||
} else if (Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_Z:
|
||||
case KeyboardAWTValues.VK_Z:
|
||||
if (!Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
} else if (Keyboard.alpha && !Keyboard.shift) {
|
||||
Keyboard.keyPressed(Key.LETTER_Z);
|
||||
debugKey(Key.LETTER_Z, released);
|
||||
} else if (Keyboard.shift && !Keyboard.alpha) {
|
||||
Keyboard.keyPressed(Key.ZOOM_MODE);
|
||||
debugKey(Key.ZOOM_MODE, released);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
debugKey(Key.NONE, released);
|
||||
}
|
||||
break;
|
||||
case KeyboardJogampValues.VK_SHIFT:
|
||||
case KeyEvent.VK_SHIFT:
|
||||
Keyboard.keyPressed(Key.SHIFT);
|
||||
case KeyboardAWTValues.VK_SHIFT:
|
||||
debugKey(Key.SHIFT, released);
|
||||
break;
|
||||
case KeyEvent.VK_CONTROL:
|
||||
Keyboard.keyPressed(Key.ALPHA);
|
||||
case KeyboardAWTValues.VK_CONTROL:
|
||||
debugKey(Key.ALPHA, released);
|
||||
break;
|
||||
case KeyboardJogampValues.VK_NUMPAD1:
|
||||
case KeyEvent.VK_NUMPAD1:
|
||||
Keyboard.keyPressed(Key.SQRT);
|
||||
case KeyboardAWTValues.VK_NUMPAD1:
|
||||
debugKey(Key.SQRT, released);
|
||||
break;
|
||||
case KeyboardJogampValues.VK_NUMPAD2:
|
||||
case KeyEvent.VK_NUMPAD2:
|
||||
Keyboard.keyPressed(Key.ROOT);
|
||||
case KeyboardAWTValues.VK_NUMPAD2:
|
||||
debugKey(Key.ROOT, released);
|
||||
break;
|
||||
case KeyboardJogampValues.VK_NUMPAD3:
|
||||
case KeyEvent.VK_NUMPAD3:
|
||||
Keyboard.keyPressed(Key.POWER_OF_2);
|
||||
case KeyboardAWTValues.VK_NUMPAD3:
|
||||
debugKey(Key.POWER_OF_2, released);
|
||||
break;
|
||||
case KeyboardJogampValues.VK_NUMPAD5:
|
||||
case KeyEvent.VK_NUMPAD5:
|
||||
Keyboard.keyPressed(Key.POWER_OF_x);
|
||||
case KeyboardAWTValues.VK_NUMPAD5:
|
||||
debugKey(Key.POWER_OF_x, released);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized static void debugKeyReleased(final int keyCode) {
|
||||
switch (keyCode) {
|
||||
case KeyEvent.VK_ENTER:
|
||||
case KeyboardAWTValues.VK_ENTER:
|
||||
int row = 2;
|
||||
int col = 1;
|
||||
Keyboard.debugKeysDown[row - 1][col - 1] = false;
|
||||
break;
|
||||
case KeyboardJogampValues.VK_LEFT:
|
||||
case KeyEvent.VK_LEFT:
|
||||
case KeyboardAWTValues.VK_LEFT:
|
||||
//LEFT
|
||||
row = 2;
|
||||
col = 3;
|
||||
Keyboard.debugKeysDown[row - 1][col - 1] = false;
|
||||
break;
|
||||
case KeyboardJogampValues.VK_RIGHT:
|
||||
case KeyEvent.VK_RIGHT:
|
||||
case KeyboardAWTValues.VK_RIGHT:
|
||||
//RIGHT
|
||||
row = 2;
|
||||
col = 5;
|
||||
@ -633,14 +650,14 @@ public class Keyboard {
|
||||
System.out.println("RELEASE");
|
||||
break;
|
||||
case KeyboardJogampValues.VK_UP:
|
||||
case KeyEvent.VK_UP:
|
||||
case KeyboardAWTValues.VK_UP:
|
||||
//UP
|
||||
row = 1;
|
||||
col = 4;
|
||||
Keyboard.debugKeysDown[row - 1][col - 1] = false;
|
||||
break;
|
||||
case KeyboardJogampValues.VK_DOWN:
|
||||
case KeyEvent.VK_DOWN:
|
||||
case KeyboardAWTValues.VK_DOWN:
|
||||
//DOWN
|
||||
row = 3;
|
||||
col = 4;
|
||||
@ -655,22 +672,21 @@ public class Keyboard {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param row
|
||||
* @param col
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean isKeyDown(final int row, final int col) {
|
||||
if (Engine.getPlatform().getSettings().isDebugEnabled() == false) {
|
||||
if (Engine.getPlatform().isRunningOnRaspberry()) {
|
||||
return Keyboard.precedentStates[row - 1][col - 1];
|
||||
} else {
|
||||
return Keyboard.debugKeysDown[row - 1][col - 1];
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized static void keyReleasedRaw(final int row, final int col) {
|
||||
// KeyboardDebugScreen.keyX = row;
|
||||
// KeyboardDebugScreen.keyY = col;
|
||||
if (row == 1 && col == 1) {
|
||||
//keyReleased(Key.BRIGHTNESS_CYCLE);
|
||||
}
|
||||
}
|
||||
|
||||
static final String[][][] KeyLabelsMap = /* [ROW, COLUMN, (0:normal 1:shift 2:alpha)] */
|
||||
{ { /* ROW 0 */
|
||||
{ "⇪", "⇪", null }, /* 0,0 */
|
||||
@ -687,8 +703,8 @@ public class Keyboard {
|
||||
{ "⇦", null, null }, /* 1,2 */
|
||||
{ "OK", null, null }, /* 1,3 */
|
||||
{ "⇨", null, null }, /* 1,4 */
|
||||
{ "↤", null, null }, /* 1,5 */
|
||||
{ "↦", null, null }, /* 1,6 */
|
||||
{ "≪", null, null }, /* 1,5 */
|
||||
{ "≫", null, null }, /* 1,6 */
|
||||
{ "", null, null } /* 1,7 */
|
||||
}, { /* ROW 2 */
|
||||
{ "", null, null }, /* 2,0 */
|
||||
@ -751,7 +767,7 @@ public class Keyboard {
|
||||
{ Key.SHIFT, Key.SHIFT, Key.SHIFT }, /* 0,0 */
|
||||
{ Key.ALPHA, Key.ALPHA, Key.ALPHA }, /* 0,1 */
|
||||
{ Key.NONE, Key.NONE, Key.NONE }, /* 0,2 */
|
||||
{ Key.NONE, Key.NONE, Key.NONE }, /* 0,3 */
|
||||
{ Key.UP, Key.NONE, Key.NONE }, /* 0,3 */
|
||||
{ Key.NONE, Key.NONE, Key.NONE }, /* 0,4 */
|
||||
{ Key.SETTINGS, Key.NONE, Key.NONE }, /* 0,5 */
|
||||
{ Key.BRIGHTNESS_CYCLE, Key.BRIGHTNESS_CYCLE_REVERSE, Key.ZOOM_MODE }, /* 0,6 */
|
||||
@ -850,19 +866,33 @@ public class Keyboard {
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized void keyPressedRaw(final int row, final int col) {
|
||||
/**
|
||||
*
|
||||
* @param row
|
||||
* @param col
|
||||
* @param released true: released, false: pressed
|
||||
*/
|
||||
public static synchronized void keyRaw(final int row, final int col, final boolean released) {
|
||||
// KeyboardDebugScreen.keyX = row;
|
||||
// KeyboardDebugScreen.keyY = col;
|
||||
final Key k = Keyboard.keyMap[row][col][Keyboard.shift ? 1 : Keyboard.alpha ? 2 : 0];
|
||||
if (k != null) {
|
||||
if (released) {
|
||||
Keyboard.keyReleased(k);
|
||||
} else {
|
||||
Keyboard.keyPressed(k);
|
||||
}
|
||||
} else {
|
||||
if (released) {
|
||||
Keyboard.keyReleased(Key.NONE);
|
||||
} else {
|
||||
Keyboard.keyPressed(Key.NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void stopKeyboard() {
|
||||
if (Engine.getPlatform().getSettings().isDebugEnabled() == false) {
|
||||
if (Engine.getPlatform().isRunningOnRaspberry()) {
|
||||
Engine.getPlatform().getGpio().digitalWrite(33, false);
|
||||
Engine.getPlatform().getGpio().digitalWrite(35, false);
|
||||
Engine.getPlatform().getGpio().digitalWrite(36, false);
|
||||
@ -900,6 +930,7 @@ public class Keyboard {
|
||||
case NONE:
|
||||
break;
|
||||
case BRIGHTNESS_CYCLE:
|
||||
Engine.INSTANCE.getHardwareDevice().getDisplayManager().setScreen(new TetrisScreen()); //TODO: rimuovere: prova
|
||||
Engine.INSTANCE.getHardwareDevice().getDisplayManager().cycleBrightness(false);
|
||||
refresh = true;
|
||||
break;
|
||||
|
@ -0,0 +1,700 @@
|
||||
package it.cavallium.warppi.device;
|
||||
|
||||
public interface KeyboardAWTValues {
|
||||
|
||||
/**
|
||||
* The first number in the range of ids used for key events.
|
||||
*/
|
||||
int KEY_FIRST = 400;
|
||||
|
||||
/**
|
||||
* The last number in the range of ids used for key events.
|
||||
*/
|
||||
int KEY_LAST = 402;
|
||||
|
||||
/**
|
||||
* The "key typed" event. This event is generated when a character is
|
||||
* entered. In the simplest case, it is produced by a single key press.
|
||||
* Often, however, characters are produced by series of key presses, and
|
||||
* the mapping from key pressed events to key typed events may be
|
||||
* many-to-one or many-to-many.
|
||||
*/
|
||||
int KEY_TYPED = KEY_FIRST;
|
||||
|
||||
/**
|
||||
* The "key pressed" event. This event is generated when a key
|
||||
* is pushed down.
|
||||
*/
|
||||
int KEY_PRESSED = 1 + KEY_FIRST; //Event.KEY_PRESS
|
||||
|
||||
/**
|
||||
* The "key released" event. This event is generated when a key
|
||||
* is let up.
|
||||
*/
|
||||
int KEY_RELEASED = 2 + KEY_FIRST; //Event.KEY_RELEASE
|
||||
|
||||
/* Virtual key codes. */
|
||||
|
||||
int VK_ENTER = '\n';
|
||||
int VK_BACK_SPACE = '\b';
|
||||
int VK_TAB = '\t';
|
||||
int VK_CANCEL = 0x03;
|
||||
int VK_CLEAR = 0x0C;
|
||||
int VK_SHIFT = 0x10;
|
||||
int VK_CONTROL = 0x11;
|
||||
int VK_ALT = 0x12;
|
||||
int VK_PAUSE = 0x13;
|
||||
int VK_CAPS_LOCK = 0x14;
|
||||
int VK_ESCAPE = 0x1B;
|
||||
int VK_SPACE = 0x20;
|
||||
int VK_PAGE_UP = 0x21;
|
||||
int VK_PAGE_DOWN = 0x22;
|
||||
int VK_END = 0x23;
|
||||
int VK_HOME = 0x24;
|
||||
|
||||
/**
|
||||
* Constant for the non-numpad <b>left</b> arrow key.
|
||||
* @see #VK_KP_LEFT
|
||||
*/
|
||||
int VK_LEFT = 0x25;
|
||||
|
||||
/**
|
||||
* Constant for the non-numpad <b>up</b> arrow key.
|
||||
* @see #VK_KP_UP
|
||||
*/
|
||||
int VK_UP = 0x26;
|
||||
|
||||
/**
|
||||
* Constant for the non-numpad <b>right</b> arrow key.
|
||||
* @see #VK_KP_RIGHT
|
||||
*/
|
||||
int VK_RIGHT = 0x27;
|
||||
|
||||
/**
|
||||
* Constant for the non-numpad <b>down</b> arrow key.
|
||||
* @see #VK_KP_DOWN
|
||||
*/
|
||||
int VK_DOWN = 0x28;
|
||||
|
||||
/**
|
||||
* Constant for the comma key, ","
|
||||
*/
|
||||
int VK_COMMA = 0x2C;
|
||||
|
||||
/**
|
||||
* Constant for the minus key, "-"
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_MINUS = 0x2D;
|
||||
|
||||
/**
|
||||
* Constant for the period key, "."
|
||||
*/
|
||||
int VK_PERIOD = 0x2E;
|
||||
|
||||
/**
|
||||
* Constant for the forward slash key, "/"
|
||||
*/
|
||||
int VK_SLASH = 0x2F;
|
||||
|
||||
/** VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39) */
|
||||
int VK_0 = 0x30;
|
||||
int VK_1 = 0x31;
|
||||
int VK_2 = 0x32;
|
||||
int VK_3 = 0x33;
|
||||
int VK_4 = 0x34;
|
||||
int VK_5 = 0x35;
|
||||
int VK_6 = 0x36;
|
||||
int VK_7 = 0x37;
|
||||
int VK_8 = 0x38;
|
||||
int VK_9 = 0x39;
|
||||
|
||||
/**
|
||||
* Constant for the semicolon key, ";"
|
||||
*/
|
||||
int VK_SEMICOLON = 0x3B;
|
||||
|
||||
/**
|
||||
* Constant for the equals key, "="
|
||||
*/
|
||||
int VK_EQUALS = 0x3D;
|
||||
|
||||
/** VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A) */
|
||||
int VK_A = 0x41;
|
||||
int VK_B = 0x42;
|
||||
int VK_C = 0x43;
|
||||
int VK_D = 0x44;
|
||||
int VK_E = 0x45;
|
||||
int VK_F = 0x46;
|
||||
int VK_G = 0x47;
|
||||
int VK_H = 0x48;
|
||||
int VK_I = 0x49;
|
||||
int VK_J = 0x4A;
|
||||
int VK_K = 0x4B;
|
||||
int VK_L = 0x4C;
|
||||
int VK_M = 0x4D;
|
||||
int VK_N = 0x4E;
|
||||
int VK_O = 0x4F;
|
||||
int VK_P = 0x50;
|
||||
int VK_Q = 0x51;
|
||||
int VK_R = 0x52;
|
||||
int VK_S = 0x53;
|
||||
int VK_T = 0x54;
|
||||
int VK_U = 0x55;
|
||||
int VK_V = 0x56;
|
||||
int VK_W = 0x57;
|
||||
int VK_X = 0x58;
|
||||
int VK_Y = 0x59;
|
||||
int VK_Z = 0x5A;
|
||||
|
||||
/**
|
||||
* Constant for the open bracket key, "["
|
||||
*/
|
||||
int VK_OPEN_BRACKET = 0x5B;
|
||||
|
||||
/**
|
||||
* Constant for the back slash key, "\"
|
||||
*/
|
||||
int VK_BACK_SLASH = 0x5C;
|
||||
|
||||
/**
|
||||
* Constant for the close bracket key, "]"
|
||||
*/
|
||||
int VK_CLOSE_BRACKET = 0x5D;
|
||||
|
||||
int VK_NUMPAD0 = 0x60;
|
||||
int VK_NUMPAD1 = 0x61;
|
||||
int VK_NUMPAD2 = 0x62;
|
||||
int VK_NUMPAD3 = 0x63;
|
||||
int VK_NUMPAD4 = 0x64;
|
||||
int VK_NUMPAD5 = 0x65;
|
||||
int VK_NUMPAD6 = 0x66;
|
||||
int VK_NUMPAD7 = 0x67;
|
||||
int VK_NUMPAD8 = 0x68;
|
||||
int VK_NUMPAD9 = 0x69;
|
||||
int VK_MULTIPLY = 0x6A;
|
||||
int VK_ADD = 0x6B;
|
||||
|
||||
/**
|
||||
* This constant is obsolete, and is included only for backwards
|
||||
* compatibility.
|
||||
* @see #VK_SEPARATOR
|
||||
*/
|
||||
int VK_SEPARATER = 0x6C;
|
||||
|
||||
/**
|
||||
* Constant for the Numpad Separator key.
|
||||
* @since 1.4
|
||||
*/
|
||||
int VK_SEPARATOR = VK_SEPARATER;
|
||||
|
||||
int VK_SUBTRACT = 0x6D;
|
||||
int VK_DECIMAL = 0x6E;
|
||||
int VK_DIVIDE = 0x6F;
|
||||
int VK_DELETE = 0x7F; /* ASCII DEL */
|
||||
int VK_NUM_LOCK = 0x90;
|
||||
int VK_SCROLL_LOCK = 0x91;
|
||||
|
||||
/** Constant for the F1 function key. */
|
||||
int VK_F1 = 0x70;
|
||||
|
||||
/** Constant for the F2 function key. */
|
||||
int VK_F2 = 0x71;
|
||||
|
||||
/** Constant for the F3 function key. */
|
||||
int VK_F3 = 0x72;
|
||||
|
||||
/** Constant for the F4 function key. */
|
||||
int VK_F4 = 0x73;
|
||||
|
||||
/** Constant for the F5 function key. */
|
||||
int VK_F5 = 0x74;
|
||||
|
||||
/** Constant for the F6 function key. */
|
||||
int VK_F6 = 0x75;
|
||||
|
||||
/** Constant for the F7 function key. */
|
||||
int VK_F7 = 0x76;
|
||||
|
||||
/** Constant for the F8 function key. */
|
||||
int VK_F8 = 0x77;
|
||||
|
||||
/** Constant for the F9 function key. */
|
||||
int VK_F9 = 0x78;
|
||||
|
||||
/** Constant for the F10 function key. */
|
||||
int VK_F10 = 0x79;
|
||||
|
||||
/** Constant for the F11 function key. */
|
||||
int VK_F11 = 0x7A;
|
||||
|
||||
/** Constant for the F12 function key. */
|
||||
int VK_F12 = 0x7B;
|
||||
|
||||
/**
|
||||
* Constant for the F13 function key.
|
||||
* @since 1.2
|
||||
*/
|
||||
/* F13 - F24 are used on IBM 3270 keyboard; use random range for constants. */
|
||||
int VK_F13 = 0xF000;
|
||||
|
||||
/**
|
||||
* Constant for the F14 function key.
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_F14 = 0xF001;
|
||||
|
||||
/**
|
||||
* Constant for the F15 function key.
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_F15 = 0xF002;
|
||||
|
||||
/**
|
||||
* Constant for the F16 function key.
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_F16 = 0xF003;
|
||||
|
||||
/**
|
||||
* Constant for the F17 function key.
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_F17 = 0xF004;
|
||||
|
||||
/**
|
||||
* Constant for the F18 function key.
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_F18 = 0xF005;
|
||||
|
||||
/**
|
||||
* Constant for the F19 function key.
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_F19 = 0xF006;
|
||||
|
||||
/**
|
||||
* Constant for the F20 function key.
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_F20 = 0xF007;
|
||||
|
||||
/**
|
||||
* Constant for the F21 function key.
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_F21 = 0xF008;
|
||||
|
||||
/**
|
||||
* Constant for the F22 function key.
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_F22 = 0xF009;
|
||||
|
||||
/**
|
||||
* Constant for the F23 function key.
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_F23 = 0xF00A;
|
||||
|
||||
/**
|
||||
* Constant for the F24 function key.
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_F24 = 0xF00B;
|
||||
|
||||
int VK_PRINTSCREEN = 0x9A;
|
||||
int VK_INSERT = 0x9B;
|
||||
int VK_HELP = 0x9C;
|
||||
int VK_META = 0x9D;
|
||||
|
||||
int VK_BACK_QUOTE = 0xC0;
|
||||
int VK_QUOTE = 0xDE;
|
||||
|
||||
/**
|
||||
* Constant for the numeric keypad <b>up</b> arrow key.
|
||||
* @see #VK_UP
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_KP_UP = 0xE0;
|
||||
|
||||
/**
|
||||
* Constant for the numeric keypad <b>down</b> arrow key.
|
||||
* @see #VK_DOWN
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_KP_DOWN = 0xE1;
|
||||
|
||||
/**
|
||||
* Constant for the numeric keypad <b>left</b> arrow key.
|
||||
* @see #VK_LEFT
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_KP_LEFT = 0xE2;
|
||||
|
||||
/**
|
||||
* Constant for the numeric keypad <b>right</b> arrow key.
|
||||
* @see #VK_RIGHT
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_KP_RIGHT = 0xE3;
|
||||
|
||||
/* For European keyboards */
|
||||
/** @since 1.2 */
|
||||
int VK_DEAD_GRAVE = 0x80;
|
||||
/** @since 1.2 */
|
||||
int VK_DEAD_ACUTE = 0x81;
|
||||
/** @since 1.2 */
|
||||
int VK_DEAD_CIRCUMFLEX = 0x82;
|
||||
/** @since 1.2 */
|
||||
int VK_DEAD_TILDE = 0x83;
|
||||
/** @since 1.2 */
|
||||
int VK_DEAD_MACRON = 0x84;
|
||||
/** @since 1.2 */
|
||||
int VK_DEAD_BREVE = 0x85;
|
||||
/** @since 1.2 */
|
||||
int VK_DEAD_ABOVEDOT = 0x86;
|
||||
/** @since 1.2 */
|
||||
int VK_DEAD_DIAERESIS = 0x87;
|
||||
/** @since 1.2 */
|
||||
int VK_DEAD_ABOVERING = 0x88;
|
||||
/** @since 1.2 */
|
||||
int VK_DEAD_DOUBLEACUTE = 0x89;
|
||||
/** @since 1.2 */
|
||||
int VK_DEAD_CARON = 0x8a;
|
||||
/** @since 1.2 */
|
||||
int VK_DEAD_CEDILLA = 0x8b;
|
||||
/** @since 1.2 */
|
||||
int VK_DEAD_OGONEK = 0x8c;
|
||||
/** @since 1.2 */
|
||||
int VK_DEAD_IOTA = 0x8d;
|
||||
/** @since 1.2 */
|
||||
int VK_DEAD_VOICED_SOUND = 0x8e;
|
||||
/** @since 1.2 */
|
||||
int VK_DEAD_SEMIVOICED_SOUND = 0x8f;
|
||||
|
||||
/** @since 1.2 */
|
||||
int VK_AMPERSAND = 0x96;
|
||||
/** @since 1.2 */
|
||||
int VK_ASTERISK = 0x97;
|
||||
/** @since 1.2 */
|
||||
int VK_QUOTEDBL = 0x98;
|
||||
/** @since 1.2 */
|
||||
int VK_LESS = 0x99;
|
||||
|
||||
/** @since 1.2 */
|
||||
int VK_GREATER = 0xa0;
|
||||
/** @since 1.2 */
|
||||
int VK_BRACELEFT = 0xa1;
|
||||
/** @since 1.2 */
|
||||
int VK_BRACERIGHT = 0xa2;
|
||||
|
||||
/**
|
||||
* Constant for the "@" key.
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_AT = 0x0200;
|
||||
|
||||
/**
|
||||
* Constant for the ":" key.
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_COLON = 0x0201;
|
||||
|
||||
/**
|
||||
* Constant for the "^" key.
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_CIRCUMFLEX = 0x0202;
|
||||
|
||||
/**
|
||||
* Constant for the "$" key.
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_DOLLAR = 0x0203;
|
||||
|
||||
/**
|
||||
* Constant for the Euro currency sign key.
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_EURO_SIGN = 0x0204;
|
||||
|
||||
/**
|
||||
* Constant for the "!" key.
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_EXCLAMATION_MARK = 0x0205;
|
||||
|
||||
/**
|
||||
* Constant for the inverted exclamation mark key.
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_INVERTED_EXCLAMATION_MARK = 0x0206;
|
||||
|
||||
/**
|
||||
* Constant for the "(" key.
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_LEFT_PARENTHESIS = 0x0207;
|
||||
|
||||
/**
|
||||
* Constant for the "#" key.
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_NUMBER_SIGN = 0x0208;
|
||||
|
||||
/**
|
||||
* Constant for the "+" key.
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_PLUS = 0x0209;
|
||||
|
||||
/**
|
||||
* Constant for the ")" key.
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_RIGHT_PARENTHESIS = 0x020A;
|
||||
|
||||
/**
|
||||
* Constant for the "_" key.
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_UNDERSCORE = 0x020B;
|
||||
|
||||
/**
|
||||
* Constant for the Microsoft Windows "Windows" key.
|
||||
* It is used for both the left and right version of the key.
|
||||
* @see #getKeyLocation()
|
||||
* @since 1.5
|
||||
*/
|
||||
int VK_WINDOWS = 0x020C;
|
||||
|
||||
/**
|
||||
* Constant for the Microsoft Windows Context Menu key.
|
||||
* @since 1.5
|
||||
*/
|
||||
int VK_CONTEXT_MENU = 0x020D;
|
||||
|
||||
/* for input method support on Asian Keyboards */
|
||||
|
||||
/* not clear what this means - listed in Microsoft Windows API */
|
||||
int VK_FINAL = 0x0018;
|
||||
|
||||
/** Constant for the Convert function key. */
|
||||
/* Japanese PC 106 keyboard, Japanese Solaris keyboard: henkan */
|
||||
int VK_CONVERT = 0x001C;
|
||||
|
||||
/** Constant for the Don't Convert function key. */
|
||||
/* Japanese PC 106 keyboard: muhenkan */
|
||||
int VK_NONCONVERT = 0x001D;
|
||||
|
||||
/** Constant for the Accept or Commit function key. */
|
||||
/* Japanese Solaris keyboard: kakutei */
|
||||
int VK_ACCEPT = 0x001E;
|
||||
|
||||
/* not clear what this means - listed in Microsoft Windows API */
|
||||
int VK_MODECHANGE = 0x001F;
|
||||
|
||||
/* replaced by VK_KANA_LOCK for Microsoft Windows and Solaris;
|
||||
might still be used on other platforms */
|
||||
int VK_KANA = 0x0015;
|
||||
|
||||
/* replaced by VK_INPUT_METHOD_ON_OFF for Microsoft Windows and Solaris;
|
||||
might still be used for other platforms */
|
||||
int VK_KANJI = 0x0019;
|
||||
|
||||
/**
|
||||
* Constant for the Alphanumeric function key.
|
||||
* @since 1.2
|
||||
*/
|
||||
/* Japanese PC 106 keyboard: eisuu */
|
||||
int VK_ALPHANUMERIC = 0x00F0;
|
||||
|
||||
/**
|
||||
* Constant for the Katakana function key.
|
||||
* @since 1.2
|
||||
*/
|
||||
/* Japanese PC 106 keyboard: katakana */
|
||||
int VK_KATAKANA = 0x00F1;
|
||||
|
||||
/**
|
||||
* Constant for the Hiragana function key.
|
||||
* @since 1.2
|
||||
*/
|
||||
/* Japanese PC 106 keyboard: hiragana */
|
||||
int VK_HIRAGANA = 0x00F2;
|
||||
|
||||
/**
|
||||
* Constant for the Full-Width Characters function key.
|
||||
* @since 1.2
|
||||
*/
|
||||
/* Japanese PC 106 keyboard: zenkaku */
|
||||
int VK_FULL_WIDTH = 0x00F3;
|
||||
|
||||
/**
|
||||
* Constant for the Half-Width Characters function key.
|
||||
* @since 1.2
|
||||
*/
|
||||
/* Japanese PC 106 keyboard: hankaku */
|
||||
int VK_HALF_WIDTH = 0x00F4;
|
||||
|
||||
/**
|
||||
* Constant for the Roman Characters function key.
|
||||
* @since 1.2
|
||||
*/
|
||||
/* Japanese PC 106 keyboard: roumaji */
|
||||
int VK_ROMAN_CHARACTERS = 0x00F5;
|
||||
|
||||
/**
|
||||
* Constant for the All Candidates function key.
|
||||
* @since 1.2
|
||||
*/
|
||||
/* Japanese PC 106 keyboard - VK_CONVERT + ALT: zenkouho */
|
||||
int VK_ALL_CANDIDATES = 0x0100;
|
||||
|
||||
/**
|
||||
* Constant for the Previous Candidate function key.
|
||||
* @since 1.2
|
||||
*/
|
||||
/* Japanese PC 106 keyboard - VK_CONVERT + SHIFT: maekouho */
|
||||
int VK_PREVIOUS_CANDIDATE = 0x0101;
|
||||
|
||||
/**
|
||||
* Constant for the Code Input function key.
|
||||
* @since 1.2
|
||||
*/
|
||||
/* Japanese PC 106 keyboard - VK_ALPHANUMERIC + ALT: kanji bangou */
|
||||
int VK_CODE_INPUT = 0x0102;
|
||||
|
||||
/**
|
||||
* Constant for the Japanese-Katakana function key.
|
||||
* This key switches to a Japanese input method and selects its Katakana input mode.
|
||||
* @since 1.2
|
||||
*/
|
||||
/* Japanese Macintosh keyboard - VK_JAPANESE_HIRAGANA + SHIFT */
|
||||
int VK_JAPANESE_KATAKANA = 0x0103;
|
||||
|
||||
/**
|
||||
* Constant for the Japanese-Hiragana function key.
|
||||
* This key switches to a Japanese input method and selects its Hiragana input mode.
|
||||
* @since 1.2
|
||||
*/
|
||||
/* Japanese Macintosh keyboard */
|
||||
int VK_JAPANESE_HIRAGANA = 0x0104;
|
||||
|
||||
/**
|
||||
* Constant for the Japanese-Roman function key.
|
||||
* This key switches to a Japanese input method and selects its Roman-Direct input mode.
|
||||
* @since 1.2
|
||||
*/
|
||||
/* Japanese Macintosh keyboard */
|
||||
int VK_JAPANESE_ROMAN = 0x0105;
|
||||
|
||||
/**
|
||||
* Constant for the locking Kana function key.
|
||||
* This key locks the keyboard into a Kana layout.
|
||||
* @since 1.3
|
||||
*/
|
||||
/* Japanese PC 106 keyboard with special Windows driver - eisuu + Control; Japanese Solaris keyboard: kana */
|
||||
int VK_KANA_LOCK = 0x0106;
|
||||
|
||||
/**
|
||||
* Constant for the input method on/off key.
|
||||
* @since 1.3
|
||||
*/
|
||||
/* Japanese PC 106 keyboard: kanji. Japanese Solaris keyboard: nihongo */
|
||||
int VK_INPUT_METHOD_ON_OFF = 0x0107;
|
||||
|
||||
/* for Sun keyboards */
|
||||
/** @since 1.2 */
|
||||
int VK_CUT = 0xFFD1;
|
||||
/** @since 1.2 */
|
||||
int VK_COPY = 0xFFCD;
|
||||
/** @since 1.2 */
|
||||
int VK_PASTE = 0xFFCF;
|
||||
/** @since 1.2 */
|
||||
int VK_UNDO = 0xFFCB;
|
||||
/** @since 1.2 */
|
||||
int VK_AGAIN = 0xFFC9;
|
||||
/** @since 1.2 */
|
||||
int VK_FIND = 0xFFD0;
|
||||
/** @since 1.2 */
|
||||
int VK_PROPS = 0xFFCA;
|
||||
/** @since 1.2 */
|
||||
int VK_STOP = 0xFFC8;
|
||||
|
||||
/**
|
||||
* Constant for the Compose function key.
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_COMPOSE = 0xFF20;
|
||||
|
||||
/**
|
||||
* Constant for the AltGraph function key.
|
||||
* @since 1.2
|
||||
*/
|
||||
int VK_ALT_GRAPH = 0xFF7E;
|
||||
|
||||
/**
|
||||
* Constant for the Begin key.
|
||||
* @since 1.5
|
||||
*/
|
||||
int VK_BEGIN = 0xFF58;
|
||||
|
||||
/**
|
||||
* This value is used to indicate that the keyCode is unknown.
|
||||
* KEY_TYPED events do not have a keyCode value; this value
|
||||
* is used instead.
|
||||
*/
|
||||
int VK_UNDEFINED = 0x0;
|
||||
|
||||
/**
|
||||
* KEY_PRESSED and KEY_RELEASED events which do not map to a
|
||||
* valid Unicode character use this for the keyChar value.
|
||||
*/
|
||||
char CHAR_UNDEFINED = 0xFFFF;
|
||||
|
||||
/**
|
||||
* A constant indicating that the keyLocation is indeterminate
|
||||
* or not relevant.
|
||||
* <code>KEY_TYPED</code> events do not have a keyLocation; this value
|
||||
* is used instead.
|
||||
* @since 1.4
|
||||
*/
|
||||
int KEY_LOCATION_UNKNOWN = 0;
|
||||
|
||||
/**
|
||||
* A constant indicating that the key pressed or released
|
||||
* is not distinguished as the left or right version of a key,
|
||||
* and did not originate on the numeric keypad (or did not
|
||||
* originate with a virtual key corresponding to the numeric
|
||||
* keypad).
|
||||
* @since 1.4
|
||||
*/
|
||||
int KEY_LOCATION_STANDARD = 1;
|
||||
|
||||
/**
|
||||
* A constant indicating that the key pressed or released is in
|
||||
* the left key location (there is more than one possible location
|
||||
* for this key). Example: the left shift key.
|
||||
* @since 1.4
|
||||
*/
|
||||
int KEY_LOCATION_LEFT = 2;
|
||||
|
||||
/**
|
||||
* A constant indicating that the key pressed or released is in
|
||||
* the right key location (there is more than one possible location
|
||||
* for this key). Example: the right shift key.
|
||||
* @since 1.4
|
||||
*/
|
||||
int KEY_LOCATION_RIGHT = 3;
|
||||
|
||||
/**
|
||||
* A constant indicating that the key event originated on the
|
||||
* numeric keypad or with a virtual key corresponding to the
|
||||
* numeric keypad.
|
||||
* @since 1.4
|
||||
*/
|
||||
int KEY_LOCATION_NUMPAD = 4;
|
||||
}
|
@ -13,7 +13,7 @@ public class PIHardwareDisplay implements HardwareDisplay {
|
||||
|
||||
@Override
|
||||
public void setBrightness(final double value) {
|
||||
if (Engine.getPlatform().getSettings().isDebugEnabled() == false) {
|
||||
if (Engine.getPlatform().isRunningOnRaspberry()) {
|
||||
Engine.getPlatform().getGpio().pwmWrite(12, (int) Math.ceil(value * 1024f));
|
||||
// SoftPwm.softPwmWrite(12, (int)(Math.ceil(brightness*10)));
|
||||
} else {
|
||||
|
@ -1,7 +1,5 @@
|
||||
package it.cavallium.warppi.device.graphicengine;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
@ -9,8 +7,6 @@ import java.net.URL;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import it.cavallium.warppi.Engine;
|
||||
import it.cavallium.warppi.util.ClassUtils;
|
||||
import it.cavallium.warppi.util.Utils;
|
||||
@ -135,18 +131,6 @@ public class RAWFont {
|
||||
return indexes;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private void saveArray(final int[] screen, final String coutputpng) {
|
||||
final BufferedImage bi = new BufferedImage(300, 200, BufferedImage.TYPE_INT_RGB);
|
||||
final int[] a = ((DataBufferInt) bi.getRaster().getDataBuffer()).getData();
|
||||
System.arraycopy(screen, 0, a, 0, screen.length);
|
||||
try {
|
||||
ImageIO.write(bi, "PNG", new File(coutputpng));
|
||||
} catch (final IOException ex) {
|
||||
Logger.getLogger(RAWFont.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void drawText(final int[] screen, final int[] screenSize, final int x, final int y, final int[] text,
|
||||
final int color) {
|
||||
final int screenLength = screen.length;
|
||||
|
@ -7,6 +7,7 @@ import it.cavallium.warppi.StaticVars;
|
||||
import it.cavallium.warppi.Platform.ConsoleUtils;
|
||||
import it.cavallium.warppi.device.Keyboard;
|
||||
import it.cavallium.warppi.event.KeyPressedEvent;
|
||||
import it.cavallium.warppi.event.KeyReleasedEvent;
|
||||
import it.cavallium.warppi.gui.HistoryBehavior;
|
||||
import it.cavallium.warppi.gui.graphicengine.BinaryFont;
|
||||
import it.cavallium.warppi.gui.graphicengine.Skin;
|
||||
@ -43,6 +44,43 @@ public class MarioScreen extends Screen {
|
||||
historyBehavior = HistoryBehavior.ALWAYS_KEEP_IN_HISTORY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void graphicInitialized() {
|
||||
try {
|
||||
if (MarioScreen.skin == null) {
|
||||
MarioScreen.skin = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadSkin("/marioskin.png");
|
||||
}
|
||||
if (MarioScreen.groundskin == null) {
|
||||
MarioScreen.groundskin = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadSkin("/marioground.png");
|
||||
}
|
||||
if (MarioScreen.gpuTest2 == null) {
|
||||
try {
|
||||
MarioScreen.gpuTest2 = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadFont("N:\\gputest\\gputest2");
|
||||
} catch (final Exception ex) {}
|
||||
}
|
||||
if (MarioScreen.gpuTest1 == null) {
|
||||
try {
|
||||
MarioScreen.gpuTest1 = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadFont("N:\\gputest\\gputest12");
|
||||
MarioScreen.gpuTest12 = true;
|
||||
} catch (final Exception ex) {
|
||||
MarioScreen.gpuTest12 = false;
|
||||
try {
|
||||
MarioScreen.gpuTest1 = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadFont("N:\\gputest\\gputest1");
|
||||
} catch (final Exception ex2) {}
|
||||
}
|
||||
}
|
||||
if (MarioScreen.gpuTest3 == null) {
|
||||
try {
|
||||
MarioScreen.gpuTest3 = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadSkin("N:\\gputest\\font_gputest3.png");
|
||||
} catch (final Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialized() {
|
||||
try {
|
||||
@ -87,12 +125,49 @@ public class MarioScreen extends Screen {
|
||||
}
|
||||
}
|
||||
|
||||
boolean rightPressed, leftPressed, jumpPressed;
|
||||
|
||||
@Override
|
||||
public boolean onKeyPressed(KeyPressedEvent k) {
|
||||
switch(k.getKey()) {
|
||||
case OK:
|
||||
case SIMPLIFY:
|
||||
case STEP:
|
||||
jumpPressed = true;
|
||||
return true;
|
||||
case LEFT:
|
||||
leftPressed = true;
|
||||
return true;
|
||||
case RIGHT:
|
||||
rightPressed = true;
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyReleased(KeyReleasedEvent k) {
|
||||
switch(k.getKey()) {
|
||||
case OK:
|
||||
case SIMPLIFY:
|
||||
case STEP:
|
||||
jumpPressed = false;
|
||||
return true;
|
||||
case LEFT:
|
||||
leftPressed = false;
|
||||
return true;
|
||||
case RIGHT:
|
||||
rightPressed = false;
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeRender(final float dt) {
|
||||
if (!errored) {
|
||||
final boolean rightPressed = Keyboard.isKeyDown(2, 5);
|
||||
final boolean leftPressed = Keyboard.isKeyDown(2, 3);
|
||||
final boolean jumpPressed = Keyboard.isKeyDown(2, 1);
|
||||
final boolean upPressed = false, downPressed = false, runPressed = false;
|
||||
g.gameTick(dt, upPressed, downPressed, leftPressed, rightPressed, jumpPressed, runPressed);
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
package it.cavallium.warppi.extra.tetris;
|
||||
|
||||
public enum BlockType {
|
||||
public enum BlockColor {
|
||||
RED,
|
||||
GREEN,
|
||||
YELLOW,
|
||||
BLUE,
|
||||
YELLOW,
|
||||
ORANGE,
|
||||
VIOLET
|
||||
PURPLE,
|
||||
CYAN
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package it.cavallium.warppi.extra.tetris;
|
||||
|
||||
public class ButtonInfo {
|
||||
|
||||
public volatile int pressedCount = 0;
|
||||
public volatile int releasedCount = 0;
|
||||
public volatile int unreadCount = 0;
|
||||
|
||||
public ButtonInfo() {
|
||||
|
||||
}
|
||||
|
||||
public void press() {
|
||||
if (pressedCount <= releasedCount) {
|
||||
pressedCount = releasedCount + 1;
|
||||
unreadCount++;
|
||||
}
|
||||
}
|
||||
|
||||
public void release() {
|
||||
releasedCount++;
|
||||
pressedCount = releasedCount;
|
||||
}
|
||||
|
||||
public int readPressed() {
|
||||
int val = unreadCount;
|
||||
unreadCount = 0;
|
||||
return val;
|
||||
}
|
||||
|
||||
public boolean hasUnreadData() {
|
||||
return unreadCount > 0;
|
||||
}
|
||||
|
||||
public boolean isPressedNow() {
|
||||
return pressedCount > releasedCount;
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package it.cavallium.warppi.extra.tetris;
|
||||
|
||||
public class MarioBlock {
|
||||
private final int x;
|
||||
private final int y;
|
||||
private final byte id;
|
||||
|
||||
public MarioBlock(final int x, final int y, final byte b) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
id = b;
|
||||
}
|
||||
|
||||
public boolean isSolid() {
|
||||
return MarioBlock.isSolid(id);
|
||||
}
|
||||
|
||||
public byte getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public static boolean isSolid(final byte id) {
|
||||
return id != 0b0;
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package it.cavallium.warppi.extra.tetris;
|
||||
|
||||
public class MarioEnemy extends MarioEntity {
|
||||
|
||||
public MarioEnemy(final double x, final double y, final double forceX, final double forceY, final boolean onGround, final boolean subjectToGravity) {
|
||||
super(x, y, forceX, forceY, onGround, subjectToGravity);
|
||||
}
|
||||
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
package it.cavallium.warppi.extra.tetris;
|
||||
|
||||
public class MarioEntity {
|
||||
protected double x;
|
||||
protected double y;
|
||||
public double forceX;
|
||||
public double forceY;
|
||||
public boolean collisionUp;
|
||||
public boolean collisionDown;
|
||||
public boolean collisionLeft;
|
||||
public boolean collisionRight;
|
||||
public boolean subjectToGravity;
|
||||
|
||||
public MarioEntity(final double x, final double y, final double forceX, final double forceY, final boolean onGround, final boolean subjectToGravity) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.forceX = forceX;
|
||||
this.forceY = forceY;
|
||||
collisionDown = onGround;
|
||||
this.subjectToGravity = subjectToGravity;
|
||||
}
|
||||
|
||||
public void setPosition(final double x, final double y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public void setPosition(final double x, final double y, final boolean onGround) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
collisionDown = onGround;
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public boolean isOnGround() {
|
||||
return collisionDown;
|
||||
}
|
||||
|
||||
public void setOnGround(final boolean onGround) {
|
||||
collisionDown = onGround;
|
||||
}
|
||||
|
||||
public void gameTick(final double dt) {
|
||||
x = computeFutureDX(dt);
|
||||
y = computeFutureDY(dt);
|
||||
forceX = computeFutureForceDX(dt);
|
||||
forceY = computeFutureForceDY(dt);
|
||||
}
|
||||
|
||||
public double computeFutureDX(final double dt) {
|
||||
return x + dt * forceX - x;
|
||||
}
|
||||
|
||||
public double computeFutureDY(final double dt) {
|
||||
final double forceY = this.forceY;
|
||||
double y = this.y;
|
||||
if (!collisionDown) {
|
||||
y += dt * forceY;
|
||||
}
|
||||
return y - this.y;
|
||||
}
|
||||
|
||||
public double computeFutureForceDX(final double dt) {
|
||||
double forceX = this.forceX;
|
||||
forceX *= 0.75;
|
||||
return forceX - this.forceX;
|
||||
}
|
||||
|
||||
public double computeFutureForceDY(final double dt) {
|
||||
double forceY = this.forceY;
|
||||
if (subjectToGravity && !collisionDown) {
|
||||
forceY -= dt * 1569.6 / 16f;
|
||||
} else {
|
||||
forceY *= 0.75;
|
||||
}
|
||||
return forceY - this.forceY;
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package it.cavallium.warppi.extra.tetris;
|
||||
|
||||
public class MarioEvent {
|
||||
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
package it.cavallium.warppi.extra.tetris;
|
||||
|
||||
public class MarioWorld {
|
||||
|
||||
private final int[] spawnPoint;
|
||||
private final int width;
|
||||
private final int height;
|
||||
private final byte[][] data;
|
||||
@SuppressWarnings("unused")
|
||||
private final MarioEvent[] events;
|
||||
private final MarioEntity[] entities;
|
||||
|
||||
/**
|
||||
* @param width
|
||||
* @param height
|
||||
* @param data
|
||||
* @param events
|
||||
* @param marioEnemies
|
||||
*/
|
||||
public MarioWorld(final int[] spawnPoint, final int width, final int height, final byte[][] data, final MarioEvent[] events, final MarioEntity[] entities) {
|
||||
this.spawnPoint = spawnPoint;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.data = data;
|
||||
this.events = events;
|
||||
this.entities = entities;
|
||||
}
|
||||
|
||||
public byte getBlockIdAt(final int x, final int y) {
|
||||
final int idy = height - 1 - y;
|
||||
if (idy < 0 || idy >= data.length) {
|
||||
return 0b0;
|
||||
}
|
||||
final int idx = x;
|
||||
if (idx < 0 || idx >= data[0].length) {
|
||||
return 0b0;
|
||||
}
|
||||
return data[idy][idx];
|
||||
}
|
||||
|
||||
public MarioBlock getBlockAt(final int x, final int y) {
|
||||
return new MarioBlock(x, y, getBlockIdAt(x, y));
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
|
||||
}
|
||||
|
||||
public double getSpawnPointX() {
|
||||
return spawnPoint[0];
|
||||
}
|
||||
|
||||
public double getSpawnPointY() {
|
||||
return spawnPoint[1];
|
||||
}
|
||||
|
||||
public MarioEntity[] getEntities() {
|
||||
return entities;
|
||||
}
|
||||
|
||||
}
|
@ -1,138 +0,0 @@
|
||||
package it.cavallium.warppi.extra.tetris;
|
||||
|
||||
public class PlayerEntity extends MarioEntity {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final int life;
|
||||
public float walkAnimation = 0;
|
||||
public float jumptime = 0;
|
||||
public boolean walking = false;
|
||||
public boolean running = false;
|
||||
public boolean jumping = false;
|
||||
public boolean flipped = false;
|
||||
public int[] marioSkinPos = new int[] { 0, 0 };
|
||||
private double controllerDX;
|
||||
private double controllerDY;
|
||||
|
||||
public PlayerEntity(final double x, final double y, final int life) {
|
||||
super(x, y, 0, 0, true, true);
|
||||
this.life = life;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void gameTick(final double dt) {
|
||||
walkAnimation += dt;
|
||||
x += computeFutureDX(dt);
|
||||
y += computeFutureDY(dt);
|
||||
forceX += computeFutureForceDX(dt);
|
||||
forceY += computeFutureForceDY(dt);
|
||||
if (controllerDX == 0) {
|
||||
walking = false;
|
||||
walkAnimation = 0;
|
||||
} else {
|
||||
if (controllerDX > 0) { //RIGHT
|
||||
walking = true;
|
||||
flipped = false;
|
||||
}
|
||||
if (controllerDX < 0) { //LEFT
|
||||
walking = true;
|
||||
flipped = true;
|
||||
}
|
||||
}
|
||||
if (controllerDY > 0) { //JUMP
|
||||
if (collisionUp) {
|
||||
jumptime = Float.MAX_VALUE;
|
||||
jumping = false;
|
||||
}
|
||||
jumptime += dt;
|
||||
if (jumptime <= 0.5f && !jumping && collisionDown) {
|
||||
jumping = true;
|
||||
collisionDown = false;
|
||||
} else if (jumptime <= 0.5f) {} else {
|
||||
jumping = false;
|
||||
}
|
||||
} else {
|
||||
jumping = false;
|
||||
if (collisionDown) {
|
||||
jumptime = 0;
|
||||
} else {
|
||||
jumptime = Float.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
if (!walking & !running & !jumping) {
|
||||
marioSkinPos[0] = 0;
|
||||
marioSkinPos[1] = 0;
|
||||
} else if (collisionDown & walking & !running & !jumping && walkAnimation >= 0.08) {
|
||||
while (walkAnimation > 0.08) {
|
||||
walkAnimation -= 0.08;
|
||||
if (marioSkinPos[0] == 1 & marioSkinPos[1] == 0) {
|
||||
marioSkinPos[0] += 2;
|
||||
} else if (marioSkinPos[0] == 3 & marioSkinPos[1] == 0) {
|
||||
marioSkinPos[0] -= 1;
|
||||
} else if (marioSkinPos[0] == 2 & marioSkinPos[1] == 0) {
|
||||
marioSkinPos[0] -= 1;
|
||||
} else {
|
||||
marioSkinPos[0] = 1;
|
||||
marioSkinPos[1] = 0;
|
||||
}
|
||||
}
|
||||
} else if (jumping) {
|
||||
marioSkinPos[0] = 5;
|
||||
marioSkinPos[1] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double computeFutureDX(final double dt) {
|
||||
return super.computeFutureDX(dt);
|
||||
}
|
||||
|
||||
public double computeFuturedDY(final double dt) {
|
||||
return super.computeFutureDY(dt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double computeFutureForceDX(final double dt) {
|
||||
double forceX = this.forceX;
|
||||
if (controllerDX == 0) {} else {
|
||||
if (controllerDX > 0) {
|
||||
if (forceX < 500f / 16f) {
|
||||
forceX += dt * 500f / 16f;
|
||||
}
|
||||
}
|
||||
if (controllerDX < 0) {
|
||||
if (forceX > -500f / 16f) {
|
||||
forceX -= dt * 500f / 16f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return forceX + super.computeFutureForceDX(dt) - this.forceX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double computeFutureForceDY(final double dt) {
|
||||
float jumptime = this.jumptime;
|
||||
double forceY = this.forceY;
|
||||
if (controllerDY > 0) { //JUMP
|
||||
if (collisionUp) {
|
||||
jumptime = Float.MAX_VALUE;
|
||||
}
|
||||
jumptime += dt;
|
||||
if (jumptime <= 0.5f && !jumping && collisionDown) {
|
||||
forceY = dt * (4 * 1569.6f) / 16f;
|
||||
} else if (jumptime <= 0.5f) {
|
||||
forceY = dt * (4 * 1569.6f) / 16f;
|
||||
}
|
||||
}
|
||||
return forceY + super.computeFutureForceDY(dt) - this.forceY;
|
||||
}
|
||||
|
||||
public void move(final float dt, final double dX, final double dY) {
|
||||
walkAnimation += dt;
|
||||
|
||||
controllerDX = dX;
|
||||
controllerDY = dY;
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package it.cavallium.warppi.extra.tetris;
|
||||
|
||||
public class PositionEvent extends MarioEvent {
|
||||
|
||||
}
|
@ -1,21 +1,234 @@
|
||||
package it.cavallium.warppi.extra.tetris;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class TetrisGame {
|
||||
|
||||
private static final int WIDTH = 10, HEIGHT = 22;
|
||||
private BlockType[] grid;
|
||||
private BlockType[] hovergrid;
|
||||
private GameStatus gameStatus = GameStatus.INITIAL;
|
||||
private int score = 0;
|
||||
public static final int WIDTH = 10, HEIGHT = 22;
|
||||
public static final double TICK_TIME = 0.25, DOWN_TIME = 0.10, MOVE_TIMER = 0.125;
|
||||
private double tickTimer, downTimer, leftTimer, rightTimer, upTimer;
|
||||
private BlockColor[] grid;
|
||||
private BlockColor[] hovergrid;
|
||||
private volatile BlockColor[] renderedGrid;
|
||||
private GameStatus gameStatus;
|
||||
private int score;
|
||||
private double currentTime;
|
||||
private Tetromino currentTetromino;
|
||||
private Tetromino nextTetromino;
|
||||
|
||||
public TetrisGame() {
|
||||
|
||||
resetVariables();
|
||||
}
|
||||
|
||||
private void playAgain() {
|
||||
grid = new BlockType[WIDTH * HEIGHT];
|
||||
hovergrid = new BlockType[WIDTH * HEIGHT];
|
||||
score = 0;
|
||||
void playAgain() {
|
||||
resetVariables();
|
||||
gameStatus = GameStatus.PLAYING;
|
||||
placeNextTetromino();
|
||||
}
|
||||
|
||||
private void resetVariables() {
|
||||
grid = new BlockColor[WIDTH * HEIGHT];
|
||||
hovergrid = new BlockColor[WIDTH * HEIGHT];
|
||||
renderedGrid = new BlockColor[WIDTH * HEIGHT];
|
||||
score = 0;
|
||||
currentTime = 0;
|
||||
tickTimer = 0;
|
||||
gameStatus = GameStatus.INITIAL;
|
||||
currentTetromino = null;
|
||||
nextTetromino = generateRandomTetromino();
|
||||
nextTetromino.fixInitialPosition();
|
||||
}
|
||||
|
||||
public void update(float dt, ButtonInfo leftPressed, ButtonInfo rightPressed, ButtonInfo downPressed,
|
||||
ButtonInfo upPressed, ButtonInfo okPressed, ButtonInfo backPressed) {
|
||||
currentTime += dt;
|
||||
tickTimer += dt;
|
||||
leftTimer += dt;
|
||||
rightTimer += dt;
|
||||
downTimer += dt;
|
||||
upTimer += dt;
|
||||
if (leftPressed.hasUnreadData()) {
|
||||
for (int i = leftPressed.readPressed(); i > 0; i--) {
|
||||
move(this.currentTetromino, -1, 0, 0);
|
||||
}
|
||||
leftTimer = -MOVE_TIMER;
|
||||
} else if (leftPressed.isPressedNow()) {
|
||||
while (leftTimer >= MOVE_TIMER) {
|
||||
leftTimer -= MOVE_TIMER;
|
||||
move(this.currentTetromino, -1, 0, 0);
|
||||
}
|
||||
} else {
|
||||
leftTimer = 0;
|
||||
}
|
||||
if (rightPressed.hasUnreadData()) {
|
||||
for (int i = rightPressed.readPressed(); i > 0; i--) {
|
||||
move(this.currentTetromino, 1, 0, 0);
|
||||
}
|
||||
rightTimer = -MOVE_TIMER;
|
||||
} else if (rightPressed.isPressedNow()) {
|
||||
while (rightTimer >= MOVE_TIMER) {
|
||||
rightTimer -= MOVE_TIMER;
|
||||
move(this.currentTetromino, 1, 0, 0);
|
||||
}
|
||||
} else {
|
||||
rightTimer = 0;
|
||||
}
|
||||
if (upPressed.hasUnreadData()) {
|
||||
for (int i = upPressed.readPressed(); i > 0; i--) {
|
||||
move(this.currentTetromino, 0, 0, 1);
|
||||
}
|
||||
upTimer = -MOVE_TIMER;
|
||||
} else if (upPressed.isPressedNow()) {
|
||||
while (upTimer >= MOVE_TIMER) {
|
||||
upTimer -= MOVE_TIMER;
|
||||
move(this.currentTetromino, 0, 0, 1);
|
||||
}
|
||||
} else {
|
||||
upTimer = 0;
|
||||
}
|
||||
if (downPressed.isPressedNow()) {
|
||||
downPressed.readPressed();
|
||||
while (downTimer >= DOWN_TIME) {
|
||||
downTimer -= DOWN_TIME;
|
||||
move(this.currentTetromino, 0, 1, 0);
|
||||
}
|
||||
} else {
|
||||
downTimer = 0;
|
||||
}
|
||||
while (tickTimer >= TICK_TIME) {
|
||||
tickTimer -= TICK_TIME;
|
||||
gameTick(leftPressed, rightPressed, downPressed, okPressed, backPressed);
|
||||
}
|
||||
if (gameStatus == GameStatus.INITIAL) {
|
||||
playAgain();
|
||||
} else {
|
||||
|
||||
}
|
||||
renderGrid();
|
||||
}
|
||||
|
||||
public void gameTick(ButtonInfo leftPressed, ButtonInfo rightPressed, ButtonInfo downPressed, ButtonInfo okPressed,
|
||||
ButtonInfo backPressed) {
|
||||
if (move(this.currentTetromino, 0, 1, 0)) {
|
||||
|
||||
} else {
|
||||
// Spawn new tetromino and write the old to the permanent grid
|
||||
drawCurrentTetromino(grid);
|
||||
checkLines();
|
||||
placeNextTetromino();
|
||||
if (move(this.currentTetromino, 0, 0, 0) == false) {
|
||||
// Lose
|
||||
this.gameStatus = GameStatus.LOST;
|
||||
playAgain();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkLines() {
|
||||
for (int i = HEIGHT - 1; i >= 0; i--) {
|
||||
boolean scored = true;
|
||||
while (scored) {
|
||||
for (int x = 0; x < WIDTH; x++) {
|
||||
if (this.grid[x + i * WIDTH] == null) {
|
||||
scored = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (scored) {
|
||||
this.score += WIDTH;
|
||||
for (int x = 0; x < WIDTH; x++) {
|
||||
int y = i;
|
||||
while (y > 0) {
|
||||
this.grid[x + (y) * WIDTH] = this.grid[x + (y - 1) * WIDTH];
|
||||
y--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean move(Tetromino t, int dX, int dY, int dRotation) {
|
||||
byte rot = (byte) ((t.getRotation() + dRotation) % 4);
|
||||
boolean[] block = t.getRenderedBlock(rot);
|
||||
int blockSize = t.getTetrominoGridSize();
|
||||
int half1 = (int) Math.floor(((double) t.getTetrominoGridSize()) / 2d);
|
||||
int half2 = blockSize - half1;
|
||||
byte aX = (byte) (t.getX() + dX), aY = (byte) (t.getY() + dY);
|
||||
int blockX = 0, blockY = 0;
|
||||
for (int x = aX - half1; x < aX + half2; x++) {
|
||||
for (int y = aY - half1; y < aY + half2; y++) {
|
||||
if (block[blockX + blockY * blockSize] == true) {
|
||||
if (x >= 0 & y >= 0 & x < WIDTH & (x + y * WIDTH) < this.grid.length) {
|
||||
if (this.grid[x + y * WIDTH] != null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
blockY++;
|
||||
}
|
||||
blockY = 0;
|
||||
blockX++;
|
||||
}
|
||||
t.setRotation(rot);
|
||||
t.setX(aX);
|
||||
t.setY(aY);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void renderGrid() {
|
||||
this.renderedGrid = Arrays.copyOf(grid, grid.length);
|
||||
drawCurrentTetromino(this.renderedGrid);
|
||||
for (int y = 0; y < HEIGHT; y++) {
|
||||
for (int x = 0; x < WIDTH; x++) {
|
||||
final int offset = x + y * WIDTH;
|
||||
renderedGrid[offset] = hovergrid[offset] != null ? hovergrid[offset] : renderedGrid[offset];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void placeNextTetromino() {
|
||||
currentTetromino = nextTetromino;
|
||||
nextTetromino = generateRandomTetromino();
|
||||
nextTetromino.fixInitialPosition();
|
||||
}
|
||||
|
||||
private Tetromino generateRandomTetromino() {
|
||||
int s = (int) (Math.random() * 7);
|
||||
final byte middleX = (byte) ((WIDTH - 1) / 2), middleY = 0, rotation = (byte) (Math.random() * 4);
|
||||
switch (s) {
|
||||
case 0:
|
||||
return new TetrominoICyan(middleX, middleY, rotation);
|
||||
case 1:
|
||||
return new TetrominoJBlue(middleX, middleY, rotation);
|
||||
case 2:
|
||||
return new TetrominoLOrange(middleX, middleY, rotation);
|
||||
case 3:
|
||||
return new TetrominoOYellow(middleX, middleY, rotation);
|
||||
case 4:
|
||||
return new TetrominoSGreen(middleX, middleY, rotation);
|
||||
case 5:
|
||||
return new TetrominoTPurple(middleX, middleY, rotation);
|
||||
default:
|
||||
return new TetrominoZRed(middleX, middleY, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
public Tetromino getNextTetromino() {
|
||||
return this.nextTetromino;
|
||||
}
|
||||
|
||||
private void drawCurrentTetromino(BlockColor[] grid) {
|
||||
currentTetromino.draw(grid, WIDTH);
|
||||
}
|
||||
|
||||
public BlockColor[] getRenderedGrid() {
|
||||
return renderedGrid;
|
||||
}
|
||||
|
||||
public int getScore() {
|
||||
return this.score;
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,12 @@ import java.io.IOException;
|
||||
import it.cavallium.warppi.Engine;
|
||||
import it.cavallium.warppi.StaticVars;
|
||||
import it.cavallium.warppi.device.Keyboard;
|
||||
import it.cavallium.warppi.event.KeyPressedEvent;
|
||||
import it.cavallium.warppi.event.KeyReleasedEvent;
|
||||
import it.cavallium.warppi.gui.HistoryBehavior;
|
||||
import it.cavallium.warppi.gui.graphicengine.BinaryFont;
|
||||
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
|
||||
import it.cavallium.warppi.gui.graphicengine.Renderer;
|
||||
import it.cavallium.warppi.gui.graphicengine.Skin;
|
||||
import it.cavallium.warppi.gui.screens.Screen;
|
||||
|
||||
@ -14,6 +18,22 @@ public class TetrisScreen extends Screen {
|
||||
|
||||
private TetrisGame g;
|
||||
|
||||
private ButtonInfo leftPressed = new ButtonInfo();
|
||||
|
||||
private ButtonInfo rightPressed = new ButtonInfo();
|
||||
|
||||
private ButtonInfo upPressed = new ButtonInfo();
|
||||
|
||||
private ButtonInfo downPressed = new ButtonInfo();
|
||||
|
||||
private ButtonInfo okPressed = new ButtonInfo();
|
||||
|
||||
private ButtonInfo backPressed = new ButtonInfo();
|
||||
|
||||
private GraphicEngine e;
|
||||
|
||||
private Renderer r;
|
||||
|
||||
private static Skin skin;
|
||||
|
||||
public TetrisScreen() {
|
||||
@ -23,155 +43,143 @@ public class TetrisScreen extends Screen {
|
||||
|
||||
@Override
|
||||
public void initialized() {
|
||||
// try {
|
||||
// if (TetrisScreen.skin == null) {
|
||||
// TetrisScreen.skin = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadSkin("/marioskin.png");
|
||||
// }
|
||||
// if (TetrisScreen.groundskin == null) {
|
||||
// TetrisScreen.groundskin = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadSkin("/marioground.png");
|
||||
// }
|
||||
// if (TetrisScreen.gpuTest2 == null) {
|
||||
// try {
|
||||
// TetrisScreen.gpuTest2 = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadFont("N:\\gputest\\gputest2");
|
||||
// } catch (final Exception ex) {}
|
||||
// }
|
||||
// if (TetrisScreen.gpuTest1 == null) {
|
||||
// try {
|
||||
// TetrisScreen.gpuTest1 = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadFont("N:\\gputest\\gputest12");
|
||||
// TetrisScreen.gpuTest12 = true;
|
||||
// } catch (final Exception ex) {
|
||||
// TetrisScreen.gpuTest12 = false;
|
||||
// try {
|
||||
// TetrisScreen.gpuTest1 = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadFont("N:\\gputest\\gputest1");
|
||||
// } catch (final Exception ex2) {}
|
||||
// }
|
||||
// }
|
||||
// if (TetrisScreen.gpuTest3 == null) {
|
||||
// try {
|
||||
// TetrisScreen.gpuTest3 = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadSkin("N:\\gputest\\font_gputest3.png");
|
||||
// } catch (final Exception ex) {
|
||||
// ex.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
// } catch (final IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
StaticVars.windowZoom.onNext(2f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void graphicInitialized() {
|
||||
try {
|
||||
e = d.engine;
|
||||
r = d.renderer;
|
||||
if (TetrisScreen.skin == null) {
|
||||
TetrisScreen.skin = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.loadSkin("/tetrisskin.png");
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void created() throws InterruptedException {
|
||||
// if (!errored) {
|
||||
// g = new MarioGame();
|
||||
// }
|
||||
g = new TetrisGame();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeRender(final float dt) {
|
||||
// if (!errored) {
|
||||
// final boolean rightPressed = Keyboard.isKeyDown(2, 5);
|
||||
// final boolean leftPressed = Keyboard.isKeyDown(2, 3);
|
||||
// final boolean jumpPressed = Keyboard.isKeyDown(2, 1);
|
||||
// final boolean upPressed = false, downPressed = false, runPressed = false;
|
||||
// g.gameTick(dt, upPressed, downPressed, leftPressed, rightPressed, jumpPressed, runPressed);
|
||||
//
|
||||
// gpuTestElapsed += dt;
|
||||
// while (gpuTestElapsed >= 0.04) {
|
||||
// gpuTestNum = (gpuTestNum + 1) % gpuTestMax;
|
||||
// gpuTestElapsed -= 0.04;
|
||||
// }
|
||||
// gpuCharTestt1Elapsed += dt;
|
||||
// while (gpuCharTestt1Elapsed >= 1.5) {
|
||||
// gpuCharTest1Num = (gpuCharTest1Num + 1) % gpuCharTest1.length;
|
||||
// gpuCharTestt1Elapsed -= 1.5;
|
||||
// }
|
||||
//
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glClearColor(0xff000000);
|
||||
// }
|
||||
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glClearColor(0xff000000);
|
||||
g.update(dt, leftPressed, rightPressed, downPressed, upPressed, okPressed, backPressed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render() {
|
||||
// if (errored) {
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringLeft(0, 20, "ERROR");
|
||||
// } else {
|
||||
// if (TetrisScreen.groundskin != null) {
|
||||
// final double playerX = g.getPlayer().getX();
|
||||
// final double playerY = g.getPlayer().getY();
|
||||
// TetrisScreen.groundskin.use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine);
|
||||
// final MarioWorld w = g.getCurrentWorld();
|
||||
// final int width = w.getWidth();
|
||||
// final int height = w.getHeight();
|
||||
// final float screenX = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getWidth() / 2f - 8f;
|
||||
// final float screenY = Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getHeight() / 2f - 8f;
|
||||
// final float shiftX = -8 + 16 * (float) playerX;
|
||||
// final float shiftY = -8 + 16 * (height - (float) playerY);
|
||||
// int blue = -1;
|
||||
// for (int ix = 0; ix < width; ix++) {
|
||||
// for (int iy = 0; iy < height; iy++) {
|
||||
// final double distX = Math.abs(playerX - ix);
|
||||
// final double distY = Math.abs(playerY - iy - 1.5d);
|
||||
// if (distX * distX + distY * distY / 2d < 25d) {
|
||||
// final byte b = w.getBlockIdAt(ix, iy);
|
||||
// if (b == 0) {
|
||||
// if (blue != 1) {
|
||||
// blue = 1;
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor(0xff9290ff);
|
||||
// }
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glFillColor(screenX - shiftX + 16 * ix, screenY - shiftY + 16 * (height - iy), 16, 16);
|
||||
// } else {
|
||||
// if (blue != 0) {
|
||||
// blue = 0;
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor(0xffffffff);
|
||||
// }
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glFillRect(screenX - shiftX + 16 * ix, screenY - shiftY + 16 * (height - iy), 16, 16, 0, 0, 16, 16);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (blue != 0) {
|
||||
// blue = 0;
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor(0xffffffff);
|
||||
// }
|
||||
//
|
||||
// //DRAW MARIO
|
||||
// TetrisScreen.skin.use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine);
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glFillRect(screenX - (g.getPlayer().flipped ? 3 : 0), screenY, 35, 27, 35 * (g.getPlayer().marioSkinPos[0] + (g.getPlayer().flipped ? 2 : 1)), 27 * g.getPlayer().marioSkinPos[1], 35 * (g.getPlayer().flipped ? -1 : 1), 27);
|
||||
//// PIDisplay.renderer.glDrawSkin(getPosX() - 18, 25 + getPosY(), 35 * (marioSkinPos[0] + (flipped ? 2 : 1)), 27 * marioSkinPos[1], 35 * (marioSkinPos[0] + (flipped ? 1 : 2)), 27 * (marioSkinPos[1] + 1), true);
|
||||
// }
|
||||
//
|
||||
//// GPU PERFORMANCE TEST
|
||||
// if (TetrisScreen.gpuTest1 != null) {
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor3f(1, 1, 1);
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glFillColor(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getWidth() - (TetrisScreen.gpuTest12 ? 512 : 256), Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getHeight() / 2 - (TetrisScreen.gpuTest12 ? 256 : 128), TetrisScreen.gpuTest12 ? 512 : 256, TetrisScreen.gpuTest12 ? 512 : 256);
|
||||
// TetrisScreen.gpuTest1.use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine);
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor3f(0, 0, 0);
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringRight(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getWidth(), Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getHeight() / 2 - (TetrisScreen.gpuTest12 ? 256 : 128), gpuCharTest1[gpuCharTest1Num]);
|
||||
// }
|
||||
// if (TetrisScreen.gpuTest3 != null) {
|
||||
// TetrisScreen.gpuTest3.use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine);
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor4f(1, 1, 1, 0.7f);
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glFillRect(0, StaticVars.screenSize[1] - 128, 224, 128, gpuTestNum * 224, 0, 224, 128);
|
||||
// }
|
||||
// if (TetrisScreen.gpuTest2 != null) {
|
||||
// TetrisScreen.gpuTest2.use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine);
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor(0xFF000000);
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringRight(StaticVars.screenSize[0], Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getHeight() - TetrisScreen.gpuTest2.getCharacterHeight(), "A");
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor(0xFF800000);
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringRight(StaticVars.screenSize[0], Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getHeight() - TetrisScreen.gpuTest2.getCharacterHeight(), "B");
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor(0xFFeea28e);
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringRight(StaticVars.screenSize[0], Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getHeight() - TetrisScreen.gpuTest2.getCharacterHeight(), "C");
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor(0xFFee7255);
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringRight(StaticVars.screenSize[0], Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getHeight() - TetrisScreen.gpuTest2.getCharacterHeight(), "D");
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor(0xFFeac0b0);
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringRight(StaticVars.screenSize[0], Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getHeight() - TetrisScreen.gpuTest2.getCharacterHeight(), "E");
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor(0xFFf3d8ce);
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringRight(StaticVars.screenSize[0], Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getHeight() - TetrisScreen.gpuTest2.getCharacterHeight(), "F");
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor(0xFFffede7);
|
||||
// Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glDrawStringRight(StaticVars.screenSize[0], Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine.getHeight() - TetrisScreen.gpuTest2.getCharacterHeight(), "G");
|
||||
// }
|
||||
// }
|
||||
if (TetrisScreen.skin != null) {
|
||||
TetrisScreen.skin.use(e);
|
||||
}
|
||||
r.glColor3f(1, 1, 1);
|
||||
BlockColor[] renderedGrid = g.getRenderedGrid();
|
||||
int centerScreen = StaticVars.screenSize[0]/2;
|
||||
int centerGrid = TetrisGame.WIDTH*6/2-1;
|
||||
final int leftOffset = centerScreen - centerGrid;
|
||||
final int topOffset = StaticVars.screenSize[1] - TetrisGame.HEIGHT*6-1;
|
||||
for (int y = 0; y < TetrisGame.HEIGHT; y++) {
|
||||
for (int x = 0; x < TetrisGame.WIDTH; x++) {
|
||||
final int offset = x+y*TetrisGame.WIDTH;
|
||||
final BlockColor type = renderedGrid[offset];
|
||||
if (type != null) {
|
||||
r.glFillRect(leftOffset + x * 5, topOffset + (y+3) * 5, 5, 5, renderedGrid[offset].ordinal() * 5, 0, 5, 5);
|
||||
} else {
|
||||
r.glFillRect(leftOffset + x * 5, topOffset + (y+3) * 5, 5, 5, 7 * 5, 0, 5, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Tetromino nextTetromino = g.getNextTetromino();
|
||||
if (nextTetromino != null) {
|
||||
r.glColor3f(0.25f, 0.25f, 0.25f);
|
||||
r.glFillColor(leftOffset + (TetrisGame.WIDTH + 3) * 5, topOffset + 3 * 5, 5*4, 5*4);
|
||||
r.glColor3f(1,1,1);
|
||||
boolean[] renderedNextTetromino = nextTetromino.getRenderedBlock();
|
||||
final BlockColor type = nextTetromino.getColor();
|
||||
int nextTetrominoGridSize = nextTetromino.getTetrominoGridSize();
|
||||
int nextGridOffset = 4*5/2 - nextTetrominoGridSize*5/2;
|
||||
for (int y = 0; y < nextTetrominoGridSize; y++) {
|
||||
for (int x = 0; x < nextTetrominoGridSize; x++) {
|
||||
final int offset = x+y*nextTetrominoGridSize;
|
||||
if (renderedNextTetromino[offset]) {
|
||||
if (type != null) {
|
||||
r.glFillRect(leftOffset + nextGridOffset + (TetrisGame.WIDTH + 3 + x) * 5, topOffset + nextGridOffset + (3 + y) * 5, 5, 5, type.ordinal() * 5, 0, 5, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
r.glColor3f(1,1,1);
|
||||
r.glDrawStringLeft(leftOffset + (TetrisGame.WIDTH + 3) * 5, topOffset + (3+5) * 5, "SCORE:"+g.getScore());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyPressed(KeyPressedEvent k) {
|
||||
switch (k.getKey()) {
|
||||
case LEFT: {
|
||||
leftPressed.press();
|
||||
return true;
|
||||
}
|
||||
case RIGHT: {
|
||||
rightPressed.press();
|
||||
return true;
|
||||
}
|
||||
case UP: {
|
||||
upPressed.press();
|
||||
return true;
|
||||
}
|
||||
case DOWN: {
|
||||
downPressed.press();
|
||||
return true;
|
||||
}
|
||||
case OK: {
|
||||
okPressed.press();
|
||||
g.playAgain();
|
||||
return true;
|
||||
}
|
||||
case BACK: {
|
||||
backPressed.press();
|
||||
return true;
|
||||
}
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyReleased(KeyReleasedEvent k) {
|
||||
switch (k.getKey()) {
|
||||
case LEFT: {
|
||||
leftPressed.release();
|
||||
return true;
|
||||
}
|
||||
case RIGHT: {
|
||||
rightPressed.release();
|
||||
return true;
|
||||
}
|
||||
case UP: {
|
||||
upPressed.release();
|
||||
return true;
|
||||
}
|
||||
case DOWN: {
|
||||
downPressed.release();
|
||||
return true;
|
||||
}
|
||||
case OK: {
|
||||
okPressed.release();
|
||||
return true;
|
||||
}
|
||||
case BACK: {
|
||||
backPressed.release();
|
||||
return true;
|
||||
}
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean mustBeRefreshed() {
|
||||
return true;
|
||||
@ -179,7 +187,6 @@ public class TetrisScreen extends Screen {
|
||||
|
||||
@Override
|
||||
public String getSessionTitle() {
|
||||
return "Absolutely not Super Mario";
|
||||
return "Tetris";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,130 @@
|
||||
package it.cavallium.warppi.extra.tetris;
|
||||
|
||||
public abstract class Tetromino {
|
||||
private byte x, y, rotation;
|
||||
private final TetrominoType type;
|
||||
public final boolean o = false, w = true;
|
||||
|
||||
public Tetromino(byte x, byte y, byte rotation, TetrominoType type) {
|
||||
super();
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.rotation = rotation;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public byte getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(byte x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public byte getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(byte y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public byte getRotation() {
|
||||
return rotation;
|
||||
}
|
||||
|
||||
public void setRotation(byte rotation) {
|
||||
this.rotation = rotation;
|
||||
}
|
||||
|
||||
public TetrominoType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public BlockColor getColor() {
|
||||
switch(type) {
|
||||
case I_CYAN:
|
||||
return BlockColor.CYAN;
|
||||
case J_BLUE:
|
||||
return BlockColor.BLUE;
|
||||
case L_ORANGE:
|
||||
return BlockColor.ORANGE;
|
||||
case O_YELLOW:
|
||||
return BlockColor.YELLOW;
|
||||
case S_GREEN:
|
||||
return BlockColor.GREEN;
|
||||
case T_PURPLE:
|
||||
return BlockColor.PURPLE;
|
||||
case Z_RED:
|
||||
return BlockColor.RED;
|
||||
default:
|
||||
return BlockColor.RED;
|
||||
}
|
||||
}
|
||||
|
||||
public void draw(BlockColor[] grid, final int WIDTH) {
|
||||
boolean[] blockGrid = getRenderedBlock();
|
||||
final int tetrominoGridSize = getTetrominoGridSize();
|
||||
final int centerOffset = (int) Math.floor((double)tetrominoGridSize/2d);
|
||||
final BlockColor type = getColor();
|
||||
for (int bx = 0; bx < tetrominoGridSize; bx++) {
|
||||
for (int by = 0; by < tetrominoGridSize; by++) {
|
||||
if (blockGrid[bx+by*tetrominoGridSize] == w) {
|
||||
final int index = x+bx-centerOffset + (y+by-centerOffset) * WIDTH;
|
||||
if (index < grid.length && index >= 0) {
|
||||
grid[index] = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void fixInitialPosition() {
|
||||
this.y += (byte) (this.getTetrominoGridSize()/2);
|
||||
}
|
||||
|
||||
public abstract int getTetrominoGridSize();
|
||||
protected abstract boolean[] getRenderedBlock(byte dRotation);
|
||||
protected boolean[] getRenderedBlock() {
|
||||
return getRenderedBlock(this.rotation);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + rotation;
|
||||
result = prime * result + ((type == null) ? 0 : type.hashCode());
|
||||
result = prime * result + x;
|
||||
result = prime * result + y;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Tetromino other = (Tetromino) obj;
|
||||
if (rotation != other.rotation)
|
||||
return false;
|
||||
if (type != other.type)
|
||||
return false;
|
||||
if (x != other.x)
|
||||
return false;
|
||||
if (y != other.y)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Tetromino = {\n\t\"x\": \"" + x + "\",\n\ty\": \"" + y + "\",\n\trotation\": \"" + rotation + "\",\n\ttype\": \"" + type + "\"\n}";
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package it.cavallium.warppi.extra.tetris;
|
||||
|
||||
public class TetrominoICyan extends Tetromino {
|
||||
public TetrominoICyan(byte x, byte y, byte rotation) {
|
||||
super(x, y, rotation, TetrominoType.I_CYAN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTetrominoGridSize() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean[] getRenderedBlock(final byte rotation) {
|
||||
switch(rotation) {
|
||||
case 0:
|
||||
return new boolean[] {
|
||||
o,o,o,o,
|
||||
w,w,w,w,
|
||||
o,o,o,o,
|
||||
o,o,o,o
|
||||
};
|
||||
case 1:
|
||||
return new boolean[] {
|
||||
o,o,w,o,
|
||||
o,o,w,o,
|
||||
o,o,w,o,
|
||||
o,o,w,o
|
||||
};
|
||||
case 2:
|
||||
return new boolean[] {
|
||||
o,o,o,o,
|
||||
o,o,o,o,
|
||||
w,w,w,w,
|
||||
o,o,o,o
|
||||
};
|
||||
case 3:
|
||||
return new boolean[] {
|
||||
o,w,o,o,
|
||||
o,w,o,o,
|
||||
o,w,o,o,
|
||||
o,w,o,o
|
||||
};
|
||||
default:
|
||||
throw new NullPointerException();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package it.cavallium.warppi.extra.tetris;
|
||||
|
||||
public class TetrominoJBlue extends Tetromino {
|
||||
public TetrominoJBlue(byte x, byte y, byte rotation) {
|
||||
super(x, y, rotation, TetrominoType.J_BLUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTetrominoGridSize() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean[] getRenderedBlock(final byte rotation) {
|
||||
switch(rotation) {
|
||||
case 0:
|
||||
return new boolean[] {
|
||||
w,o,o,
|
||||
w,w,w,
|
||||
o,o,o
|
||||
};
|
||||
case 1:
|
||||
return new boolean[] {
|
||||
o,w,w,
|
||||
o,w,o,
|
||||
o,w,o
|
||||
};
|
||||
case 2:
|
||||
return new boolean[] {
|
||||
o,o,o,
|
||||
w,w,w,
|
||||
o,o,w
|
||||
};
|
||||
case 3:
|
||||
return new boolean[] {
|
||||
o,w,o,
|
||||
o,w,o,
|
||||
w,w,o
|
||||
};
|
||||
default:
|
||||
throw new NullPointerException();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package it.cavallium.warppi.extra.tetris;
|
||||
|
||||
public class TetrominoLOrange extends Tetromino {
|
||||
public TetrominoLOrange(byte x, byte y, byte rotation) {
|
||||
super(x, y, rotation, TetrominoType.L_ORANGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTetrominoGridSize() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean[] getRenderedBlock(final byte rotation) {
|
||||
switch(rotation) {
|
||||
case 0:
|
||||
return new boolean[] {
|
||||
o,o,w,
|
||||
w,w,w,
|
||||
o,o,o
|
||||
};
|
||||
case 1:
|
||||
return new boolean[] {
|
||||
o,w,o,
|
||||
o,w,o,
|
||||
o,w,w
|
||||
};
|
||||
case 2:
|
||||
return new boolean[] {
|
||||
o,o,o,
|
||||
w,w,w,
|
||||
w,o,o
|
||||
};
|
||||
case 3:
|
||||
return new boolean[] {
|
||||
w,w,o,
|
||||
o,w,o,
|
||||
o,w,o
|
||||
};
|
||||
default:
|
||||
throw new NullPointerException();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package it.cavallium.warppi.extra.tetris;
|
||||
|
||||
public class TetrominoOYellow extends Tetromino {
|
||||
public TetrominoOYellow(byte x, byte y, byte rotation) {
|
||||
super(x, y, rotation, TetrominoType.O_YELLOW);
|
||||
}
|
||||
@Override
|
||||
public int getTetrominoGridSize() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean[] getRenderedBlock(byte rotation) {
|
||||
return new boolean[] {
|
||||
w,w,
|
||||
w,w,
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package it.cavallium.warppi.extra.tetris;
|
||||
|
||||
public class TetrominoSGreen extends Tetromino {
|
||||
public TetrominoSGreen(byte x, byte y, byte rotation) {
|
||||
super(x, y, rotation, TetrominoType.S_GREEN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTetrominoGridSize() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean[] getRenderedBlock(final byte rotation) {
|
||||
switch(rotation) {
|
||||
case 0:
|
||||
return new boolean[] {
|
||||
o,w,w,
|
||||
w,w,o,
|
||||
o,o,o
|
||||
};
|
||||
case 1:
|
||||
return new boolean[] {
|
||||
o,w,o,
|
||||
o,w,w,
|
||||
o,o,w
|
||||
};
|
||||
case 2:
|
||||
return new boolean[] {
|
||||
o,o,o,
|
||||
o,w,w,
|
||||
w,w,o
|
||||
};
|
||||
case 3:
|
||||
return new boolean[] {
|
||||
w,o,o,
|
||||
w,w,o,
|
||||
o,w,o
|
||||
};
|
||||
default:
|
||||
throw new NullPointerException();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package it.cavallium.warppi.extra.tetris;
|
||||
|
||||
public class TetrominoTPurple extends Tetromino {
|
||||
public TetrominoTPurple(byte x, byte y, byte rotation) {
|
||||
super(x, y, rotation, TetrominoType.T_PURPLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTetrominoGridSize() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean[] getRenderedBlock(byte rotation) {
|
||||
switch(rotation) {
|
||||
case 0:
|
||||
return new boolean[] {
|
||||
o,w,o,
|
||||
w,w,w,
|
||||
o,o,o
|
||||
};
|
||||
case 1:
|
||||
return new boolean[] {
|
||||
o,w,o,
|
||||
o,w,w,
|
||||
o,w,o
|
||||
};
|
||||
case 2:
|
||||
return new boolean[] {
|
||||
o,o,o,
|
||||
w,w,w,
|
||||
o,w,o
|
||||
};
|
||||
case 3:
|
||||
return new boolean[] {
|
||||
o,w,o,
|
||||
w,w,o,
|
||||
o,w,o
|
||||
};
|
||||
default:
|
||||
throw new NullPointerException();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package it.cavallium.warppi.extra.tetris;
|
||||
|
||||
public enum TetrominoType {
|
||||
I_CYAN,
|
||||
O_YELLOW,
|
||||
T_PURPLE,
|
||||
S_GREEN,
|
||||
Z_RED,
|
||||
J_BLUE,
|
||||
L_ORANGE
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package it.cavallium.warppi.extra.tetris;
|
||||
|
||||
public class TetrominoZRed extends Tetromino {
|
||||
public TetrominoZRed(byte x, byte y, byte rotation) {
|
||||
super(x, y, rotation, TetrominoType.Z_RED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTetrominoGridSize() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean[] getRenderedBlock(final byte rotation) {
|
||||
switch(rotation) {
|
||||
case 0:
|
||||
return new boolean[] {
|
||||
w,w,o,
|
||||
o,w,w,
|
||||
o,o,o
|
||||
};
|
||||
case 1:
|
||||
return new boolean[] {
|
||||
o,o,w,
|
||||
o,w,w,
|
||||
o,w,o
|
||||
};
|
||||
case 2:
|
||||
return new boolean[] {
|
||||
o,o,o,
|
||||
w,w,o,
|
||||
o,w,w
|
||||
};
|
||||
case 3:
|
||||
return new boolean[] {
|
||||
o,w,o,
|
||||
w,w,o,
|
||||
w,o,o
|
||||
};
|
||||
default:
|
||||
throw new NullPointerException();
|
||||
}
|
||||
}
|
||||
}
|
@ -24,6 +24,12 @@ public class CalculatorHUD extends HUD {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void graphicInitialized() throws InterruptedException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render() {
|
||||
// TODO Auto-generated method stub
|
||||
|
@ -5,14 +5,13 @@ import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import it.cavallium.warppi.Engine;
|
||||
import it.cavallium.warppi.Platform.ConsoleUtils;
|
||||
import it.cavallium.warppi.Platform.Semaphore;
|
||||
import it.cavallium.warppi.StaticVars;
|
||||
import it.cavallium.warppi.device.Keyboard;
|
||||
import it.cavallium.warppi.flow.Observable;
|
||||
import it.cavallium.warppi.flow.Pair;
|
||||
import it.cavallium.warppi.gui.graphicengine.BinaryFont;
|
||||
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
|
||||
import it.cavallium.warppi.gui.graphicengine.Renderer;
|
||||
@ -243,10 +242,10 @@ public final class DisplayManager implements RenderingLoop {
|
||||
screen.create();
|
||||
}
|
||||
this.screen = screen;
|
||||
screenChange.release();
|
||||
if (screen.initialized == false) {
|
||||
screen.initialize();
|
||||
}
|
||||
screenChange.release();
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
Engine.getPlatform().exit(0);
|
||||
@ -268,10 +267,10 @@ public final class DisplayManager implements RenderingLoop {
|
||||
try {
|
||||
screen.create();
|
||||
this.screen = screen;
|
||||
screenChange.release();
|
||||
if (screen.initialized == false) {
|
||||
screen.initialize();
|
||||
}
|
||||
screenChange.release();
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
Engine.getPlatform().exit(0);
|
||||
@ -373,6 +372,13 @@ public final class DisplayManager implements RenderingLoop {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!screen.graphicInitialized) {
|
||||
try {
|
||||
screen.initializeGraphic();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
renderer.glClear(engine.getWidth(), engine.getHeight());
|
||||
}
|
||||
|
||||
@ -440,7 +446,6 @@ public final class DisplayManager implements RenderingLoop {
|
||||
setScreen(initialScreen);
|
||||
initialScreen = null;
|
||||
}
|
||||
screen.initialize();
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
Engine.getPlatform().exit(0);
|
||||
|
@ -5,6 +5,8 @@ public interface GraphicalInterface {
|
||||
|
||||
void initialize() throws InterruptedException;
|
||||
|
||||
void initializeGraphic() throws InterruptedException;
|
||||
|
||||
void render();
|
||||
|
||||
void renderTopmost();
|
||||
|
@ -3,6 +3,7 @@ package it.cavallium.warppi.gui;
|
||||
public abstract class HUD implements GraphicalInterface {
|
||||
public DisplayManager d;
|
||||
public boolean created = false;
|
||||
public boolean graphicInitialized = false;
|
||||
public boolean initialized = false;
|
||||
public boolean visible = true;
|
||||
|
||||
@ -16,6 +17,14 @@ public abstract class HUD implements GraphicalInterface {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeGraphic() throws InterruptedException {
|
||||
if (!graphicInitialized) {
|
||||
graphicInitialized = true;
|
||||
graphicInitialized();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create() throws InterruptedException {
|
||||
if (!created) {
|
||||
@ -26,6 +35,8 @@ public abstract class HUD implements GraphicalInterface {
|
||||
|
||||
public abstract void created() throws InterruptedException;
|
||||
|
||||
public abstract void graphicInitialized() throws InterruptedException;
|
||||
|
||||
public abstract void initialized() throws InterruptedException;
|
||||
|
||||
public abstract void renderBackground();
|
||||
|
@ -5,6 +5,7 @@ import java.util.Arrays;
|
||||
import it.cavallium.warppi.event.KeyboardEventListener;
|
||||
import it.cavallium.warppi.gui.expression.blocks.Block;
|
||||
import it.cavallium.warppi.gui.expression.blocks.BlockVariable;
|
||||
import it.cavallium.warppi.gui.expression.blocks.TreeContainer;
|
||||
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
|
||||
import it.cavallium.warppi.gui.graphicengine.Renderer;
|
||||
|
||||
@ -45,7 +46,7 @@ public abstract class ExtraMenu<T extends Block> implements KeyboardEventListene
|
||||
return false;
|
||||
}
|
||||
|
||||
public abstract ExtraMenu<T> clone(InputContext ic);
|
||||
public abstract ExtraMenu<T> clone(final TreeContainer parent, InputContext ic);
|
||||
|
||||
public abstract ExtraMenu<T> clone(T newBlockVariable);
|
||||
|
||||
|
@ -19,6 +19,22 @@ public abstract class Block implements TreeBlock, GraphicalElement {
|
||||
protected int line;
|
||||
protected TreeContainer parent;
|
||||
|
||||
public Block() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy
|
||||
* @param b
|
||||
*/
|
||||
public Block(TreeContainer parent, Block b) {
|
||||
this.small = b.small;
|
||||
this.width = b.width;
|
||||
this.height = b.height;
|
||||
this.line = b.line;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param r
|
||||
@ -95,5 +111,5 @@ public abstract class Block implements TreeBlock, GraphicalElement {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public abstract Block clone(InputContext ic);
|
||||
public abstract Block clone(TreeContainer parent, InputContext ic);
|
||||
}
|
||||
|
@ -18,9 +18,14 @@ public class BlockChar extends Block {
|
||||
recomputeDimensions();
|
||||
}
|
||||
|
||||
public BlockChar(final char ch, InputContext ic) {
|
||||
this.ch = ch;
|
||||
recomputeDimensions();
|
||||
/**
|
||||
* Copy
|
||||
* @param b
|
||||
* @param ic
|
||||
*/
|
||||
protected BlockChar(final TreeContainer parent, final BlockChar b, InputContext ic) {
|
||||
super(parent, b);
|
||||
this.ch = b.ch;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -83,8 +88,8 @@ public class BlockChar extends Block {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockChar clone(InputContext ic) {
|
||||
return new BlockChar(ch, ic);
|
||||
public BlockChar clone(final TreeContainer parent, InputContext ic) {
|
||||
return new BlockChar(parent, this, ic);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -79,24 +79,25 @@ public class BlockContainer implements TreeContainer, GraphicalElement {
|
||||
recomputeDimensions();
|
||||
}
|
||||
|
||||
private BlockContainer(BlockContainer old, InputContext ic) {
|
||||
private BlockContainer(final TreeBlock parent, BlockContainer old, InputContext ic) {
|
||||
this.autoMinimums = old.autoMinimums;
|
||||
this.content = new ObjectArrayList<>();
|
||||
for (Block b : old.content) {
|
||||
this.content.add(b.clone(ic));
|
||||
this.content.add(b.clone(this, ic));
|
||||
}
|
||||
|
||||
this.height = old.height;
|
||||
this.line = old.line;
|
||||
this.minHeight = old.minHeight;
|
||||
this.minWidth = old.minWidth;
|
||||
this.parent = old.parent;
|
||||
this.parent = parent;
|
||||
this.small = old.small;
|
||||
this.width = old.width;
|
||||
this.withBorder = old.withBorder;
|
||||
}
|
||||
|
||||
public BlockContainer clone(InputContext ic) {
|
||||
return new BlockContainer(this, ic);
|
||||
public BlockContainer clone(final TreeBlock parent, InputContext ic) {
|
||||
return new BlockContainer(parent, this, ic);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -261,6 +262,8 @@ public class BlockContainer implements TreeContainer, GraphicalElement {
|
||||
innerContainersBeforeCaret++;
|
||||
}
|
||||
}
|
||||
// If the caret is at the end of a block with inner containers don't delete anything and enter into that block.
|
||||
if (innerContainers == null || (innerContainers.size() - innerContainersBeforeCaret != 0)) {
|
||||
removeAt(pos - 1);
|
||||
if (blocks != null) {
|
||||
ObjectListIterator<Block> blocksIterator = blocks.iterator();
|
||||
@ -275,6 +278,7 @@ public class BlockContainer implements TreeContainer, GraphicalElement {
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
caret.skip(1);
|
||||
if (removed) {
|
||||
recomputeDimensions();
|
||||
|
@ -27,10 +27,14 @@ public class BlockDivision extends Block {
|
||||
recomputeDimensions();
|
||||
}
|
||||
|
||||
private BlockDivision(BlockDivision old, InputContext ic) {
|
||||
containerUp = old.containerUp.clone(ic);
|
||||
containerDown = old.containerDown.clone(ic);
|
||||
recomputeDimensions();
|
||||
private BlockDivision(final TreeContainer parent, BlockDivision old, InputContext ic) {
|
||||
super(parent, old);
|
||||
containerUp = old.containerUp.clone(this, ic);
|
||||
containerDown = old.containerDown.clone(this, ic);
|
||||
paddingLeftLower = old.paddingLeftLower;
|
||||
paddingLeftUpper = old.paddingLeftUpper;
|
||||
h1 = old.h1;
|
||||
System.out.println(String.join(",", ""+h1, ""+old.h1, ""+line, ""+old.line));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -144,7 +148,7 @@ public class BlockDivision extends Block {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockDivision clone(InputContext ic) {
|
||||
return new BlockDivision(this, ic);
|
||||
public BlockDivision clone(final TreeContainer parent, InputContext ic) {
|
||||
return new BlockDivision(parent, this, ic);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package it.cavallium.warppi.gui.expression.blocks;
|
||||
|
||||
import it.cavallium.warppi.gui.expression.Caret;
|
||||
import it.cavallium.warppi.gui.expression.InputContext;
|
||||
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
|
||||
import it.cavallium.warppi.gui.graphicengine.Renderer;
|
||||
|
||||
@ -8,6 +9,21 @@ public class BlockExponentialNotation extends BlockPower {
|
||||
private int bw;
|
||||
private int bh;
|
||||
|
||||
public BlockExponentialNotation() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy
|
||||
* @param old
|
||||
* @param ic
|
||||
*/
|
||||
private BlockExponentialNotation(final TreeContainer parent, BlockExponentialNotation old, InputContext ic) {
|
||||
super(parent, old, ic);
|
||||
this.bw = old.bw;
|
||||
this.bh = old.bh;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(final GraphicEngine ge, final Renderer r, final int x, final int y, final Caret caret) {
|
||||
BlockContainer.getDefaultFont(small).use(ge);
|
||||
@ -23,4 +39,9 @@ public class BlockExponentialNotation extends BlockPower {
|
||||
bh = BlockContainer.getDefaultCharHeight(small);
|
||||
width += bw;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockExponentialNotation clone(final TreeContainer parent, InputContext ic) {
|
||||
return new BlockExponentialNotation(parent, this, ic);
|
||||
}
|
||||
}
|
||||
|
@ -40,10 +40,19 @@ public class BlockLogarithm extends Block implements IParenthesis {
|
||||
recomputeDimensions();
|
||||
}
|
||||
|
||||
private BlockLogarithm(BlockLogarithm old, InputContext ic) {
|
||||
containerBase = old.containerBase.clone(ic);
|
||||
containerNumber = old.containerNumber.clone(ic);
|
||||
recomputeDimensions();
|
||||
private BlockLogarithm(final TreeContainer parent, BlockLogarithm old, InputContext ic) {
|
||||
super(parent, old);
|
||||
containerBase = old.containerBase.clone(this, ic);
|
||||
containerNumber = old.containerNumber.clone(this, ic);
|
||||
this.prw = old.prw;
|
||||
this.bw = old.bw;
|
||||
this.bh = old.bh;
|
||||
this.bl = old.bl;
|
||||
this.chw = old.chw;
|
||||
this.chh = old.chh;
|
||||
this.schh = old.schh;
|
||||
this.nmbh = old.nmbh;
|
||||
this.toph = old.toph;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -183,8 +192,8 @@ public class BlockLogarithm extends Block implements IParenthesis {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockLogarithm clone(InputContext ic) {
|
||||
return new BlockLogarithm(this, ic);
|
||||
public BlockLogarithm clone(final TreeContainer parent, InputContext ic) {
|
||||
return new BlockLogarithm(parent, this, ic);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,9 +1,19 @@
|
||||
package it.cavallium.warppi.gui.expression.blocks;
|
||||
|
||||
import it.cavallium.warppi.gui.expression.InputContext;
|
||||
|
||||
public class BlockNumericChar extends BlockChar {
|
||||
|
||||
public BlockNumericChar(final char ch) {
|
||||
super(ch);
|
||||
}
|
||||
|
||||
private BlockNumericChar(final TreeContainer parent, BlockNumericChar old, InputContext ic) {
|
||||
super(parent, old, ic);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockNumericChar clone(final TreeContainer parent, InputContext ic) {
|
||||
return new BlockNumericChar(parent, this, ic);
|
||||
}
|
||||
}
|
||||
|
@ -15,8 +15,8 @@ public class BlockParenthesis extends BlockParenthesisAbstract {
|
||||
super(blocks);
|
||||
}
|
||||
|
||||
private BlockParenthesis(BlockParenthesis old, InputContext ic) {
|
||||
super(old, ic);
|
||||
private BlockParenthesis(final TreeContainer parent, BlockParenthesis old, InputContext ic) {
|
||||
super(parent, old, ic);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -38,8 +38,8 @@ public class BlockParenthesis extends BlockParenthesisAbstract {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockParenthesis clone(InputContext ic) {
|
||||
return new BlockParenthesis(this, ic);
|
||||
public BlockParenthesis clone(final TreeContainer parent, InputContext ic) {
|
||||
return new BlockParenthesis(parent, this, ic);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -31,10 +31,18 @@ public abstract class BlockParenthesisAbstract extends Block implements IParenth
|
||||
recomputeDimensions();
|
||||
}
|
||||
|
||||
BlockParenthesisAbstract(BlockParenthesisAbstract old, InputContext ic) {
|
||||
containerNumber = old.containerNumber.clone(ic);
|
||||
prefix = old.prefix == null ? null : new String(old.prefix);
|
||||
recomputeDimensions();
|
||||
/**
|
||||
* Copy
|
||||
* @param old
|
||||
* @param ic
|
||||
*/
|
||||
BlockParenthesisAbstract(final TreeContainer parent, BlockParenthesisAbstract old, InputContext ic) {
|
||||
super(parent, old);
|
||||
containerNumber = old.containerNumber.clone(this, ic);
|
||||
prefix = old.prefix;
|
||||
prw = old.prw;
|
||||
chw = old.chw;
|
||||
chh = old.chh;
|
||||
}
|
||||
|
||||
public BlockParenthesisAbstract(final ObjectArrayList<Block> blocks) {
|
||||
|
@ -20,8 +20,9 @@ public class BlockPower extends Block {
|
||||
recomputeDimensions();
|
||||
}
|
||||
|
||||
private BlockPower(BlockPower old, InputContext ic) {
|
||||
this.containerExponent = old.containerExponent.clone(ic);
|
||||
protected BlockPower(final TreeContainer parent, BlockPower old, InputContext ic) {
|
||||
super(parent, old);
|
||||
this.containerExponent = old.containerExponent.clone(this, ic);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -100,7 +101,7 @@ public class BlockPower extends Block {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPower clone(InputContext ic) {
|
||||
return new BlockPower(this, ic);
|
||||
public BlockPower clone(final TreeContainer parent, InputContext ic) {
|
||||
return new BlockPower(parent, this, ic);
|
||||
}
|
||||
}
|
||||
|
@ -21,8 +21,9 @@ public class BlockPower2 extends Block {
|
||||
recomputeDimensions();
|
||||
}
|
||||
|
||||
private BlockPower2(BlockPower2 old, InputContext ic) {
|
||||
this.containerExponent = old.containerExponent.clone(ic);
|
||||
private BlockPower2(final TreeContainer parent, BlockPower2 old, InputContext ic) {
|
||||
super(parent, old);
|
||||
this.containerExponent = old.containerExponent.clone(this, ic);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -106,7 +107,7 @@ public class BlockPower2 extends Block {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPower2 clone(InputContext ic) {
|
||||
return new BlockPower2(this, ic);
|
||||
public BlockPower2 clone(final TreeContainer parent, InputContext ic) {
|
||||
return new BlockPower2(parent, this, ic);
|
||||
}
|
||||
}
|
||||
|
@ -13,8 +13,8 @@ public class BlockSine extends BlockParenthesisAbstract {
|
||||
super("SIN");
|
||||
}
|
||||
|
||||
private BlockSine(BlockSine old, InputContext ic) {
|
||||
super(old, ic);
|
||||
private BlockSine(final TreeContainer parent, BlockSine old, InputContext ic) {
|
||||
super(parent, old, ic);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -24,7 +24,7 @@ public class BlockSine extends BlockParenthesisAbstract {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block clone(InputContext ic) {
|
||||
return new BlockSine(this, ic);
|
||||
public BlockSine clone(final TreeContainer parent, InputContext ic) {
|
||||
return new BlockSine(parent, this, ic);
|
||||
}
|
||||
}
|
||||
|
@ -22,9 +22,10 @@ public class BlockSquareRoot extends Block {
|
||||
recomputeDimensions();
|
||||
}
|
||||
|
||||
private BlockSquareRoot(BlockSquareRoot old, InputContext ic) {
|
||||
this.containerNumber = old.containerNumber.clone(ic);
|
||||
recomputeDimensions();
|
||||
private BlockSquareRoot(final TreeContainer parent, BlockSquareRoot old, InputContext ic) {
|
||||
super(parent, old);
|
||||
this.containerNumber = old.containerNumber.clone(this, ic);
|
||||
this.h1 = old.h1;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -118,7 +119,7 @@ public class BlockSquareRoot extends Block {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockSquareRoot clone(InputContext ic) {
|
||||
return new BlockSquareRoot(this, ic);
|
||||
public BlockSquareRoot clone(final TreeContainer parent, InputContext ic) {
|
||||
return new BlockSquareRoot(parent, this, ic);
|
||||
}
|
||||
}
|
||||
|
@ -16,8 +16,8 @@ public class BlockUndefined extends Block {
|
||||
recomputeDimensions();
|
||||
}
|
||||
|
||||
private BlockUndefined(BlockUndefined old, InputContext ic) {
|
||||
recomputeDimensions();
|
||||
private BlockUndefined(final TreeContainer parent, BlockUndefined old, InputContext ic) {
|
||||
super(parent, old);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -76,8 +76,8 @@ public class BlockUndefined extends Block {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockUndefined clone(InputContext ic) {
|
||||
return new BlockUndefined(this, ic);
|
||||
public BlockUndefined clone(final TreeContainer parent, InputContext ic) {
|
||||
return new BlockUndefined(parent, this, ic);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -45,7 +45,8 @@ public class BlockVariable extends Block {
|
||||
recomputeDimensions();
|
||||
}
|
||||
|
||||
private BlockVariable(BlockVariable old, InputContext ic) {
|
||||
private BlockVariable(final TreeContainer parent, BlockVariable old, InputContext ic) {
|
||||
super(parent, old);
|
||||
this.ic = ic;
|
||||
this.ch = old.ch;
|
||||
type = old.type;
|
||||
@ -53,8 +54,7 @@ public class BlockVariable extends Block {
|
||||
typeDirtyID = old.typeDirtyID;
|
||||
this.typeLocked = old.typeLocked;
|
||||
menu = old.menu == null ? null : new VariableMenu(old.menu, this);
|
||||
retrieveValue();
|
||||
recomputeDimensions();
|
||||
mustRefresh = old.mustRefresh;
|
||||
}
|
||||
|
||||
private void retrieveValue() {
|
||||
@ -273,8 +273,8 @@ public class BlockVariable extends Block {
|
||||
}
|
||||
|
||||
@Override
|
||||
public VariableMenu clone(InputContext ic) {
|
||||
return new VariableMenu(this, block.clone(ic));
|
||||
public VariableMenu clone(final TreeContainer parent, InputContext ic) {
|
||||
return new VariableMenu(this, block.clone(parent, ic));
|
||||
}
|
||||
|
||||
}
|
||||
@ -295,7 +295,7 @@ public class BlockVariable extends Block {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockVariable clone(InputContext ic) {
|
||||
return new BlockVariable(this, ic);
|
||||
public BlockVariable clone(final TreeContainer parent, InputContext ic) {
|
||||
return new BlockVariable(parent, this, ic);
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ import it.cavallium.warppi.util.Error;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
|
||||
public abstract class InputContainer implements GraphicalElement, InputLayout {
|
||||
private static final long serialVersionUID = 923589369317765667L;
|
||||
protected BlockContainer root;
|
||||
protected Caret caret;
|
||||
private static final float CARET_DURATION = 0.5f;
|
||||
@ -61,11 +60,11 @@ public abstract class InputContainer implements GraphicalElement, InputLayout {
|
||||
*/
|
||||
protected InputContainer(InputContainer old, InputContext ic) {
|
||||
this.caretTime = old.caretTime;
|
||||
this.extra = old.extra == null ? null : old.extra.clone(ic);
|
||||
this.extra = old.extra == null ? null : old.extra.clone(null, ic);
|
||||
this.maxPosition = old.maxPosition;
|
||||
this.caret = old.caret == null ? null : new Caret(old.caret);
|
||||
this.inputContext = ic;
|
||||
this.root = old.root == null ? null : old.root.clone(ic);
|
||||
this.root = old.root == null ? null : old.root.clone(null, ic);
|
||||
this.parsed = old.parsed;
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,6 @@ public class NormalInputContainer extends InputContainer {
|
||||
* @param userInput
|
||||
* @param ic
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public NormalInputContainer(InputContainer old, InputContext ic) {
|
||||
super(old, ic);
|
||||
}
|
||||
|
@ -13,7 +13,15 @@ public interface Skin {
|
||||
|
||||
void use(GraphicEngine d);
|
||||
|
||||
/**
|
||||
* May not be available before initialization
|
||||
* @return skin width
|
||||
*/
|
||||
int getSkinWidth();
|
||||
|
||||
/**
|
||||
* May not be available before initialization
|
||||
* @return skin height
|
||||
*/
|
||||
int getSkinHeight();
|
||||
}
|
||||
|
@ -1,14 +1,10 @@
|
||||
package it.cavallium.warppi.gui.graphicengine.impl.common;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import it.cavallium.warppi.Engine;
|
||||
import it.cavallium.warppi.Platform.PngUtils.PngReader;
|
||||
import it.cavallium.warppi.Platform.ImageUtils.ImageReader;
|
||||
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
|
||||
import it.cavallium.warppi.gui.graphicengine.Skin;
|
||||
|
||||
@ -29,14 +25,7 @@ public abstract class PngSkin implements Skin {
|
||||
if (!file.startsWith("/")) {
|
||||
file = "/" + file;
|
||||
}
|
||||
if (!file.endsWith(".png")) {
|
||||
final File f = File.createTempFile("picalculator-png", ".png");
|
||||
f.deleteOnExit();
|
||||
final BufferedImage img = ImageIO.read(Engine.getPlatform().getStorageUtils().getResourceStream(file));
|
||||
ImageIO.write(img, "PNG", f);
|
||||
file = f.toString();
|
||||
}
|
||||
final PngReader r = Engine.getPlatform().getPngUtils().load(Engine.getPlatform().getStorageUtils().getResourceStream(file));
|
||||
final ImageReader r = Engine.getPlatform().getImageUtils().load(Engine.getPlatform().getStorageUtils().getResourceStream(file));
|
||||
if (r == null) {
|
||||
skinData = new int[0];
|
||||
skinSize = new int[] { 0, 0 };
|
||||
|
@ -1,7 +1,5 @@
|
||||
package it.cavallium.warppi.gui.graphicengine.impl.common;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -10,8 +8,6 @@ import java.util.LinkedList;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import it.cavallium.warppi.Engine;
|
||||
import it.cavallium.warppi.Platform.ConsoleUtils;
|
||||
import it.cavallium.warppi.gui.graphicengine.BinaryFont;
|
||||
@ -223,18 +219,6 @@ public abstract class RFTFont implements BinaryFont {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private void saveArray(final int[] screen, final int w, final int h, final String coutputpng) {
|
||||
final BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
|
||||
final int[] a = ((DataBufferInt) bi.getRaster().getDataBuffer()).getData();
|
||||
System.arraycopy(screen, 0, a, 0, screen.length);
|
||||
try {
|
||||
ImageIO.write(bi, "PNG", new File(coutputpng));
|
||||
} catch (final IOException ex) {
|
||||
Logger.getLogger(BinaryFont.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public int[] getCharIndexes(final String txt) {
|
||||
final int l = txt.length();
|
||||
final int[] indexes = new int[l];
|
||||
|
@ -27,6 +27,9 @@ public class ChooseVariableValueScreen extends Screen {
|
||||
@Override
|
||||
public void initialized() throws InterruptedException {}
|
||||
|
||||
@Override
|
||||
public void graphicInitialized() throws InterruptedException {}
|
||||
|
||||
@Override
|
||||
public void render() {
|
||||
Utils.getFont(false, true).use(Engine.INSTANCE.getHardwareDevice().getDisplayManager().engine);
|
||||
|
@ -19,6 +19,9 @@ public class EmptyScreen extends Screen {
|
||||
@Override
|
||||
public void initialized() throws InterruptedException {}
|
||||
|
||||
@Override
|
||||
public void graphicInitialized() throws InterruptedException {}
|
||||
|
||||
@Override
|
||||
public void render() {
|
||||
// TODO Auto-generated method stub
|
||||
|
@ -27,6 +27,9 @@ public class KeyboardDebugScreen extends Screen {
|
||||
@Override
|
||||
public void initialized() throws InterruptedException {}
|
||||
|
||||
@Override
|
||||
public void graphicInitialized() throws InterruptedException {}
|
||||
|
||||
@Override
|
||||
public void render() {
|
||||
final Renderer renderer = Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer;
|
||||
|
@ -34,6 +34,9 @@ public class LoadingScreen extends Screen {
|
||||
StaticVars.windowZoom.onNext(1f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void graphicInitialized() throws InterruptedException {}
|
||||
|
||||
@Override
|
||||
public void beforeRender(final float dt) {
|
||||
loadingTextTranslation = GraphicUtils.sinDeg(endLoading * 90f) * 10f;
|
||||
|
@ -105,6 +105,11 @@ public class MathInputScreen extends Screen {
|
||||
/* Fine caricamento */
|
||||
}
|
||||
|
||||
@Override
|
||||
public void graphicInitialized() throws InterruptedException {
|
||||
/* Fine caricamento */
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeRender(final float dt) {
|
||||
if (Engine.INSTANCE.getHardwareDevice().getDisplayManager().error == null) {
|
||||
|
@ -10,6 +10,7 @@ public abstract class Screen implements KeyboardEventListener, TouchEventListene
|
||||
public DisplayManager d;
|
||||
public boolean created = false;
|
||||
public boolean initialized = false;
|
||||
public boolean graphicInitialized = false;
|
||||
public HistoryBehavior historyBehavior = HistoryBehavior.NORMAL;
|
||||
|
||||
public static long lastDebugScreenID = 1;
|
||||
@ -19,6 +20,14 @@ public abstract class Screen implements KeyboardEventListener, TouchEventListene
|
||||
debugScreenID = lastDebugScreenID++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeGraphic() throws InterruptedException {
|
||||
if (!graphicInitialized) {
|
||||
graphicInitialized = true;
|
||||
graphicInitialized();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() throws InterruptedException {
|
||||
if (!initialized) {
|
||||
@ -35,10 +44,30 @@ public abstract class Screen implements KeyboardEventListener, TouchEventListene
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when creating the screen
|
||||
* Called before initialized()
|
||||
* Called before graphicInitialized()
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public abstract void created() throws InterruptedException;
|
||||
|
||||
/**
|
||||
* Load everything except skins, etc...
|
||||
* Called after created()
|
||||
* Called after graphicInitialized()
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public abstract void initialized() throws InterruptedException;
|
||||
|
||||
/**
|
||||
* Load skins, etc...
|
||||
* Called after created()
|
||||
* Called before initialized()
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public abstract void graphicInitialized() throws InterruptedException;
|
||||
|
||||
@Override
|
||||
public abstract void render();
|
||||
|
||||
|
@ -23,6 +23,9 @@ public class SolveForXScreen extends Screen {
|
||||
@Override
|
||||
public void initialized() throws InterruptedException {}
|
||||
|
||||
@Override
|
||||
public void graphicInitialized() throws InterruptedException {}
|
||||
|
||||
@Override
|
||||
public void render() {
|
||||
Engine.INSTANCE.getHardwareDevice().getDisplayManager().renderer.glColor4i(0, 0, 0, 64);
|
||||
|
@ -9,6 +9,8 @@ import it.cavallium.warppi.util.Utils;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
|
||||
public abstract class FunctionDynamic implements Function {
|
||||
private boolean simplified;
|
||||
|
||||
public FunctionDynamic(final MathContext root) {
|
||||
this.root = root;
|
||||
functions = new Function[] {};
|
||||
|
@ -6,6 +6,8 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
|
||||
public abstract class FunctionSingle implements Function {
|
||||
|
||||
private boolean simplified;
|
||||
|
||||
/**
|
||||
* Create a new instance of FunctionSingle. The Math Context will be the
|
||||
* same of <strong>value</strong>'s.
|
||||
|
@ -1,65 +0,0 @@
|
||||
package it.cavallium.warppi.math.functions;
|
||||
|
||||
import it.cavallium.warppi.gui.expression.blocks.Block;
|
||||
import it.cavallium.warppi.math.Function;
|
||||
import it.cavallium.warppi.math.FunctionVisitor;
|
||||
import it.cavallium.warppi.math.MathContext;
|
||||
import it.cavallium.warppi.math.rules.Rule;
|
||||
import it.cavallium.warppi.util.Error;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
|
||||
public class EmptyNumber implements Function {
|
||||
|
||||
public EmptyNumber(final MathContext root) {
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
private final MathContext root;
|
||||
|
||||
@Override
|
||||
public ObjectArrayList<Function> simplify(final Rule rule) throws Error, InterruptedException {
|
||||
return rule.execute(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MathContext getMathContext() {
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
return o instanceof EmptyNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Function clone() {
|
||||
return new EmptyNumber(root);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Function clone(MathContext c) {
|
||||
return new EmptyNumber(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Function setParameter(final int index, final Function var) throws IndexOutOfBoundsException {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Function getParameter(final int index) throws IndexOutOfBoundsException {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectArrayList<Block> toBlock(final MathContext context) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T accept(final FunctionVisitor<T> visitor) {
|
||||
return visitor.visit(this);
|
||||
}
|
||||
|
||||
}
|
@ -14,6 +14,7 @@ public class Variable implements Function {
|
||||
protected char var;
|
||||
protected final MathContext root;
|
||||
protected V_TYPE type = V_TYPE.CONSTANT;
|
||||
private boolean simplified;
|
||||
|
||||
public Variable(final MathContext root, final char val, final V_TYPE type) {
|
||||
this.root = root;
|
||||
|
@ -1,6 +1,7 @@
|
||||
package it.cavallium.warppi.math.solver;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import it.cavallium.warppi.Engine;
|
||||
@ -9,6 +10,9 @@ import it.cavallium.warppi.math.Function;
|
||||
import it.cavallium.warppi.math.rules.Rule;
|
||||
import it.cavallium.warppi.math.rules.RuleType;
|
||||
import it.cavallium.warppi.util.Error;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMaps;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
|
||||
public class MathSolver {
|
||||
@ -17,6 +21,7 @@ public class MathSolver {
|
||||
private final AtomicInteger stepState = new AtomicInteger(0);
|
||||
private int stepStateRepetitions = 0;
|
||||
private int consecutiveNullSteps = 0;
|
||||
private final Object2ObjectOpenHashMap<Function, ObjectArrayList<Rule>> simplificationCache;
|
||||
|
||||
private enum StepState {
|
||||
_1_CALCULATION, _2_EXPANSION, _3_CALCULATION, _4_REDUCTION
|
||||
@ -28,6 +33,7 @@ public class MathSolver {
|
||||
|
||||
public MathSolver(final Function initialFunction) {
|
||||
this.initialFunction = initialFunction;
|
||||
this.simplificationCache = new Object2ObjectOpenHashMap<Function, ObjectArrayList<Rule>>();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -214,6 +220,7 @@ public class MathSolver {
|
||||
for (final Function fnc : fncs) {
|
||||
boolean didSomething = false;
|
||||
for (final Rule rule : rules) {
|
||||
if (isSimplified(fnc, rule) == false) {
|
||||
final List<Function> ruleResults = fnc.simplify(rule);
|
||||
if (ruleResults != null && !ruleResults.isEmpty()) {
|
||||
if (results == null) {
|
||||
@ -221,10 +228,12 @@ public class MathSolver {
|
||||
}
|
||||
results.addAll(ruleResults);
|
||||
appliedRules.add(rule);
|
||||
setSimplified(fnc, rule);
|
||||
didSomething = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!didSomething && fncs.size() > 1) {
|
||||
if (results == null) {
|
||||
results = new ObjectArrayList<>();
|
||||
@ -248,4 +257,30 @@ public class MathSolver {
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private boolean isSimplified(Function fnc, Rule rule) {
|
||||
if (simplificationCache.containsKey(fnc)) {
|
||||
List<Rule> alreadySimplifiedRules = simplificationCache.get(fnc);
|
||||
if (alreadySimplifiedRules.contains(rule)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
simplificationCache.put(fnc, new ObjectArrayList<Rule>());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void setSimplified(Function fnc, Rule rule) {
|
||||
ObjectArrayList<Rule> oar;
|
||||
if (simplificationCache.containsKey(fnc)) {
|
||||
oar = new ObjectArrayList<>();
|
||||
simplificationCache.put(fnc, oar);
|
||||
} else {
|
||||
oar = simplificationCache.get(fnc);
|
||||
if (oar.contains(rule)) return;
|
||||
}
|
||||
oar.add(rule);
|
||||
}
|
||||
}
|
||||
|
@ -4,15 +4,10 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.OperatingSystemMXBean;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.math.RoundingMode;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -571,55 +566,6 @@ public class Utils {
|
||||
return sdata;
|
||||
}
|
||||
|
||||
public static void printSystemResourcesUsage() {
|
||||
System.out.println("============");
|
||||
final OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
|
||||
for (final Method method : operatingSystemMXBean.getClass().getDeclaredMethods()) {
|
||||
method.setAccessible(true);
|
||||
if (method.getName().startsWith("get") && Modifier.isPublic(method.getModifiers())) {
|
||||
Object value;
|
||||
try {
|
||||
value = method.invoke(operatingSystemMXBean);
|
||||
} catch (final Exception e) {
|
||||
value = e;
|
||||
} // try
|
||||
boolean percent = false;
|
||||
boolean mb = false;
|
||||
final String displayName = method.getName();
|
||||
final String displayValue = value.toString();
|
||||
if (displayName.endsWith("CpuLoad")) {
|
||||
percent = true;
|
||||
}
|
||||
if (displayName.endsWith("MemorySize")) {
|
||||
mb = true;
|
||||
}
|
||||
final List<String> arr = new ArrayList<>();
|
||||
arr.add("getFreePhysicalMemorySize");
|
||||
arr.add("getProcessCpuLoad");
|
||||
arr.add("getSystemCpuLoad");
|
||||
arr.add("getTotalPhysicalMemorySize");
|
||||
if (arr.contains(displayName)) {
|
||||
if (percent) {
|
||||
try {
|
||||
System.out.println(displayName + " = " + (int) (Float.parseFloat(displayValue) * 10000f) / 100f + "%");
|
||||
} catch (final Exception ex) {
|
||||
System.out.println(displayName + " = " + displayValue);
|
||||
}
|
||||
} else if (mb) {
|
||||
try {
|
||||
System.out.println(displayName + " = " + Long.parseLong(displayValue) / 1024L / 1024L + " MB");
|
||||
} catch (final Exception ex) {
|
||||
System.out.println(displayName + " = " + displayValue);
|
||||
}
|
||||
} else {
|
||||
System.out.println(displayName + " = " + displayValue);
|
||||
}
|
||||
}
|
||||
} // if
|
||||
} // for
|
||||
System.out.println("============");
|
||||
}
|
||||
|
||||
public static boolean isWindows() {
|
||||
return Engine.getPlatform().getOsName().indexOf("win") >= 0;
|
||||
}
|
||||
|
@ -1,102 +0,0 @@
|
||||
package org.nevec.rjm;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Vector;
|
||||
|
||||
import it.cavallium.warppi.util.Error;
|
||||
|
||||
/**
|
||||
* Bernoulli numbers.
|
||||
*
|
||||
* @since 2006-06-25
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class Bernoulli {
|
||||
/*
|
||||
* The list of all Bernoulli numbers as a vector, n=0,2,4,....
|
||||
*/
|
||||
static Vector<Rational> a = new Vector<>();
|
||||
|
||||
public Bernoulli() {
|
||||
if (Bernoulli.a.size() == 0) {
|
||||
Bernoulli.a.add(Rational.ONE);
|
||||
Bernoulli.a.add(new Rational(1, 6));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a coefficient in the internal table.
|
||||
*
|
||||
* @param n
|
||||
* the zero-based index of the coefficient. n=0 for the constant
|
||||
* term.
|
||||
* @param value
|
||||
* the new value of the coefficient.
|
||||
*/
|
||||
protected void set(final int n, final Rational value) {
|
||||
final int nindx = n / 2;
|
||||
if (nindx < Bernoulli.a.size()) {
|
||||
Bernoulli.a.set(nindx, value);
|
||||
} else {
|
||||
while (Bernoulli.a.size() < nindx) {
|
||||
Bernoulli.a.add(Rational.ZERO);
|
||||
}
|
||||
Bernoulli.a.add(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The Bernoulli number at the index provided.
|
||||
*
|
||||
* @param n
|
||||
* the index, non-negative.
|
||||
* @return the B_0=1 for n=0, B_1=-1/2 for n=1, B_2=1/6 for n=2 etc
|
||||
* @throws Error
|
||||
*/
|
||||
public Rational at(final int n) throws Error {
|
||||
if (n == 1) {
|
||||
return new Rational(-1, 2);
|
||||
} else if (n % 2 != 0) {
|
||||
return Rational.ZERO;
|
||||
} else {
|
||||
final int nindx = n / 2;
|
||||
if (Bernoulli.a.size() <= nindx) {
|
||||
for (int i = 2 * Bernoulli.a.size(); i <= n; i += 2) {
|
||||
set(i, doubleSum(i));
|
||||
}
|
||||
}
|
||||
return Bernoulli.a.elementAt(nindx);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a new B_n by a standard double sum.
|
||||
*
|
||||
* @param n The index of the Bernoulli number.
|
||||
*
|
||||
* @return The Bernoulli number at n.
|
||||
*/
|
||||
private Rational doubleSum(final int n) throws Error {
|
||||
Rational resul = Rational.ZERO;
|
||||
for (int k = 0; k <= n; k++) {
|
||||
Rational jsum = Rational.ZERO;
|
||||
BigInteger bin = BigInteger.ONE;
|
||||
for (int j = 0; j <= k; j++) {
|
||||
final BigInteger jpown = new BigInteger("" + j).pow(n);
|
||||
if (j % 2 == 0) {
|
||||
jsum = jsum.add(bin.multiply(jpown));
|
||||
} else {
|
||||
jsum = jsum.subtract(bin.multiply(jpown));
|
||||
}
|
||||
|
||||
/*
|
||||
* update binomial(k,j) recursively
|
||||
*/
|
||||
bin = bin.multiply(new BigInteger("" + (k - j))).divide(new BigInteger("" + (j + 1)));
|
||||
}
|
||||
resul = resul.add(jsum.divide(new BigInteger("" + (k + 1))));
|
||||
}
|
||||
return resul;
|
||||
}
|
||||
|
||||
} /* Bernoulli */
|
@ -1,220 +0,0 @@
|
||||
package org.nevec.rjm;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
|
||||
/**
|
||||
* Complex numbers with BigDecimal real and imaginary components
|
||||
*
|
||||
* @since 2008-10-26
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class BigComplex {
|
||||
/**
|
||||
* real part
|
||||
*/
|
||||
BigDecimal re;
|
||||
|
||||
/**
|
||||
* imaginary part
|
||||
*/
|
||||
BigDecimal im;
|
||||
|
||||
/**
|
||||
* The constant that equals zero
|
||||
*/
|
||||
final static BigComplex ZERO = new BigComplex(BigDecimal.ZERO, BigDecimal.ZERO);
|
||||
|
||||
/**
|
||||
* Default ctor equivalent to zero.
|
||||
*/
|
||||
public BigComplex() {
|
||||
re = BigDecimal.ZERO;
|
||||
im = BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
/**
|
||||
* ctor with real and imaginary parts
|
||||
*
|
||||
* @param x
|
||||
* real part
|
||||
* @param y
|
||||
* imaginary part
|
||||
*/
|
||||
public BigComplex(final BigDecimal x, final BigDecimal y) {
|
||||
re = x;
|
||||
im = y;
|
||||
}
|
||||
|
||||
/**
|
||||
* ctor with real part.
|
||||
*
|
||||
* @param x
|
||||
* real part.
|
||||
* The imaginary part is set to zero.
|
||||
*/
|
||||
public BigComplex(final BigDecimal x) {
|
||||
re = x;
|
||||
im = BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
/**
|
||||
* ctor with real and imaginary parts
|
||||
*
|
||||
* @param x
|
||||
* real part
|
||||
* @param y
|
||||
* imaginary part
|
||||
*/
|
||||
public BigComplex(final double x, final double y) {
|
||||
re = new BigDecimal(x);
|
||||
im = new BigDecimal(y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply with another BigComplex
|
||||
*
|
||||
* @param oth
|
||||
* The BigComplex which is a factor in the product
|
||||
* @param mc
|
||||
* Defining precision and rounding mode
|
||||
* @return This multiplied by oth
|
||||
* @since 2010-07-19 implemented with 3 multiplications and 5
|
||||
* additions/subtractions
|
||||
*/
|
||||
BigComplex multiply(final BigComplex oth, final MathContext mc) {
|
||||
final BigDecimal a = re.add(im).multiply(oth.re);
|
||||
final BigDecimal b = oth.re.add(oth.im).multiply(im);
|
||||
final BigDecimal c = oth.im.subtract(oth.re).multiply(re);
|
||||
final BigDecimal x = a.subtract(b, mc);
|
||||
final BigDecimal y = a.add(c, mc);
|
||||
return new BigComplex(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a BigDecimal
|
||||
*
|
||||
* @param oth
|
||||
* the value to be added to the real part.
|
||||
* @return this added to oth
|
||||
*/
|
||||
BigComplex add(final BigDecimal oth) {
|
||||
final BigDecimal x = re.add(oth);
|
||||
return new BigComplex(x, im);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract another BigComplex
|
||||
*
|
||||
* @param oth
|
||||
* the value to be subtracted from this.
|
||||
* @return this minus oth
|
||||
*/
|
||||
BigComplex subtract(final BigComplex oth) {
|
||||
final BigDecimal x = re.subtract(oth.re);
|
||||
final BigDecimal y = im.subtract(oth.im);
|
||||
return new BigComplex(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Complex-conjugation
|
||||
*
|
||||
* @return the complex conjugate of this.
|
||||
*/
|
||||
BigComplex conj() {
|
||||
return new BigComplex(re, im.negate());
|
||||
}
|
||||
|
||||
/**
|
||||
* The absolute value squared.
|
||||
*
|
||||
* @return The sum of the squares of real and imaginary parts.
|
||||
* This is the square of BigComplex.abs() .
|
||||
*/
|
||||
BigDecimal norm() {
|
||||
return re.multiply(re).add(im.multiply(im));
|
||||
}
|
||||
|
||||
/**
|
||||
* The absolute value.
|
||||
*
|
||||
* @return the square root of the sum of the squares of real and imaginary
|
||||
* parts.
|
||||
* @since 2008-10-27
|
||||
*/
|
||||
BigDecimal abs(final MathContext mc) {
|
||||
return BigDecimalMath.sqrt(norm(), mc);
|
||||
}
|
||||
|
||||
/**
|
||||
* The square root.
|
||||
*
|
||||
* @return the square root of the this.
|
||||
* The branch is chosen such that the imaginary part of the result
|
||||
* has the
|
||||
* same sign as the imaginary part of this.
|
||||
* @see Tim Ahrendt, <a href="https://doi.org/10.1145/236869.236924">Fast
|
||||
* High-precision computation of complex square roots</a>,
|
||||
* ISSAC 1996 p142-149.
|
||||
* @since 2008-10-27
|
||||
*/
|
||||
BigComplex sqrt(final MathContext mc) {
|
||||
final BigDecimal half = new BigDecimal("2");
|
||||
/*
|
||||
* compute l=sqrt(re^2+im^2), then u=sqrt((l+re)/2)
|
||||
* and v= +- sqrt((l-re)/2 as the new real and imaginary parts.
|
||||
*/
|
||||
final BigDecimal l = abs(mc);
|
||||
if (l.compareTo(BigDecimal.ZERO) == 0) {
|
||||
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 v = BigDecimalMath.sqrt(l.subtract(re).divide(half, mc), mc);
|
||||
if (im.compareTo(BigDecimal.ZERO) >= 0) {
|
||||
return new BigComplex(u, v);
|
||||
} else {
|
||||
return new BigComplex(u, v.negate());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The inverse of this.
|
||||
*
|
||||
* @return 1/this
|
||||
*/
|
||||
BigComplex inverse(final MathContext mc) {
|
||||
final BigDecimal hyp = norm();
|
||||
/* 1/(x+iy)= (x-iy)/(x^2+y^2 */
|
||||
return new BigComplex(re.divide(hyp, mc), im.divide(hyp, mc).negate());
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide through another BigComplex number.
|
||||
*
|
||||
* @return this/oth
|
||||
*/
|
||||
BigComplex divide(final BigComplex oth, final MathContext mc) {
|
||||
/* lazy implementation: (x+iy)/(a+ib)= (x+iy)* 1/(a+ib) */
|
||||
return multiply(oth.inverse(mc), mc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Human-readable Fortran-type display
|
||||
*
|
||||
* @return real and imaginary part in parenthesis, divided by a comma.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + re.toString() + "," + im.toString() + ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Human-readable Fortran-type display
|
||||
*
|
||||
* @return real and imaginary part in parenthesis, divided by a comma.
|
||||
*/
|
||||
public String toString(final MathContext mc) {
|
||||
return "(" + re.round(mc).toString() + "," + im.round(mc).toString() + ")";
|
||||
}
|
||||
|
||||
} /* BigComplex */
|
File diff suppressed because it is too large
Load Diff
@ -1,644 +0,0 @@
|
||||
package org.nevec.rjm;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Vector;
|
||||
|
||||
import it.cavallium.warppi.util.Error;
|
||||
|
||||
/**
|
||||
* BigInteger special functions and Number theory.
|
||||
*
|
||||
* @since 2009-08-06
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class BigIntegerMath {
|
||||
|
||||
/**
|
||||
* Evaluate binomial(n,k).
|
||||
*
|
||||
* @param n
|
||||
* The upper index
|
||||
* @param k
|
||||
* The lower index
|
||||
* @return The binomial coefficient
|
||||
*/
|
||||
static public BigInteger binomial(final int n, final int k) {
|
||||
if (k == 0) {
|
||||
return BigInteger.ONE;
|
||||
}
|
||||
BigInteger bin = new BigInteger("" + n);
|
||||
final BigInteger n2 = bin;
|
||||
for (BigInteger i = new BigInteger("" + (k - 1)); i.compareTo(BigInteger.ONE) >= 0; i = i.subtract(BigInteger.ONE)) {
|
||||
bin = bin.multiply(n2.subtract(i));
|
||||
}
|
||||
for (BigInteger i = new BigInteger("" + k); i.compareTo(BigInteger.ONE) == 1; i = i.subtract(BigInteger.ONE)) {
|
||||
bin = bin.divide(i);
|
||||
}
|
||||
return bin;
|
||||
} /* binomial */
|
||||
|
||||
/**
|
||||
* Evaluate binomial(n,k).
|
||||
*
|
||||
* @param n
|
||||
* The upper index
|
||||
* @param k
|
||||
* The lower index
|
||||
* @return The binomial coefficient
|
||||
* @since 2008-10-15
|
||||
*/
|
||||
static public BigInteger binomial(final BigInteger n, final BigInteger k) {
|
||||
/*
|
||||
* binomial(n,0) =1
|
||||
*/
|
||||
if (k.compareTo(BigInteger.ZERO) == 0) {
|
||||
return BigInteger.ONE;
|
||||
}
|
||||
|
||||
BigInteger bin = new BigInteger("" + n);
|
||||
|
||||
/*
|
||||
* the following version first calculates n(n-1)(n-2)..(n-k+1)
|
||||
* in the first loop, and divides this product through k(k-1)(k-2)....2
|
||||
* in the second loop. This is rather slow and replaced by a faster
|
||||
* version
|
||||
* below
|
||||
* BigInteger n2 = bin ;
|
||||
* BigInteger i= k.subtract(BigInteger.ONE) ;
|
||||
* for( ; i.compareTo(BigInteger.ONE) >= 0 ; i =
|
||||
* i.subtract(BigInteger.ONE) )
|
||||
* bin = bin.multiply(n2.subtract(i)) ;
|
||||
* i= new BigInteger(""+k) ;
|
||||
* for( ; i.compareTo(BigInteger.ONE) == 1 ; i =
|
||||
* i.subtract(BigInteger.ONE) )
|
||||
* bin = bin.divide(i) ;
|
||||
*/
|
||||
|
||||
/*
|
||||
* calculate n then n(n-1)/2 then n(n-1)(n-2)(2*3) etc up to
|
||||
* n(n-1)..(n-k+1)/(2*3*..k)
|
||||
* This is roughly the best way to keep the individual intermediate
|
||||
* products small
|
||||
* 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());
|
||||
if (n.subtract(k).compareTo(k) < 0) {
|
||||
truek = n.subtract(k);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate C(num,truek) where num=n and truek is the smaller of n-k
|
||||
* and k.
|
||||
* Have already initialized bin=n=C(n,1) above. Start definining the
|
||||
* factorial
|
||||
* in the denominator, named fden
|
||||
*/
|
||||
BigInteger i = new BigInteger("2");
|
||||
BigInteger num = new BigInteger(n.toString());
|
||||
/*
|
||||
* a for-loop (i=2;i<= truek;i++)
|
||||
*/
|
||||
for (; i.compareTo(truek) <= 0; i = i.add(BigInteger.ONE)) {
|
||||
/*
|
||||
* num = n-i+1 after this operation
|
||||
*/
|
||||
num = num.subtract(BigInteger.ONE);
|
||||
/*
|
||||
* multiply by (n-i+1)/i
|
||||
*/
|
||||
bin = bin.multiply(num).divide(i);
|
||||
}
|
||||
return bin;
|
||||
} /* binomial */
|
||||
|
||||
/**
|
||||
* Evaluate sigma_k(n).
|
||||
*
|
||||
* @param n
|
||||
* the main argument which defines the divisors
|
||||
* @param k
|
||||
* the lower index, which defines the power
|
||||
* @return The sum of the k-th powers of the positive divisors
|
||||
*/
|
||||
static public BigInteger sigmak(final BigInteger n, final int k) {
|
||||
return new Ifactor(n.abs()).sigma(k).n;
|
||||
} /* sigmak */
|
||||
|
||||
/**
|
||||
* Evaluate sigma(n).
|
||||
*
|
||||
* @param n
|
||||
* the argument for which divisors will be searched.
|
||||
* @return the sigma function. Sum of the positive divisors of the argument.
|
||||
* @since 2006-08-14
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
static public BigInteger sigma(final int n) {
|
||||
return new Ifactor(Math.abs(n)).sigma().n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the list of positive divisors.<br>
|
||||
* <b>Deprecated: This function is extremely slow and inefficient!</b>
|
||||
*
|
||||
* @param n
|
||||
* The integer of which the divisors are to be found.
|
||||
* @return The sorted list of positive divisors.
|
||||
* @since 2010-08-27
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
@Deprecated
|
||||
static public Vector<BigInteger> divisors(final BigInteger n) {
|
||||
return new Ifactor(n.abs()).divisors();
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate sigma(n).
|
||||
*
|
||||
* @param n
|
||||
* the argument for which divisors will be searched.
|
||||
* @return the sigma function. Sum of the divisors of the argument.
|
||||
* @since 2006-08-14
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
static public BigInteger sigma(final BigInteger n) {
|
||||
return new Ifactor(n.abs()).sigma().n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate floor(sqrt(n)).
|
||||
*
|
||||
* @param n
|
||||
* The non-negative argument.
|
||||
* @return The integer square root. The square root rounded down.
|
||||
* @since 2010-08-27
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
static public int isqrt(final int n) {
|
||||
if (n < 0) {
|
||||
throw new ArithmeticException("Negative argument " + n);
|
||||
}
|
||||
final double resul = Math.sqrt(n);
|
||||
return (int) Math.round(resul);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate floor(sqrt(n)).
|
||||
*
|
||||
* @param n
|
||||
* The non-negative argument.
|
||||
* Arguments less than zero throw an ArithmeticException.
|
||||
* @return The integer square root, the square root rounded down.
|
||||
* @since 2010-08-27
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
static public long isqrt(final long n) {
|
||||
if (n < 0) {
|
||||
throw new ArithmeticException("Negative argument " + n);
|
||||
}
|
||||
final double resul = Math.sqrt(n);
|
||||
return Math.round(resul);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate floor(sqrt(n)).
|
||||
*
|
||||
* @param n
|
||||
* The non-negative argument.
|
||||
* Arguments less than zero throw an ArithmeticException.
|
||||
* @return The integer square root, the square root rounded down.
|
||||
* @since 2011-02-12
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
static public BigInteger isqrt(final BigInteger n) {
|
||||
if (n.compareTo(BigInteger.ZERO) < 0) {
|
||||
throw new ArithmeticException("Negative argument " + n.toString());
|
||||
}
|
||||
/*
|
||||
* Start with an estimate from a floating point reduction.
|
||||
*/
|
||||
BigInteger x;
|
||||
final int bl = n.bitLength();
|
||||
if (bl > 120) {
|
||||
x = n.shiftRight(bl / 2 - 1);
|
||||
} else {
|
||||
final double resul = Math.sqrt(n.doubleValue());
|
||||
x = new BigInteger("" + Math.round(resul));
|
||||
}
|
||||
|
||||
final BigInteger two = new BigInteger("2");
|
||||
while (true) {
|
||||
/*
|
||||
* check whether the result is accurate, x^2 =n
|
||||
*/
|
||||
final BigInteger x2 = x.pow(2);
|
||||
BigInteger xplus2 = x.add(BigInteger.ONE).pow(2);
|
||||
if (x2.compareTo(n) <= 0 && xplus2.compareTo(n) > 0) {
|
||||
return x;
|
||||
}
|
||||
xplus2 = xplus2.subtract(x.shiftLeft(2));
|
||||
if (xplus2.compareTo(n) <= 0 && x2.compareTo(n) > 0) {
|
||||
return x.subtract(BigInteger.ONE);
|
||||
}
|
||||
/*
|
||||
* Newton algorithm. This correction is on the
|
||||
* low side caused by the integer divisions. So the value required
|
||||
* may end up by one unit too large by the bare algorithm, and this
|
||||
* is caught above by comparing x^2, (x+-1)^2 with n.
|
||||
*/
|
||||
xplus2 = x2.subtract(n).divide(x).divide(two);
|
||||
x = x.subtract(xplus2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate core(n).
|
||||
* Returns the smallest positive integer m such that n/m is a perfect
|
||||
* square.
|
||||
*
|
||||
* @param n
|
||||
* The non-negative argument.
|
||||
* @return The square-free part of n.
|
||||
* @since 2011-02-12
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
static public BigInteger core(final BigInteger n) {
|
||||
if (n.compareTo(BigInteger.ZERO) < 0) {
|
||||
throw new ArithmeticException("Negative argument " + n);
|
||||
}
|
||||
final Ifactor i = new Ifactor(n);
|
||||
return i.core();
|
||||
}
|
||||
|
||||
/**
|
||||
* Minor of an integer matrix.
|
||||
*
|
||||
* @param A
|
||||
* The matrix.
|
||||
* @param r
|
||||
* The row index of the row to be removed (0-based).
|
||||
* An exception is thrown if this is outside the range 0 to the
|
||||
* upper row index of A.
|
||||
* @param c
|
||||
* The column index of the column to be removed (0-based).
|
||||
* An exception is thrown if this is outside the range 0 to the
|
||||
* upper column index of A.
|
||||
* @return The depleted matrix. This is not a deep copy but contains
|
||||
* references to the original.
|
||||
* @since 2010-08-27
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
static public BigInteger[][] minor(final BigInteger[][] A, final int r, final int c) throws ArithmeticException {
|
||||
/* original row count */
|
||||
final int rL = A.length;
|
||||
if (rL == 0) {
|
||||
throw new ArithmeticException("zero row count in matrix");
|
||||
}
|
||||
if (r < 0 || r >= rL) {
|
||||
throw new ArithmeticException("row number " + r + " out of range 0.." + (rL - 1));
|
||||
}
|
||||
/* original column count */
|
||||
final int cL = A[0].length;
|
||||
if (cL == 0) {
|
||||
throw new ArithmeticException("zero column count in matrix");
|
||||
}
|
||||
if (c < 0 || c >= cL) {
|
||||
throw new ArithmeticException("column number " + c + " out of range 0.." + (cL - 1));
|
||||
}
|
||||
final BigInteger M[][] = new BigInteger[rL - 1][cL - 1];
|
||||
int imrow = 0;
|
||||
for (int row = 0; row < rL; row++) {
|
||||
if (row != r) {
|
||||
int imcol = 0;
|
||||
for (int col = 0; col < cL; col++) {
|
||||
if (col != c) {
|
||||
M[imrow][imcol] = A[row][col];
|
||||
imcol++;
|
||||
}
|
||||
}
|
||||
imrow++;
|
||||
}
|
||||
}
|
||||
return M;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace column of a matrix with a column vector.
|
||||
*
|
||||
* @param A
|
||||
* The matrix.
|
||||
* @param c
|
||||
* The column index of the column to be substituted (0-based).
|
||||
* @param v
|
||||
* The column vector to be inserted.
|
||||
* With the current implementation, it must be at least as long
|
||||
* as the row count, and
|
||||
* its elements that exceed that count are ignored.
|
||||
* @return The modified matrix. This is not a deep copy but contains
|
||||
* references to the original.
|
||||
* @since 2010-08-27
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
static private BigInteger[][] colSubs(final BigInteger[][] A, final int c, final BigInteger[] v)
|
||||
throws ArithmeticException {
|
||||
/* original row count */
|
||||
final int rL = A.length;
|
||||
if (rL == 0) {
|
||||
throw new ArithmeticException("zero row count in matrix");
|
||||
}
|
||||
/* original column count */
|
||||
final int cL = A[0].length;
|
||||
if (cL == 0) {
|
||||
throw new ArithmeticException("zero column count in matrix");
|
||||
}
|
||||
if (c < 0 || c >= cL) {
|
||||
throw new ArithmeticException("column number " + c + " out of range 0.." + (cL - 1));
|
||||
}
|
||||
final BigInteger M[][] = new BigInteger[rL][cL];
|
||||
for (int row = 0; row < rL; row++) {
|
||||
for (int col = 0; col < cL; col++) {
|
||||
/*
|
||||
* currently, v may just be longer than the row count, and
|
||||
* surplus
|
||||
* elements will be ignored. Shorter v lead to an exception.
|
||||
*/
|
||||
if (col != c) {
|
||||
M[row][col] = A[row][col];
|
||||
} else {
|
||||
M[row][col] = v[row];
|
||||
}
|
||||
}
|
||||
}
|
||||
return M;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determinant of an integer square matrix.
|
||||
*
|
||||
* @param A
|
||||
* The square matrix.
|
||||
* If column and row dimensions are unequal, an
|
||||
* ArithmeticException is thrown.
|
||||
* @return The determinant.
|
||||
* @since 2010-08-27
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
static public BigInteger det(final BigInteger[][] A) throws ArithmeticException {
|
||||
BigInteger d = BigInteger.ZERO;
|
||||
/* row size */
|
||||
final int rL = A.length;
|
||||
if (rL == 0) {
|
||||
throw new ArithmeticException("zero row count in matrix");
|
||||
}
|
||||
/* column size */
|
||||
final int cL = A[0].length;
|
||||
if (cL != rL) {
|
||||
throw new ArithmeticException("Non-square matrix dim " + rL + " by " + cL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the low-order cases directly.
|
||||
*/
|
||||
if (rL == 1) {
|
||||
return A[0][0];
|
||||
} else if (rL == 2) {
|
||||
d = A[0][0].multiply(A[1][1]);
|
||||
return d.subtract(A[0][1].multiply(A[1][0]));
|
||||
} else {
|
||||
/* Work arbitrarily along the first column of the matrix */
|
||||
for (int r = 0; r < rL; r++) {
|
||||
/*
|
||||
* Do not consider minors that do no contribute anyway
|
||||
*/
|
||||
if (A[r][0].compareTo(BigInteger.ZERO) != 0) {
|
||||
final BigInteger M[][] = BigIntegerMath.minor(A, r, 0);
|
||||
final BigInteger m = A[r][0].multiply(BigIntegerMath.det(M));
|
||||
/* recursive call */
|
||||
if (r % 2 == 0) {
|
||||
d = d.add(m);
|
||||
} else {
|
||||
d = d.subtract(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Solve a linear system of equations.
|
||||
*
|
||||
* @param A
|
||||
* The square matrix.
|
||||
* If it is not of full rank, an ArithmeticException is thrown.
|
||||
* @param rhs
|
||||
* The right hand side. The length of this vector must match the
|
||||
* matrix size;
|
||||
* else an ArithmeticException is thrown.
|
||||
* @return The vector of x in A*x=rhs.
|
||||
* @since 2010-08-28
|
||||
* @author Richard J. Mathar
|
||||
* @throws Error
|
||||
*/
|
||||
static public Rational[] solve(final BigInteger[][] A, final BigInteger[] rhs) throws ArithmeticException, Error {
|
||||
|
||||
final int rL = A.length;
|
||||
if (rL == 0) {
|
||||
throw new ArithmeticException("zero row count in matrix");
|
||||
}
|
||||
|
||||
/* column size */
|
||||
final int cL = A[0].length;
|
||||
if (cL != rL) {
|
||||
throw new ArithmeticException("Non-square matrix dim " + rL + " by " + cL);
|
||||
}
|
||||
if (rhs.length != rL) {
|
||||
throw new ArithmeticException("Right hand side dim " + rhs.length + " unequal matrix dim " + rL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Gauss elimination
|
||||
*/
|
||||
final Rational x[] = new Rational[rL];
|
||||
|
||||
/*
|
||||
* copy of r.h.s ito a mutable Rationalright hand side
|
||||
*/
|
||||
for (int c = 0; c < cL; c++) {
|
||||
x[c] = new Rational(rhs[c]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create zeros downwards column c by linear combination of row c and
|
||||
* row r.
|
||||
*/
|
||||
for (int c = 0; c < cL - 1; c++) {
|
||||
/*
|
||||
* zero on the diagonal? swap with a non-zero row, searched with
|
||||
* index r
|
||||
*/
|
||||
if (A[c][c].compareTo(BigInteger.ZERO) == 0) {
|
||||
boolean swpd = false;
|
||||
for (int r = c + 1; r < rL; r++) {
|
||||
if (A[r][c].compareTo(BigInteger.ZERO) != 0) {
|
||||
for (int cpr = c; cpr < cL; cpr++) {
|
||||
final BigInteger tmp = A[c][cpr];
|
||||
A[c][cpr] = A[r][cpr];
|
||||
A[r][cpr] = tmp;
|
||||
}
|
||||
final Rational tmp = x[c];
|
||||
x[c] = x[r];
|
||||
x[r] = tmp;
|
||||
swpd = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* not swapped with a non-zero row: determinant zero and no
|
||||
* solution
|
||||
*/
|
||||
if (!swpd) {
|
||||
throw new ArithmeticException("Zero determinant of main matrix");
|
||||
}
|
||||
}
|
||||
/* create zero at A[c+1..cL-1][c] */
|
||||
for (int r = c + 1; r < rL; r++) {
|
||||
/*
|
||||
* skip the cpr=c which actually sets the zero: this element is
|
||||
* not visited again
|
||||
*/
|
||||
for (int cpr = c + 1; cpr < cL; cpr++) {
|
||||
final BigInteger tmp = A[c][c].multiply(A[r][cpr]).subtract(A[c][cpr].multiply(A[r][c]));
|
||||
A[r][cpr] = tmp;
|
||||
}
|
||||
final Rational tmp = x[r].multiply(A[c][c]).subtract(x[c].multiply(A[r][c]));
|
||||
x[r] = tmp;
|
||||
}
|
||||
}
|
||||
if (A[cL - 1][cL - 1].compareTo(BigInteger.ZERO) == 0) {
|
||||
throw new ArithmeticException("Zero determinant of main matrix");
|
||||
}
|
||||
/* backward elimination */
|
||||
for (int r = cL - 1; r >= 0; r--) {
|
||||
x[r] = x[r].divide(A[r][r]);
|
||||
for (int rpr = r - 1; rpr >= 0; rpr--) {
|
||||
x[rpr] = x[rpr].subtract(x[r].multiply(A[rpr][r]));
|
||||
}
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* The lowest common multiple
|
||||
*
|
||||
* @param a
|
||||
* The first argument
|
||||
* @param b
|
||||
* The second argument
|
||||
* @return lcm(|a|,|b|)
|
||||
* @since 2010-08-27
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
static public BigInteger lcm(final BigInteger a, final BigInteger b) {
|
||||
final BigInteger g = a.gcd(b);
|
||||
return a.multiply(b).abs().divide(g);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate the value of an integer polynomial at some integer argument.
|
||||
*
|
||||
* @param c
|
||||
* Represents the coefficients c[0]+c[1]*x+c[2]*x^2+.. of the
|
||||
* polynomial
|
||||
* @param x
|
||||
* The abscissa point of the evaluation
|
||||
* @return The polynomial value.
|
||||
* @since 2010-08-27
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
static public BigInteger valueOf(final Vector<BigInteger> c, final BigInteger x) {
|
||||
if (c.size() == 0) {
|
||||
return BigInteger.ZERO;
|
||||
}
|
||||
BigInteger res = c.lastElement();
|
||||
for (int i = c.size() - 2; i >= 0; i--) {
|
||||
res = res.multiply(x).add(c.elementAt(i));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* The central factorial number t(n,k) number at the indices provided.
|
||||
*
|
||||
* @param n
|
||||
* the first parameter, non-negative.
|
||||
* @param k
|
||||
* the second index, non-negative.
|
||||
* @return t(n,k)
|
||||
* @since 2009-08-06
|
||||
* @author Richard J. Mathar
|
||||
* @throws Error
|
||||
* @see <a href="https://doi.org/10.1080/01630568908816313">P. L. Butzer
|
||||
* et al, Num. Funct. Anal. Opt. 10 (5)( 1989) 419-488</a>
|
||||
*/
|
||||
static public Rational centrlFactNumt(final int n, final int k) throws Error {
|
||||
if (k > n || k < 0 || k % 2 != n % 2) {
|
||||
return Rational.ZERO;
|
||||
} else if (k == n) {
|
||||
return Rational.ONE;
|
||||
} else {
|
||||
/* Proposition 6.2.6 */
|
||||
final Factorial f = new Factorial();
|
||||
Rational jsum = new Rational(0, 1);
|
||||
final int kprime = n - k;
|
||||
for (int j = 0; j <= kprime; j++) {
|
||||
Rational nusum = new Rational(0, 1);
|
||||
for (int nu = 0; nu <= j; nu++) {
|
||||
Rational t = new Rational(j - 2 * nu, 2);
|
||||
t = t.pow(kprime + j);
|
||||
t = t.multiply(BigIntegerMath.binomial(j, nu));
|
||||
if (nu % 2 != 0) {
|
||||
nusum = nusum.subtract(t);
|
||||
} else {
|
||||
nusum = nusum.add(t);
|
||||
}
|
||||
}
|
||||
nusum = nusum.divide(f.at(j)).divide(n + j);
|
||||
nusum = nusum.multiply(BigIntegerMath.binomial(2 * kprime, kprime - j));
|
||||
if (j % 2 != 0) {
|
||||
jsum = jsum.subtract(nusum);
|
||||
} else {
|
||||
jsum = jsum.add(nusum);
|
||||
}
|
||||
}
|
||||
return jsum.multiply(k).multiply(BigIntegerMath.binomial(n + kprime, k));
|
||||
}
|
||||
} /* CentralFactNumt */
|
||||
|
||||
/**
|
||||
* The central factorial number T(n,k) number at the indices provided.
|
||||
*
|
||||
* @param n
|
||||
* the first parameter, non-negative.
|
||||
* @param k
|
||||
* the second index, non-negative.
|
||||
* @return T(n,k)
|
||||
* @since 2009-08-06
|
||||
* @author Richard J. Mathar
|
||||
* @see <a href="https://doi.org/10.1080/01630568908816313">P. L. Butzer
|
||||
* et al, Num. Funct. Anal. Opt. 10 (5)( 1989) 419-488</a>
|
||||
*/
|
||||
static public Rational centrlFactNumT(final int n, final int k) {
|
||||
if (k > n || k < 0 || k % 2 != n % 2) {
|
||||
return Rational.ZERO;
|
||||
} else if (k == n) {
|
||||
return Rational.ONE;
|
||||
} else {
|
||||
/* Proposition 2.1 */
|
||||
return BigIntegerMath.centrlFactNumT(n - 2, k - 2).add(BigIntegerMath.centrlFactNumT(n - 2, k).multiply(new Rational(k * k, 4)));
|
||||
}
|
||||
} /* CentralFactNumT */
|
||||
|
||||
} /* BigIntegerMath */
|
@ -1,764 +0,0 @@
|
||||
package org.nevec.rjm;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Scanner;
|
||||
import java.util.Vector;
|
||||
|
||||
import it.cavallium.warppi.util.Error;
|
||||
|
||||
/**
|
||||
* Polynomial with integer coefficients.
|
||||
* Alternatively to be interpreted as a sequence which has the polynomial as an
|
||||
* (approximate)
|
||||
* generating function.
|
||||
*
|
||||
* @since 2010-08-27
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class BigIntegerPoly implements Cloneable {
|
||||
/**
|
||||
* The list of all coefficients, starting with a0, then a1, as in
|
||||
* poly=a0+a1*x+a2*x^2+a3*x^3+...
|
||||
*/
|
||||
Vector<BigInteger> a;
|
||||
|
||||
/**
|
||||
* Default ctor.
|
||||
* Creates the polynomial p(x)=0.
|
||||
*/
|
||||
public BigIntegerPoly() {
|
||||
a = new Vector<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ctor with a comma-separated list as the list of coefficients.
|
||||
*
|
||||
* @param L
|
||||
* the string of the form a0,a1,a2,a3 with the coefficients
|
||||
*/
|
||||
public BigIntegerPoly(final String L) throws NumberFormatException {
|
||||
a = new Vector<>();
|
||||
final Scanner sc = new Scanner(L);
|
||||
sc.useDelimiter(",");
|
||||
while (sc.hasNextBigInteger()) {
|
||||
a.add(sc.nextBigInteger());
|
||||
}
|
||||
simplify();
|
||||
sc.close();
|
||||
} /* ctor */
|
||||
|
||||
/**
|
||||
* Ctor with a list of coefficients.
|
||||
*
|
||||
* @param c
|
||||
* The coefficients a0, a1, a2 etc in a0+a1*x+a2*x^2+...
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public BigIntegerPoly(final Vector<BigInteger> c) {
|
||||
a = (Vector<BigInteger>) c.clone();
|
||||
simplify();
|
||||
} /* ctor */
|
||||
|
||||
/**
|
||||
* Ctor with a list of coefficients.
|
||||
*
|
||||
* @param c
|
||||
* The coefficients a0, a1, a2 etc in a0+a1*x+a2*x^2+...
|
||||
*/
|
||||
public BigIntegerPoly(final BigInteger[] c) {
|
||||
for (final BigInteger element : c) {
|
||||
a.add(element.add(BigInteger.ZERO));
|
||||
}
|
||||
simplify();
|
||||
} /* ctor */
|
||||
|
||||
/**
|
||||
* Create a copy of this.
|
||||
*
|
||||
* @since 2010-08-27
|
||||
*/
|
||||
@Override
|
||||
public BigIntegerPoly clone() {
|
||||
return new BigIntegerPoly(a);
|
||||
} /* clone */
|
||||
|
||||
/**
|
||||
* Translate into a RatPoly copy.
|
||||
*
|
||||
* @since 2012-03-02
|
||||
*/
|
||||
public RatPoly toRatPoly() {
|
||||
final RatPoly bd = new RatPoly();
|
||||
for (int i = 0; i < a.size(); i++) {
|
||||
bd.set(i, a.elementAt(i));
|
||||
}
|
||||
return bd;
|
||||
} /* toRatPoly */
|
||||
|
||||
/**
|
||||
* Retrieve a polynomial coefficient.
|
||||
*
|
||||
* @param n
|
||||
* the zero-based index of the coefficient. n=0 for the constant
|
||||
* term.
|
||||
* @return the polynomial coefficient in front of x^n.
|
||||
*/
|
||||
public BigInteger at(final int n) {
|
||||
if (n < a.size()) {
|
||||
return a.elementAt(n);
|
||||
} else {
|
||||
return BigInteger.ZERO;
|
||||
}
|
||||
} /* at */
|
||||
|
||||
/**
|
||||
* Evaluate at some integer argument.
|
||||
*
|
||||
* @param x
|
||||
* The abscissa point of the evaluation
|
||||
* @return The polynomial value.
|
||||
* @since 2010-08-27
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public BigInteger valueOf(final BigInteger x) {
|
||||
if (a.size() == 0) {
|
||||
return BigInteger.ZERO;
|
||||
}
|
||||
BigInteger res = a.lastElement();
|
||||
/*
|
||||
* Heron casted form
|
||||
*/
|
||||
for (int i = a.size() - 2; i >= 0; i--) {
|
||||
res = res.multiply(x).add(a.elementAt(i));
|
||||
}
|
||||
return res;
|
||||
} /* valueOf */
|
||||
|
||||
/**
|
||||
* Horner scheme to find the function value at the argument x
|
||||
*
|
||||
* @param x
|
||||
* The argument x.
|
||||
* @return Value of the polynomial at x.
|
||||
* @since 2008-11-13
|
||||
*/
|
||||
public BigInteger valueOf(final int x) {
|
||||
return valueOf(new BigInteger("" + x));
|
||||
} /* valueOf */
|
||||
|
||||
/**
|
||||
* Set a polynomial coefficient.
|
||||
*
|
||||
* @param n
|
||||
* the zero-based index of the coefficient. n=0 for the constant
|
||||
* term.
|
||||
* If the polynomial has not yet the degree to need this
|
||||
* coefficient,
|
||||
* the intermediate coefficients are set to zero.
|
||||
* @param value
|
||||
* the new value of the coefficient.
|
||||
*/
|
||||
public void set(final int n, final BigInteger value) {
|
||||
if (n < a.size()) {
|
||||
a.set(n, value);
|
||||
} else {
|
||||
/*
|
||||
* fill intermediate powers with coefficients of zero
|
||||
*/
|
||||
while (a.size() < n) {
|
||||
a.add(BigInteger.ZERO);
|
||||
}
|
||||
a.add(value);
|
||||
}
|
||||
} /* set */
|
||||
|
||||
/**
|
||||
* Set a polynomial coefficient.
|
||||
*
|
||||
* @param n
|
||||
* the zero-based index of the coefficient. n=0 for the constant
|
||||
* term.
|
||||
* If the polynomial has not yet the degree to need this
|
||||
* coefficient,
|
||||
* the intermediate coefficients are implicitly set to zero.
|
||||
* @param value
|
||||
* the new value of the coefficient.
|
||||
*/
|
||||
public void set(final int n, final int value) {
|
||||
final BigInteger val2 = new BigInteger("" + value);
|
||||
set(n, val2);
|
||||
} /* set */
|
||||
|
||||
/**
|
||||
* Count of coefficients.
|
||||
*
|
||||
* @return the number of polynomial coefficients.
|
||||
* Differs from the polynomial degree by one.
|
||||
*/
|
||||
public int size() {
|
||||
return a.size();
|
||||
} /* size */
|
||||
|
||||
/**
|
||||
* Polynomial degree.
|
||||
*
|
||||
* @return the polynomial degree.
|
||||
*/
|
||||
public int degree() {
|
||||
return a.size() - 1;
|
||||
} /* degree */
|
||||
|
||||
/**
|
||||
* Polynomial lower degree.
|
||||
*
|
||||
* @return power of the smallest non-zero coefficient.
|
||||
* If the polynomial is identical to 0, 0 is returned.
|
||||
*/
|
||||
public int ldegree() {
|
||||
for (int n = 0; n < a.size(); n++) {
|
||||
if (a.elementAt(n).compareTo(BigInteger.ZERO) != 0) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} /* ldegree */
|
||||
|
||||
/**
|
||||
* Multiply by a constant factor.
|
||||
*
|
||||
* @param val
|
||||
* the factor
|
||||
* @return the product of this with the factor.
|
||||
* All coefficients of this have been multiplied individually by the
|
||||
* factor.
|
||||
* @since 2010-08-27
|
||||
*/
|
||||
public BigIntegerPoly multiply(final BigInteger val) {
|
||||
final BigIntegerPoly resul = new BigIntegerPoly();
|
||||
if (val.compareTo(BigInteger.ZERO) != 0) {
|
||||
for (int n = 0; n < a.size(); n++) {
|
||||
resul.set(n, a.elementAt(n).multiply(val));
|
||||
}
|
||||
}
|
||||
return resul;
|
||||
} /* multiply */
|
||||
|
||||
/**
|
||||
* Multiply by another polynomial
|
||||
*
|
||||
* @param val
|
||||
* the other polynomial
|
||||
* @return the product of this with the other polynomial
|
||||
*/
|
||||
public BigIntegerPoly multiply(final BigIntegerPoly val) {
|
||||
final BigIntegerPoly resul = new BigIntegerPoly();
|
||||
/*
|
||||
* the degree of the result is the sum of the two degrees.
|
||||
*/
|
||||
final int nmax = degree() + val.degree();
|
||||
for (int n = 0; n <= nmax; n++) {
|
||||
BigInteger coef = BigInteger.ZERO;
|
||||
for (int nleft = 0; nleft <= n; nleft++) {
|
||||
coef = coef.add(at(nleft).multiply(val.at(n - nleft)));
|
||||
}
|
||||
resul.set(n, coef);
|
||||
}
|
||||
resul.simplify();
|
||||
return resul;
|
||||
} /* multiply */
|
||||
|
||||
/**
|
||||
* Raise to a positive power.
|
||||
*
|
||||
* @param n
|
||||
* the exponent of the power
|
||||
* @return the n-th power of this.
|
||||
*/
|
||||
public BigIntegerPoly pow(final int n) throws ArithmeticException {
|
||||
BigIntegerPoly resul = new BigIntegerPoly("1");
|
||||
if (n < 0) {
|
||||
throw new ArithmeticException("negative polynomial power " + n);
|
||||
} else {
|
||||
for (int i = 1; i <= n; i++) {
|
||||
resul = resul.multiply(this);
|
||||
}
|
||||
resul.simplify();
|
||||
return resul;
|
||||
}
|
||||
} /* pow */
|
||||
|
||||
/**
|
||||
* Add another polynomial
|
||||
*
|
||||
* @param val
|
||||
* the other polynomial
|
||||
* @return the sum of this with the other polynomial
|
||||
* @since 2010-08-27
|
||||
*/
|
||||
public BigIntegerPoly add(final BigIntegerPoly val) {
|
||||
final BigIntegerPoly resul = new BigIntegerPoly();
|
||||
/*
|
||||
* the degree of the result is the larger of the two degrees (before
|
||||
* simplify() at least).
|
||||
*/
|
||||
final int nmax = degree() > val.degree() ? degree() : val.degree();
|
||||
for (int n = 0; n <= nmax; n++) {
|
||||
final BigInteger coef = at(n).add(val.at(n));
|
||||
resul.set(n, coef);
|
||||
}
|
||||
resul.simplify();
|
||||
return resul;
|
||||
} /* add */
|
||||
|
||||
/**
|
||||
* Subtract another polynomial
|
||||
*
|
||||
* @param val
|
||||
* the other polynomial
|
||||
* @return the difference between this and the other polynomial
|
||||
* @since 2008-10-25
|
||||
*/
|
||||
public BigIntegerPoly subtract(final BigIntegerPoly val) {
|
||||
final BigIntegerPoly resul = new BigIntegerPoly();
|
||||
/*
|
||||
* the degree of the result is the larger of the two degrees (before
|
||||
* simplify() at least).
|
||||
*/
|
||||
final int nmax = degree() > val.degree() ? degree() : val.degree();
|
||||
for (int n = 0; n <= nmax; n++) {
|
||||
final BigInteger coef = at(n).subtract(val.at(n));
|
||||
resul.set(n, coef);
|
||||
}
|
||||
resul.simplify();
|
||||
return resul;
|
||||
} /* subtract */
|
||||
|
||||
/**
|
||||
* Divide by another polynomial.
|
||||
*
|
||||
* @param val
|
||||
* the other polynomial
|
||||
* @return A vector with [0] containg the polynomial of degree which is the
|
||||
* difference of the degree of this and the degree of val. [1] the
|
||||
* remainder polynomial.
|
||||
* This = returnvalue[0] + returnvalue[1]/val .
|
||||
* @since 2012-03-01
|
||||
*/
|
||||
public BigIntegerPoly[] divideAndRemainder(final BigIntegerPoly val) {
|
||||
final BigIntegerPoly[] ret = new BigIntegerPoly[2];
|
||||
/*
|
||||
* remove any high-order zeros. note that the clone() operation calls
|
||||
* simplify().
|
||||
*/
|
||||
final BigIntegerPoly valSimpl = val.clone();
|
||||
final BigIntegerPoly thisSimpl = clone();
|
||||
|
||||
/*
|
||||
* catch the case with val equal to zero
|
||||
*/
|
||||
if (valSimpl.degree() == 0 && valSimpl.a.firstElement().compareTo(BigInteger.ZERO) == 0) {
|
||||
throw new ArithmeticException("Division through zero polynomial");
|
||||
}
|
||||
/*
|
||||
* degree of this smaller than degree of val: remainder is this
|
||||
*/
|
||||
if (thisSimpl.degree() < valSimpl.degree()) {
|
||||
/*
|
||||
* leading polynomial equals zero
|
||||
*/
|
||||
ret[0] = new BigIntegerPoly();
|
||||
ret[1] = thisSimpl;
|
||||
} else {
|
||||
/*
|
||||
* long division. Highest degree by dividing the highest degree
|
||||
* of this thru val. At this point an exception is thrown if the
|
||||
* polynomial division cannot be done with integer coefficients.
|
||||
*/
|
||||
ret[0] = new BigIntegerPoly();
|
||||
final BigInteger[] newc = thisSimpl.a.lastElement().divideAndRemainder(valSimpl.a.lastElement());
|
||||
if (newc[1].compareTo(BigInteger.ZERO) != 0) {
|
||||
throw new ArithmeticException("Incompatible leading term in " + this + " / " + val);
|
||||
}
|
||||
ret[0].set(thisSimpl.degree() - valSimpl.degree(), newc[0]);
|
||||
|
||||
/*
|
||||
* recurrences: build this - val*(1-termresult) and feed this
|
||||
* into another round of division. Have intermediate
|
||||
* ret[0]+ret[1]/val.
|
||||
*/
|
||||
ret[1] = thisSimpl.subtract(ret[0].multiply(valSimpl));
|
||||
|
||||
/*
|
||||
* any remainder left ?
|
||||
*/
|
||||
if (ret[1].degree() < valSimpl.degree()) {
|
||||
;
|
||||
} else {
|
||||
final BigIntegerPoly rem[] = ret[1].divideAndRemainder(val);
|
||||
ret[0] = ret[0].add(rem[0]);
|
||||
ret[1] = rem[1];
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
} /* divideAndRemainder */
|
||||
|
||||
/**
|
||||
* Print as a comma-separated list of coefficients.
|
||||
*
|
||||
* @return the representation a0,a1,a2,a3,...
|
||||
* @since 2010-08-27
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = new String();
|
||||
for (int n = 0; n < a.size(); n++) {
|
||||
if (n == 0) {
|
||||
str += a.elementAt(n).toString();
|
||||
} else {
|
||||
str += "," + a.elementAt(n).toString();
|
||||
}
|
||||
}
|
||||
if (str.length() == 0) {
|
||||
str = "0";
|
||||
}
|
||||
return str;
|
||||
} /* toString */
|
||||
|
||||
/**
|
||||
* Print as a polyomial in x.
|
||||
*
|
||||
* @return The representation a0+a1*x+a2*x^2+...
|
||||
* The terms with zero coefficients are not mentioned.
|
||||
* @since 2008-10-26
|
||||
*/
|
||||
public String toPString() {
|
||||
String str = new String();
|
||||
for (int n = 0; n < a.size(); n++) {
|
||||
final BigInteger num = a.elementAt(n);
|
||||
if (num.compareTo(BigInteger.ZERO) != 0) {
|
||||
str += " ";
|
||||
if (num.compareTo(BigInteger.ZERO) > 0 && n > 0) {
|
||||
str += "+";
|
||||
}
|
||||
str += a.elementAt(n).toString();
|
||||
if (n > 0) {
|
||||
str += "*x";
|
||||
if (n > 1) {
|
||||
str += "^" + n;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (str.length() == 0) {
|
||||
str = "0";
|
||||
}
|
||||
return str;
|
||||
} /* toPString */
|
||||
|
||||
/**
|
||||
* Simplify the representation.
|
||||
* Trailing values with zero coefficients (at high powers) are deleted.
|
||||
*/
|
||||
protected void simplify() {
|
||||
int n = a.size() - 1;
|
||||
if (n >= 0) {
|
||||
while (a.elementAt(n).compareTo(BigInteger.ZERO) == 0) {
|
||||
a.removeElementAt(n);
|
||||
if (--n < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* simplify */
|
||||
|
||||
/**
|
||||
* First derivative.
|
||||
*
|
||||
* @return The first derivative with respect to the indeterminate variable.
|
||||
* @since 2008-10-26
|
||||
*/
|
||||
public BigIntegerPoly derive() {
|
||||
if (a.size() <= 1) {
|
||||
/*
|
||||
* derivative of the constant is just zero
|
||||
*/
|
||||
return new BigIntegerPoly();
|
||||
} else {
|
||||
final BigIntegerPoly d = new BigIntegerPoly();
|
||||
for (int i = 1; i <= degree(); i++) {
|
||||
final BigInteger c = a.elementAt(i).multiply(new BigInteger("" + i));
|
||||
d.set(i - 1, c);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
} /* derive */
|
||||
|
||||
/**
|
||||
* Truncate polynomial degree.
|
||||
*
|
||||
* @return The polynomial with all coefficients beyond deg set to zero.
|
||||
* @since 2010-08-27
|
||||
*/
|
||||
public BigIntegerPoly trunc(final int newdeg) {
|
||||
final BigIntegerPoly t = new BigIntegerPoly();
|
||||
for (int i = 0; i <= newdeg; i++) {
|
||||
t.set(i, at(i));
|
||||
}
|
||||
t.simplify();
|
||||
return t;
|
||||
} /* trunc */
|
||||
|
||||
/**
|
||||
* Inverse Binomial transform.
|
||||
*
|
||||
* @param maxdeg
|
||||
* the maximum polynomial degree of the result
|
||||
* @return the sequence of coefficients is the inverse binomial transform of
|
||||
* the original sequence.
|
||||
* @since 2010-08-29
|
||||
*/
|
||||
public BigIntegerPoly binomialTInv(final int maxdeg) {
|
||||
final BigIntegerPoly r = new BigIntegerPoly();
|
||||
for (int i = 0; i <= maxdeg; i++) {
|
||||
BigInteger c = BigInteger.ZERO;
|
||||
for (int j = 0; j <= i && j < a.size(); j++) {
|
||||
if ((j + i) % 2 != 0) {
|
||||
c = c.subtract(a.elementAt(j).multiply(BigIntegerMath.binomial(i, j)));
|
||||
} else {
|
||||
c = c.add(a.elementAt(j).multiply(BigIntegerMath.binomial(i, j)));
|
||||
}
|
||||
}
|
||||
r.set(i, c);
|
||||
}
|
||||
r.simplify();
|
||||
return r;
|
||||
} /* binomialTInv */
|
||||
|
||||
/**
|
||||
* Compute the order of the root r.
|
||||
*
|
||||
* @return 1 for simple roots, 2 for order 2 etc., 0 if not a root
|
||||
* @since 2010-08-27
|
||||
*/
|
||||
public int rootDeg(final BigInteger r) {
|
||||
int o = 0;
|
||||
BigIntegerPoly d = clone();
|
||||
BigInteger roo = d.valueOf(r);
|
||||
while (roo.compareTo(BigInteger.ZERO) == 0) {
|
||||
o++;
|
||||
d = d.derive();
|
||||
roo = d.valueOf(r);
|
||||
}
|
||||
return o;
|
||||
} /* rootDeg */
|
||||
|
||||
/**
|
||||
* Generate the integer roots of the polynomial.
|
||||
*
|
||||
* @return The vector of integer roots, without their multiplicity.
|
||||
* @since 2010-08-27
|
||||
*/
|
||||
public Vector<BigInteger> iroots() {
|
||||
/* The vector of the roots */
|
||||
final Vector<BigInteger> res = new Vector<>();
|
||||
|
||||
/*
|
||||
* collect the zero
|
||||
*/
|
||||
if (a.firstElement().compareTo(BigInteger.ZERO) == 0) {
|
||||
res.add(BigInteger.ZERO);
|
||||
}
|
||||
|
||||
/*
|
||||
* collect the divisors of the constant element (or the reduced
|
||||
* polynomial)
|
||||
*/
|
||||
final int l = ldegree();
|
||||
if (a.elementAt(l).compareTo(BigInteger.ZERO) != 0) {
|
||||
@SuppressWarnings("deprecation")
|
||||
final Vector<BigInteger> cand = BigIntegerMath.divisors(a.elementAt(l).abs());
|
||||
|
||||
/* check the divisors (both signs) */
|
||||
for (int i = 0; i < cand.size(); i++) {
|
||||
BigInteger roo = valueOf(cand.elementAt(i));
|
||||
if (roo.compareTo(BigInteger.ZERO) == 0) {
|
||||
/* found a root cand[i] */
|
||||
res.add(cand.elementAt(i));
|
||||
}
|
||||
roo = valueOf(cand.elementAt(i).negate());
|
||||
if (roo.compareTo(BigInteger.ZERO) == 0) {
|
||||
res.add(cand.elementAt(i).negate());
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
} /* iroots */
|
||||
|
||||
/**
|
||||
* Generate the factors which are 2nd degree polynomials.
|
||||
*
|
||||
* @return A (potentially empty) vector of factors, without multiplicity.
|
||||
* Only factors with non-zero absolute coefficient are generated.
|
||||
* This means the factors are of the form x^2+a*x+b=0 with nonzero
|
||||
* b.
|
||||
* @throws Error
|
||||
* @since 2012-03-01
|
||||
*/
|
||||
protected Vector<BigIntegerPoly> i2roots() throws Error {
|
||||
/*
|
||||
* The vector of the factors to be returned
|
||||
*/
|
||||
final Vector<BigIntegerPoly> res = new Vector<>();
|
||||
|
||||
if (degree() < 2) {
|
||||
return res;
|
||||
}
|
||||
|
||||
final BigInteger bsco = a.firstElement().abs();
|
||||
@SuppressWarnings("deprecation")
|
||||
final Vector<BigInteger> b = BigIntegerMath.divisors(bsco);
|
||||
final BigInteger csco = a.lastElement().abs();
|
||||
@SuppressWarnings("deprecation")
|
||||
final Vector<BigInteger> c = BigIntegerMath.divisors(csco);
|
||||
|
||||
/*
|
||||
* Generate the floating point values of roots. To have some reasonable
|
||||
* accuracy in the results, add zeros to the integer coefficients,
|
||||
* scaled
|
||||
* by the expected division with values of b (which are all <=
|
||||
* a.firstele).
|
||||
* Number of decimal digits in bsco by using a log2->log10 rough
|
||||
* estimate
|
||||
* and adding 6 safety digits
|
||||
*/
|
||||
final RatPoly thisDec = toRatPoly();
|
||||
final Vector<BigComplex> roo = thisDec.roots(6 + (int) (0.3 * bsco.bitCount()));
|
||||
|
||||
final BigDecimal half = new BigDecimal("0.5");
|
||||
|
||||
/*
|
||||
* for each of the roots z try to see whether c*z^2+a*z+b=0 with integer
|
||||
* a, b and c
|
||||
* where b is restricted to a signed divisor of the constant
|
||||
* coefficient.
|
||||
* 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 BigInteger bco : b) {
|
||||
for (final BigInteger cco : c) {
|
||||
/*
|
||||
* the major reason to avoid the case b=0 is that this would
|
||||
* require precaution of double counting below. Note that
|
||||
* this
|
||||
* case is already covered by using iroots().
|
||||
*/
|
||||
if (bco.signum() != 0) {
|
||||
for (int sig = -1; sig <= 1; sig += 2) {
|
||||
final BigInteger bcosig = sig > 0 ? bco : bco.negate();
|
||||
/*
|
||||
* -a = b/z+c*z has real part b*Re(z)/|z|^2+c*Re(z)
|
||||
* = Re z *( b/|z|^2+c)
|
||||
*/
|
||||
BigDecimal negA = BigDecimalMath.add(BigDecimalMath.divideRound(bcosig, z.norm()), cco);
|
||||
negA = negA.multiply(z.re);
|
||||
/*
|
||||
* convert to a with round-to-nearest
|
||||
*/
|
||||
final BigInteger a = negA.negate().add(half).toBigInteger();
|
||||
|
||||
/*
|
||||
* test the polynomial remainder. if zero, add the
|
||||
* term
|
||||
* to the results.
|
||||
*/
|
||||
final BigIntegerPoly dtst = new BigIntegerPoly("" + bcosig + "," + a + "," + cco);
|
||||
try {
|
||||
final BigIntegerPoly[] rm = divideAndRemainder(dtst);
|
||||
if (rm[1].isZero()) {
|
||||
res.add(dtst);
|
||||
}
|
||||
} catch (final ArithmeticException ex) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
} /* i2roots */
|
||||
|
||||
/**
|
||||
* Test whether this polynomial value is zero.
|
||||
*
|
||||
* @return If this is a polynomial p(x)=0 for all x.
|
||||
*/
|
||||
public boolean isZero() {
|
||||
simplify();
|
||||
return a.size() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factorization into integer polynomials.
|
||||
* The current factorization detects only factors which are polynomials of
|
||||
* order up to 2.
|
||||
*
|
||||
* @return The vector of factors. Factors with higher multiplicity are
|
||||
* represented by repetition.
|
||||
* @throws Error
|
||||
* @since 2012-03-01
|
||||
*/
|
||||
public Vector<BigIntegerPoly> ifactor() throws Error {
|
||||
/*
|
||||
* this ought be entirely rewritten in terms of the LLL algorithm
|
||||
*/
|
||||
final Vector<BigIntegerPoly> fac = new Vector<>();
|
||||
|
||||
/* collect integer roots (polynomial factors of degree 1) */
|
||||
final Vector<BigInteger> r = iroots();
|
||||
BigIntegerPoly[] res = new BigIntegerPoly[2];
|
||||
res[0] = this;
|
||||
for (final BigInteger i : r) {
|
||||
final int deg = rootDeg(i);
|
||||
/* construct the factor x-i */
|
||||
final BigIntegerPoly f = new BigIntegerPoly("" + i.negate() + ",1");
|
||||
for (int mu = 0; mu < deg; mu++) {
|
||||
fac.add(f);
|
||||
res = res[0].divideAndRemainder(f);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* collect factors which are polynomials of degree 2
|
||||
*/
|
||||
final Vector<BigIntegerPoly> pol2 = i2roots();
|
||||
for (final BigIntegerPoly i : pol2) {
|
||||
/*
|
||||
* the internal loop catches cases with higher
|
||||
* powers of individual polynomials (of actual degree 2 or 4...)
|
||||
*/
|
||||
while (res[0].degree() >= 2) {
|
||||
try {
|
||||
final BigIntegerPoly[] dtst = res[0].divideAndRemainder(i);
|
||||
if (dtst[1].isZero()) {
|
||||
fac.add(i);
|
||||
res = dtst;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} catch (final ArithmeticException ex) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* add remaining factor, if not equal to 1
|
||||
*/
|
||||
if (res[0].degree() > 0 || res[0].a.firstElement().compareTo(BigInteger.ONE) != 0) {
|
||||
fac.add(res[0]);
|
||||
}
|
||||
return fac;
|
||||
} /* ifactor */
|
||||
|
||||
} /* BigIntegerPoly */
|
@ -1,567 +0,0 @@
|
||||
package org.nevec.rjm;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.math.MathContext;
|
||||
import java.security.ProviderException;
|
||||
|
||||
import it.cavallium.warppi.util.Error;
|
||||
import it.cavallium.warppi.util.Utils;
|
||||
|
||||
/**
|
||||
* Square roots on the real line.
|
||||
* These represent numbers which are a product of a (signed) fraction by
|
||||
* a square root of a non-negative fraction.
|
||||
* This might be extended to values on the imaginary axis by allowing negative
|
||||
* values underneath the square root, but this is not yet implemented.
|
||||
*
|
||||
* @since 2011-02-12
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class BigSurd implements Cloneable, Comparable<BigSurd> {
|
||||
/**
|
||||
* The value of zero.
|
||||
*/
|
||||
static public BigSurd ZERO = new BigSurd();
|
||||
|
||||
/**
|
||||
* The value of one.
|
||||
*/
|
||||
static public BigSurd ONE = new BigSurd(Rational.ONE, Rational.ONE);
|
||||
/**
|
||||
* Prefactor
|
||||
*/
|
||||
Rational pref;
|
||||
|
||||
/**
|
||||
* The number underneath the square root, always non-negative.
|
||||
* The mathematical object has the value pref*sqrt(disc).
|
||||
*/
|
||||
Rational disc;
|
||||
|
||||
/**
|
||||
* Default ctor, which represents the zero.
|
||||
*
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd() {
|
||||
pref = Rational.ZERO;
|
||||
disc = Rational.ZERO;
|
||||
}
|
||||
|
||||
/**
|
||||
* ctor given the prefactor and the basis of the root.
|
||||
* This creates an object of value a*sqrt(b).
|
||||
*
|
||||
* @param a
|
||||
* the prefactor.
|
||||
* @param b
|
||||
* the discriminant.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd(final Rational a, final Rational b) {
|
||||
pref = a;
|
||||
/*
|
||||
* reject attempts to use a negative b
|
||||
*/
|
||||
if (b.signum() < 0) {
|
||||
throw new ProviderException("Not implemented: imaginary surds");
|
||||
}
|
||||
disc = b;
|
||||
try {
|
||||
normalize();
|
||||
normalizeG();
|
||||
} catch (final Error e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ctor given the numerator and denominator of the root.
|
||||
* This creates an object of value sqrt(a/b).
|
||||
*
|
||||
* @param a
|
||||
* the numerator
|
||||
* @param b
|
||||
* the denominator.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd(final int a, final int b) {
|
||||
this(Rational.ONE, new Rational(a, b));
|
||||
}
|
||||
|
||||
/**
|
||||
* ctor given the value under the root.
|
||||
* This creates an object of value sqrt(a).
|
||||
*
|
||||
* @param a
|
||||
* the discriminant.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd(final BigInteger a) {
|
||||
this(Rational.ONE, new Rational(a, BigInteger.ONE));
|
||||
}
|
||||
|
||||
public BigSurd(final Rational a) {
|
||||
this(Rational.ONE, a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a deep copy.
|
||||
*
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
@Override
|
||||
public BigSurd clone() {
|
||||
final Rational fclon = pref.clone();
|
||||
final Rational dclon = disc.clone();
|
||||
/*
|
||||
* the main intent here is to bypass any attempt to reduce the
|
||||
* discriminant
|
||||
* by figuring out the square-free part in normalize(), which has
|
||||
* already done
|
||||
* in the current copy of the number.
|
||||
*/
|
||||
final BigSurd cl = new BigSurd();
|
||||
cl.pref = fclon;
|
||||
cl.disc = dclon;
|
||||
return cl;
|
||||
} /* BigSurd.clone */
|
||||
|
||||
/**
|
||||
* Add two surds of compatible discriminant.
|
||||
*
|
||||
* @param val
|
||||
* The value to be added to this.
|
||||
*/
|
||||
|
||||
public BigSurdVec add(final BigSurd val) {
|
||||
// zero plus somethings yields something
|
||||
if (signum() == 0) {
|
||||
return new BigSurdVec(val);
|
||||
} else if (val.signum() == 0) {
|
||||
return new BigSurdVec(this);
|
||||
} else {
|
||||
// let the ctor of BigSurdVec to the work
|
||||
return new BigSurdVec(this, val);
|
||||
}
|
||||
} /* BigSurd.add */
|
||||
|
||||
/**
|
||||
* Multiply by another square root.
|
||||
*
|
||||
* @param val
|
||||
* a second number of this type.
|
||||
* @return the product of this with the val.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd multiply(final BigSurd val) {
|
||||
return new BigSurd(pref.multiply(val.pref), disc.multiply(val.disc));
|
||||
} /* BigSurd.multiply */
|
||||
|
||||
/**
|
||||
* Multiply by a rational number.
|
||||
*
|
||||
* @param val
|
||||
* the factor.
|
||||
* @return the product of this with the val.
|
||||
* @since 2011-02-15
|
||||
*/
|
||||
public BigSurd multiply(final Rational val) {
|
||||
return new BigSurd(pref.multiply(val), disc);
|
||||
} /* BigSurd.multiply */
|
||||
|
||||
/**
|
||||
* Multiply by a BigInteger.
|
||||
*
|
||||
* @param val
|
||||
* a second number.
|
||||
* @return the product of this with the value.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd multiply(final BigInteger val) {
|
||||
return new BigSurd(pref.multiply(val), disc);
|
||||
} /* BigSurd.multiply */
|
||||
|
||||
/**
|
||||
* Multiply by an integer.
|
||||
*
|
||||
* @param val
|
||||
* a second number.
|
||||
* @return the product of this with the value.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd multiply(final int val) {
|
||||
final BigInteger tmp = new BigInteger("" + val);
|
||||
return multiply(tmp);
|
||||
} /* BigSurd.multiply */
|
||||
|
||||
/**
|
||||
* Compute the square.
|
||||
*
|
||||
* @return this value squared.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public Rational sqr() {
|
||||
Rational res = pref.pow(2);
|
||||
res = res.multiply(disc);
|
||||
return res;
|
||||
} /* BigSurd.sqr */
|
||||
|
||||
/**
|
||||
* Divide by another square root.
|
||||
*
|
||||
* @param val
|
||||
* A second number of this type.
|
||||
* @return The value of this/val
|
||||
* @throws Error
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd divide(final BigSurd val) throws Error {
|
||||
if (val.signum() == 0) {
|
||||
throw new ArithmeticException("Dividing " + toFancyString() + " through zero.");
|
||||
}
|
||||
return new BigSurd(pref.divide(val.pref), disc.divide(val.disc));
|
||||
} /* BigSurd.divide */
|
||||
|
||||
private String toFancyString() {
|
||||
final BigSurd bs = this;
|
||||
final BigInteger denominator = pref.b;
|
||||
String s = "";
|
||||
if (denominator.compareTo(BigInteger.ONE) != 0) {
|
||||
s += "(";
|
||||
}
|
||||
if (bs.isBigInteger()) {
|
||||
s += bs.BigDecimalValue(new MathContext(Utils.scale, Utils.scaleMode2)).toBigInteger().toString();
|
||||
} else if (bs.isRational()) {
|
||||
s += bs.toRational().toString();
|
||||
} else {
|
||||
final BigInteger numerator = bs.pref.a;
|
||||
if (numerator.compareTo(BigInteger.ONE) != 0) {
|
||||
s += numerator.toString();
|
||||
s += "*";
|
||||
s += "(";
|
||||
}
|
||||
s += "2√";
|
||||
if (bs.disc.isInteger()) {
|
||||
s += bs.disc.toString();
|
||||
} else {
|
||||
s += "(" + bs.disc.toString() + ")";
|
||||
}
|
||||
if (numerator.compareTo(BigInteger.ONE) != 0) {
|
||||
s += ")";
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide by an integer.
|
||||
*
|
||||
* @param val
|
||||
* a second number.
|
||||
* @return the value of this/val
|
||||
* @throws Error
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd divide(final BigInteger val) throws Error {
|
||||
if (val.signum() == 0) {
|
||||
throw new ArithmeticException("Dividing " + toFancyString() + " through zero.");
|
||||
}
|
||||
return new BigSurd(pref.divide(val), disc);
|
||||
} /* BigSurd.divide */
|
||||
|
||||
/**
|
||||
* Divide by an integer.
|
||||
*
|
||||
* @param val
|
||||
* A second number.
|
||||
* @return The value of this/val
|
||||
* @throws Error
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd divide(final int val) throws Error {
|
||||
if (val == 0) {
|
||||
throw new ArithmeticException("Dividing " + toFancyString() + " through zero.");
|
||||
}
|
||||
return new BigSurd(pref.divide(val), disc);
|
||||
} /* BigSurd.divide */
|
||||
|
||||
/**
|
||||
* Compute the negative.
|
||||
*
|
||||
* @return -this.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd negate() {
|
||||
/*
|
||||
* This is trying to be quick, avoiding normalize(), by toggling
|
||||
* the sign in a clone()
|
||||
*/
|
||||
final BigSurd n = clone();
|
||||
n.pref = n.pref.negate();
|
||||
return n;
|
||||
} /* BigSurd.negate */
|
||||
|
||||
/**
|
||||
* Absolute value.
|
||||
*
|
||||
* @return The absolute (non-negative) value of this.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurd abs() {
|
||||
return new BigSurd(pref.abs(), disc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the value of this with another constant.
|
||||
*
|
||||
* @param val
|
||||
* the other constant to compare with
|
||||
* @return -1, 0 or 1 if this number is numerically less than, equal to,
|
||||
* or greater than val.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(final BigSurd val) {
|
||||
/*
|
||||
* Since we keep the discriminant positive, the rough estimate
|
||||
* comes from comparing the signs of the prefactors.
|
||||
*/
|
||||
final int sig = signum();
|
||||
final int sigv = val.signum();
|
||||
if (sig < 0 && sigv >= 0) {
|
||||
return -1;
|
||||
}
|
||||
if (sig > 0 && sigv <= 0) {
|
||||
return 1;
|
||||
}
|
||||
if (sig == 0 && sigv == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (sig == 0 && sigv > 0) {
|
||||
return -1;
|
||||
}
|
||||
if (sig == 0 && sigv < 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Work out the cases of equal sign. Compare absolute values by
|
||||
* comparison
|
||||
* of the squares which is forwarded to the comparison of the Rational
|
||||
* class.
|
||||
*/
|
||||
final Rational this2 = sqr();
|
||||
final Rational val2 = val.sqr();
|
||||
final int c = this2.compareTo(val2);
|
||||
if (c == 0) {
|
||||
return 0;
|
||||
} else if (sig > 0 && c > 0 || sig < 0 && c < 0) {
|
||||
return 1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} /* BigSurd.compareTo */
|
||||
|
||||
/**
|
||||
* Return a string in the format (number/denom)*()^(1/2).
|
||||
* If the discriminant equals 1, print just the prefactor.
|
||||
*
|
||||
* @return the human-readable version in base 10
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
if (disc.compareTo(Rational.ONE) != 0 && disc.compareTo(Rational.ZERO) != 0) {
|
||||
return "(" + pref.toString() + ")*(" + disc.toString() + ")^(1/2)";
|
||||
} else {
|
||||
return pref.toString();
|
||||
}
|
||||
} /* BigSurd.toString */
|
||||
|
||||
/**
|
||||
* Return a double value representation.
|
||||
*
|
||||
* @return The value with double precision.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public double doubleValue() {
|
||||
/*
|
||||
* First compute the square to prevent overflows if the two pieces of
|
||||
* the prefactor and the discriminant are of very different magnitude.
|
||||
*/
|
||||
final Rational p2 = pref.pow(2).multiply(disc);
|
||||
System.out.println("dv sq " + p2.toString());
|
||||
final double res = p2.doubleValue();
|
||||
System.out.println("dv sq " + res);
|
||||
return pref.signum() >= 0 ? Math.sqrt(res) : -Math.sqrt(res);
|
||||
} /* BigSurd.doubleValue */
|
||||
|
||||
/**
|
||||
* Return a float value representation.
|
||||
*
|
||||
* @return The value with single precision.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public float floatValue() {
|
||||
return (float) doubleValue();
|
||||
} /* BigSurd.floatValue */
|
||||
|
||||
/**
|
||||
* True if the value is integer.
|
||||
* Equivalent to the indication whether a conversion to an integer
|
||||
* can be exact.
|
||||
*
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public boolean isBigInteger() {
|
||||
return pref.isBigInteger() && (disc.signum() == 0 || disc.compareTo(Rational.ONE) == 0);
|
||||
} /* BigSurd.isBigInteger */
|
||||
|
||||
/**
|
||||
* True if the value is rational.
|
||||
* Equivalent to the indication whether a conversion to a Rational can be
|
||||
* exact.
|
||||
*
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public boolean isRational() {
|
||||
return disc.signum() == 0 || disc.compareTo(Rational.ONE) == 0;
|
||||
} /* BigSurd.isRational */
|
||||
|
||||
/**
|
||||
* Convert to a rational value if possible
|
||||
*
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
public Rational toRational() {
|
||||
if (isRational()) {
|
||||
return pref;
|
||||
} else {
|
||||
throw new ArithmeticException("Undefined conversion " + toFancyString() + " to Rational.");
|
||||
}
|
||||
} /* BigSurd.toRational */
|
||||
|
||||
/**
|
||||
* The sign: 1 if the number is >0, 0 if ==0, -1 if <0
|
||||
*
|
||||
* @return the signum of the value.
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public int signum() {
|
||||
/*
|
||||
* Since the disc is kept positive, this is the same
|
||||
* as the sign of the prefactor. This works because a zero discriminant
|
||||
* is always copied over to the prefactor, not hidden.
|
||||
*/
|
||||
return pref.signum();
|
||||
} /* BigSurd.signum */
|
||||
|
||||
/**
|
||||
* Normalize to squarefree discriminant.
|
||||
*
|
||||
* @throws Error
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
protected void normalize() throws Error {
|
||||
/*
|
||||
* Move squares out of the numerator and denominator of the discriminant
|
||||
*/
|
||||
if (disc.signum() != 0) {
|
||||
/*
|
||||
* square-free part of the numerator: numer = numC*some^2
|
||||
*/
|
||||
final BigInteger numC = BigIntegerMath.core(disc.numer());
|
||||
/*
|
||||
* extract the perfect square of the numerator
|
||||
*/
|
||||
BigInteger sq = disc.numer().divide(numC);
|
||||
/*
|
||||
* extract the associated square root
|
||||
*/
|
||||
BigInteger sqf = BigIntegerMath.isqrt(sq);
|
||||
|
||||
/*
|
||||
* move sqf over to the pre-factor
|
||||
*/
|
||||
pref = pref.multiply(sqf);
|
||||
|
||||
final BigInteger denC = BigIntegerMath.core(disc.denom());
|
||||
sq = disc.denom().divide(denC);
|
||||
sqf = BigIntegerMath.isqrt(sq);
|
||||
pref = pref.divide(sqf);
|
||||
|
||||
disc = new Rational(numC, denC);
|
||||
} else {
|
||||
pref = Rational.ZERO;
|
||||
}
|
||||
} /* BigSurd.normalize */
|
||||
|
||||
/**
|
||||
* Normalize to coprime numerator and denominator in prefactor and
|
||||
* discriminant
|
||||
*
|
||||
* @throws Error
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
protected void normalizeG() throws Error {
|
||||
/*
|
||||
* Is there a common factor between the numerator of the prefactor
|
||||
* and the denominator of the discriminant ?
|
||||
*/
|
||||
BigInteger d = pref.numer().abs().gcd(disc.denom());
|
||||
if (d.compareTo(BigInteger.ONE) > 0) {
|
||||
pref = pref.divide(d);
|
||||
/*
|
||||
* instead of multiplying with the square of d, using two steps
|
||||
* offers a change to recognize the common factor..
|
||||
*/
|
||||
disc = disc.multiply(d);
|
||||
disc = disc.multiply(d);
|
||||
}
|
||||
/*
|
||||
* Is there a common factor between the denominator of the prefactor
|
||||
* and the numerator of the discriminant ?
|
||||
*/
|
||||
d = pref.denom().gcd(disc.numer());
|
||||
if (d.compareTo(BigInteger.ONE) > 0) {
|
||||
pref = pref.multiply(d);
|
||||
/*
|
||||
* instead of dividing through the square of d, using two steps
|
||||
* offers a change to recognize the common factor..
|
||||
*/
|
||||
disc = disc.divide(d);
|
||||
disc = disc.divide(d);
|
||||
}
|
||||
} /* BigSurd.normalizeG */
|
||||
|
||||
/**
|
||||
* Return the approximate floating point representation.
|
||||
*
|
||||
* @param mc
|
||||
* Description of the accuracy needed.
|
||||
* @return A representation with digits valid as described by mc
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
public BigDecimal BigDecimalValue(final MathContext mc) {
|
||||
/*
|
||||
* the relative error of the result equals the relative error of the
|
||||
* prefactor plus half of the relative error of the discriminant.
|
||||
* So adding 3 digits temporarily is sufficient.
|
||||
*/
|
||||
final MathContext locmc = new MathContext(mc.getPrecision() + 3, mc.getRoundingMode());
|
||||
/*
|
||||
* first the square root of the discriminant
|
||||
*/
|
||||
final BigDecimal sqrdis = BigDecimalMath.sqrt(disc.BigDecimalValue(locmc), locmc);
|
||||
/*
|
||||
* Then multiply by the prefactor. If sqrdis is a terminating decimal
|
||||
* fraction,
|
||||
* we prevent early truncation of the result by truncating later.
|
||||
*/
|
||||
final BigDecimal res = sqrdis.multiply(pref.BigDecimalValue(mc));
|
||||
return BigDecimalMath.scalePrec(res, mc);
|
||||
} /* BigDecimalValue */
|
||||
|
||||
} /* BigSurd */
|
@ -1,650 +0,0 @@
|
||||
package org.nevec.rjm;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.math.MathContext;
|
||||
import java.util.Vector;
|
||||
|
||||
import it.cavallium.warppi.util.Error;
|
||||
import it.cavallium.warppi.util.Utils;
|
||||
|
||||
/**
|
||||
* A BigSurdVec represents an algebraic sum or differences of values which each
|
||||
* term an instance of BigSurd. This mainly means that sums or differences of
|
||||
* two BigSurd (or two BigSurdVec) can be represented (exactly) as a BigSurdVec.
|
||||
*
|
||||
* @since 2012-02-15
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class BigSurdVec implements Comparable<BigSurdVec> {
|
||||
/**
|
||||
* The value of zero.
|
||||
*/
|
||||
static public BigSurdVec ZERO = new BigSurdVec();
|
||||
|
||||
/**
|
||||
* The value of one.
|
||||
*/
|
||||
static public BigSurdVec ONE = new BigSurdVec(BigSurd.ONE);
|
||||
|
||||
/**
|
||||
* Internal representation: Each term as a single BigSurd. The value zero is
|
||||
* represented by an empty vector.
|
||||
*/
|
||||
Vector<BigSurd> terms;
|
||||
|
||||
/**
|
||||
* Default ctor, which represents the zero.
|
||||
*
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
public BigSurdVec() {
|
||||
terms = new Vector<>();
|
||||
} /* ctor */
|
||||
|
||||
/**
|
||||
* ctor given the value of a BigSurd.
|
||||
*
|
||||
* @param a
|
||||
* The value to be represented by this vector.
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
public BigSurdVec(final BigSurd a) {
|
||||
terms = new Vector<>(1);
|
||||
terms.add(a);
|
||||
} /* ctor */
|
||||
|
||||
/**
|
||||
* ctor given two values, which (when added) represent this number a+b.
|
||||
*
|
||||
* @param a
|
||||
* The value to be represented by the first term of the vector.
|
||||
* @param b
|
||||
* The value to be represented by the second term of the vector.
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
public BigSurdVec(final BigSurd a, final BigSurd b) {
|
||||
terms = new Vector<>(2);
|
||||
terms.add(a);
|
||||
terms.add(b);
|
||||
try {
|
||||
normalize();
|
||||
} catch (final Error e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
} /* ctor */
|
||||
|
||||
/**
|
||||
* Combine terms that can be written as a single surd. This unites for
|
||||
* example the terms sqrt(90) and sqrt(10) to 4*sqrt(10).
|
||||
*
|
||||
* @throws Error
|
||||
*
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
protected void normalize() throws Error {
|
||||
/*
|
||||
* nothing to be done if at most one term
|
||||
*/
|
||||
if (terms.size() <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Vector<BigSurd> newter = new Vector<>();
|
||||
newter.add(terms.firstElement());
|
||||
/*
|
||||
* add j-th element to the existing vector and combine were possible
|
||||
*/
|
||||
for (int j = 1; j < terms.size(); j++) {
|
||||
final BigSurd todo = terms.elementAt(j);
|
||||
boolean merged = false;
|
||||
for (int ex = 0; ex < newter.size(); ex++) {
|
||||
BigSurd v = newter.elementAt(ex);
|
||||
/*
|
||||
* try to merge terms[j] and newter[ex]. todo = r * v with r a
|
||||
* rational number is needed. Replaces v with v+todo = v*(1+r)
|
||||
* if this reduction works.
|
||||
*/
|
||||
final BigSurd r = todo.divide(v);
|
||||
if (r.isRational()) {
|
||||
/* compute r+1 */
|
||||
final Rational newpref = r.toRational().add(1);
|
||||
/*
|
||||
* eliminate accidental zeros; overwrite with v*(1+r).
|
||||
*/
|
||||
if (newpref.compareTo(Rational.ZERO) == 0) {
|
||||
newter.removeElementAt(ex);
|
||||
} else {
|
||||
v = v.multiply(newpref);
|
||||
newter.setElementAt(v, ex);
|
||||
}
|
||||
merged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* append if none of the existing elements matched
|
||||
*/
|
||||
if (!merged) {
|
||||
newter.add(todo);
|
||||
}
|
||||
}
|
||||
|
||||
/* overwrite old version */
|
||||
terms = newter;
|
||||
} /* normalize */
|
||||
|
||||
/**
|
||||
* Compare algebraic value with oth. Returns -1, 0 or +1 depending on
|
||||
* whether this is smaller, equal to or larger than oth.
|
||||
*
|
||||
* @param oth
|
||||
* The value with which this is to be compared.
|
||||
* @return 0 or +-1.
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(final BigSurdVec oth) {
|
||||
BigSurdVec diff;
|
||||
try {
|
||||
diff = this.subtract(oth);
|
||||
return diff.signum();
|
||||
} catch (final Error e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
} /* compareTo */
|
||||
|
||||
/**
|
||||
* Sign function. Returns -1, 0 or +1 depending on whether this is smaller,
|
||||
* equal to or larger than zero.
|
||||
*
|
||||
* @return 0 or +-1.
|
||||
* @throws Error
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
public int signum() throws Error {
|
||||
/*
|
||||
* the case of zero is unique, because no (reduced) vector of surds
|
||||
* other than the one element 0 itself can add/subtract to zero.
|
||||
*/
|
||||
if (terms.size() == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* if there is one term: forward to the signum function of BigSurd
|
||||
*/
|
||||
if (terms.size() == 1) {
|
||||
return terms.firstElement().signum();
|
||||
}
|
||||
|
||||
/*
|
||||
* if all terms have a common sign: take that one offsig is the index of
|
||||
* the first "offending" term in the sense that its sign doese not agree
|
||||
* with the term[0].
|
||||
*/
|
||||
final int sig0 = terms.elementAt(0).signum();
|
||||
int offsig = 1;
|
||||
for (; offsig < terms.size(); offsig++) {
|
||||
if (terms.elementAt(offsig).signum() != sig0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (offsig >= terms.size()) {
|
||||
return sig0;
|
||||
}
|
||||
|
||||
/*
|
||||
* if there are two terms (now known to have different sign): forward to
|
||||
* the comparison of the two elements as BigSurds
|
||||
*/
|
||||
if (terms.size() == 2) {
|
||||
return terms.elementAt(0).compareTo(terms.elementAt(1).negate());
|
||||
}
|
||||
|
||||
/*
|
||||
* if there are three terms, move the one with the offending sign to the
|
||||
* other side and square both sides (which looses the sign) to remove
|
||||
* all but one surds. The difference of the squared sides contains at
|
||||
* most two terms, which reduces to the case above. t(0)+t(offbar) <>
|
||||
* -t(offs)
|
||||
*/
|
||||
if (terms.size() == 3) {
|
||||
BigSurdVec lhs;
|
||||
if (offsig == 2) {
|
||||
lhs = new BigSurdVec(terms.elementAt(0), terms.elementAt(1));
|
||||
} else {
|
||||
lhs = new BigSurdVec(terms.elementAt(0), terms.elementAt(2));
|
||||
}
|
||||
lhs = lhs.sqr();
|
||||
/*
|
||||
* Strange line: this line isn't used, but it's present in this
|
||||
* code!
|
||||
*
|
||||
*
|
||||
*
|
||||
* BigSurd rhs = new BigSurd(terms.elementAt(offsig).sqr(),
|
||||
* Rational.ONE);
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
if (lhs.compareTo(lhs) > 0) {
|
||||
/*
|
||||
* dominating sign was t(0)+t(offbar)
|
||||
*/
|
||||
return terms.elementAt(0).signum();
|
||||
} else {
|
||||
return terms.elementAt(offsig).signum();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* for a larger number of terms: take a floating point representation
|
||||
* with a small but correct number of digits, and resume with the sign
|
||||
* of that one.
|
||||
*/
|
||||
return floatValue() > 0. ? 1 : -1;
|
||||
|
||||
} /* signum */
|
||||
|
||||
/**
|
||||
* Construct an approximate floating point representation
|
||||
*
|
||||
* @param mc
|
||||
* The intended accuracy of the result.
|
||||
* @return A truncated version with the precision described by mc
|
||||
*/
|
||||
public BigDecimal BigDecimalValue(final MathContext mc) {
|
||||
/*
|
||||
* simple cases with one term forwarded to the BigSurd class
|
||||
*/
|
||||
if (terms.size() == 0) {
|
||||
return BigDecimal.ZERO;
|
||||
} else if (terms.size() == 1) {
|
||||
return terms.firstElement().BigDecimalValue(mc);
|
||||
}
|
||||
|
||||
/*
|
||||
* To reduce cancellation errors, loop over increasing local precision
|
||||
* until we are stable to the required result. Keep the old (less
|
||||
* precise) estimate in res[0], and the newer, more precise in res[1].
|
||||
*/
|
||||
final BigDecimal[] res = new BigDecimal[2];
|
||||
res[0] = BigDecimal.ZERO;
|
||||
for (int addpr = 1;; addpr += 3) {
|
||||
final MathContext locmc = new MathContext(mc.getPrecision() + addpr, mc.getRoundingMode());
|
||||
res[1] = BigDecimal.ZERO;
|
||||
for (final BigSurd j : terms) {
|
||||
res[1] = BigDecimalMath.addRound(res[1], j.BigDecimalValue(locmc));
|
||||
}
|
||||
if (addpr > 1) {
|
||||
final BigDecimal err = res[1].subtract(res[0]).abs();
|
||||
final int prec = BigDecimalMath.err2prec(res[1], err);
|
||||
if (prec > mc.getPrecision()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
res[0] = res[1];
|
||||
}
|
||||
return BigDecimalMath.scalePrec(res[1], mc);
|
||||
|
||||
} /* BigDecimalValue */
|
||||
|
||||
/**
|
||||
* Construct an approximate floating point representation
|
||||
*
|
||||
* @return A truncated version with the precision described by mc
|
||||
*/
|
||||
public double doubleValue() {
|
||||
final BigDecimal bd = BigDecimalValue(MathContext.DECIMAL128);
|
||||
return bd.doubleValue();
|
||||
} /* doubleValue */
|
||||
|
||||
/**
|
||||
* Construct an approximate floating point representation
|
||||
*
|
||||
* @return A truncated version with the precision described by mc
|
||||
*/
|
||||
public double floatValue() {
|
||||
final BigDecimal bd = BigDecimalValue(MathContext.DECIMAL64);
|
||||
return bd.floatValue();
|
||||
} /* floatValue */
|
||||
|
||||
/**
|
||||
* Add two vectors algebraically.
|
||||
*
|
||||
* @param val
|
||||
* The value to be added to this.
|
||||
* @return The new value representing this+val.
|
||||
* @throws Error
|
||||
*/
|
||||
public BigSurdVec add(final BigSurdVec val) throws Error {
|
||||
final BigSurdVec sum = new BigSurdVec();
|
||||
/*
|
||||
* concatenate the vectors and eliminate common overlaps
|
||||
*/
|
||||
for (final BigSurd term : terms) {
|
||||
if (term.compareTo(BigSurd.ZERO) != 0) {
|
||||
sum.terms.add(term);
|
||||
}
|
||||
}
|
||||
for (final BigSurd term : val.terms) {
|
||||
if (term.compareTo(BigSurd.ZERO) != 0) {
|
||||
sum.terms.add(term);
|
||||
}
|
||||
}
|
||||
sum.normalize();
|
||||
return sum;
|
||||
} /* add */
|
||||
|
||||
/**
|
||||
* Add two vectors algebraically.
|
||||
*
|
||||
* @param val
|
||||
* The value to be added to this.
|
||||
* @return The new value representing this+val.
|
||||
* @throws Error
|
||||
*/
|
||||
public BigSurdVec add(final BigSurd val) throws Error {
|
||||
final BigSurdVec sum = new BigSurdVec();
|
||||
/*
|
||||
* concatenate the vectors and eliminate common overlaps
|
||||
*/
|
||||
sum.terms.addAll(terms);
|
||||
sum.terms.add(val);
|
||||
sum.normalize();
|
||||
return sum;
|
||||
} /* add */
|
||||
|
||||
/**
|
||||
* Subtract another number.
|
||||
*
|
||||
* @param val
|
||||
* The value to be subtracted from this.
|
||||
* @return The new value representing this-val.
|
||||
* @throws Error
|
||||
*/
|
||||
public BigSurdVec subtract(final BigSurdVec val) throws Error {
|
||||
final BigSurdVec sum = new BigSurdVec();
|
||||
/*
|
||||
* concatenate the vectors and eliminate common overlaps
|
||||
*/
|
||||
sum.terms.addAll(terms);
|
||||
for (final BigSurd s : val.terms) {
|
||||
sum.terms.add(s.negate());
|
||||
}
|
||||
sum.normalize();
|
||||
return sum;
|
||||
} /* subtract */
|
||||
|
||||
/**
|
||||
* Subtract another number.
|
||||
*
|
||||
* @param val
|
||||
* The value to be subtracted from this.
|
||||
* @return The new value representing this-val.
|
||||
* @throws Error
|
||||
*/
|
||||
public BigSurdVec subtract(final BigSurd val) throws Error {
|
||||
final BigSurdVec sum = new BigSurdVec();
|
||||
/*
|
||||
* concatenate the vectors and eliminate common overlaps
|
||||
*/
|
||||
sum.terms.addAll(terms);
|
||||
sum.terms.add(val.negate());
|
||||
sum.normalize();
|
||||
return sum;
|
||||
} /* subtract */
|
||||
|
||||
/**
|
||||
* Compute the negative.
|
||||
*
|
||||
* @return -this.
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
public BigSurdVec negate() {
|
||||
/*
|
||||
* accumulate the negated elements of term one by one
|
||||
*/
|
||||
final BigSurdVec resul = new BigSurdVec();
|
||||
for (final BigSurd s : terms) {
|
||||
resul.terms.add(s.negate());
|
||||
}
|
||||
/*
|
||||
* no normalization step here, because the negation of all terms does
|
||||
* not introduce new common factors
|
||||
*/
|
||||
return resul;
|
||||
} /* negate */
|
||||
|
||||
/**
|
||||
* Compute the square.
|
||||
*
|
||||
* @return this value squared.
|
||||
* @throws Error
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
public BigSurdVec sqr() throws Error {
|
||||
/*
|
||||
* Binomial expansion. First the sum of the terms squared, then 2 times
|
||||
* the mixed products.
|
||||
*/
|
||||
final BigSurdVec resul = new BigSurdVec();
|
||||
for (int i = 0; i < terms.size(); i++) {
|
||||
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++) {
|
||||
resul.terms.add(terms.elementAt(i).multiply(terms.elementAt(j)).multiply(2));
|
||||
}
|
||||
}
|
||||
resul.normalize();
|
||||
return resul;
|
||||
} /* sqr */
|
||||
|
||||
/**
|
||||
* Multiply by another square root.
|
||||
*
|
||||
* @param val
|
||||
* a second number of this type.
|
||||
* @return the product of this with the val.
|
||||
* @throws Error
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public BigSurdVec multiply(final BigSurd val) throws Error {
|
||||
final BigSurdVec resul = new BigSurdVec();
|
||||
for (final BigSurd s : terms) {
|
||||
resul.terms.add(s.multiply(val));
|
||||
}
|
||||
resul.normalize();
|
||||
return resul;
|
||||
} /* multiply */
|
||||
|
||||
public BigSurdVec multiply(final BigSurdVec val) throws Error {
|
||||
BigSurdVec resul = new BigSurdVec();
|
||||
for (final BigSurd s : terms) {
|
||||
resul.terms.add(s);
|
||||
}
|
||||
for (final BigSurd s : val.terms) {
|
||||
resul = resul.multiply(s);
|
||||
}
|
||||
return resul;
|
||||
} /* multiply */
|
||||
|
||||
public BigSurdVec divide(final BigSurd val) throws Error {
|
||||
final BigSurdVec resul = new BigSurdVec();
|
||||
for (final BigSurd s : terms) {
|
||||
resul.terms.add(s.divide(val));
|
||||
}
|
||||
resul.normalize();
|
||||
return resul;
|
||||
} /* multiply */
|
||||
|
||||
public BigSurdVec divide(final BigSurdVec val) throws Error {
|
||||
BigSurdVec resul = new BigSurdVec();
|
||||
resul.terms = terms;
|
||||
for (final BigSurd s : val.terms) {
|
||||
resul = resul.divide(s);
|
||||
}
|
||||
return resul;
|
||||
} /* divide */
|
||||
|
||||
/**
|
||||
* True if the value is rational. Equivalent to the indication whether a
|
||||
* conversion to a Rational can be exact.
|
||||
*
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public boolean isRational() {
|
||||
boolean val = false;
|
||||
for (final BigSurd s : terms) {
|
||||
val = s.isRational();
|
||||
if (val == false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return val;
|
||||
} /* BigSurdVec.isRational */
|
||||
|
||||
/**
|
||||
* True if the value is BigInteger. Equivalent to the indication whether a
|
||||
* conversion to a BigInteger can be exact.
|
||||
*
|
||||
* @since 2011-02-12
|
||||
*/
|
||||
public boolean isBigInteger() {
|
||||
boolean val = false;
|
||||
for (final BigSurd s : terms) {
|
||||
val = s.isBigInteger();
|
||||
if (val == false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return val;
|
||||
} /* BigSurdVec.isRational */
|
||||
|
||||
/**
|
||||
* Convert to a rational value if possible
|
||||
*
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
public Rational toRational() {
|
||||
Rational rat = Rational.ZERO;
|
||||
if (isRational() == false) {
|
||||
throw new ArithmeticException("Undefined conversion " + toString() + " to Rational.");
|
||||
}
|
||||
for (final BigSurd s : terms) {
|
||||
rat = rat.add(s.pref);
|
||||
}
|
||||
return rat;
|
||||
} /* BigSurd.toRational */
|
||||
|
||||
/**
|
||||
* Convert to a BigInteger value if possible
|
||||
*
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
public BigInteger toBigInteger() {
|
||||
BigDecimal tmp = BigDecimal.ZERO.setScale(Utils.scale, Utils.scaleMode);
|
||||
if (isBigInteger() == false) {
|
||||
throw new ArithmeticException("Undefined conversion " + toString() + " to Rational.");
|
||||
}
|
||||
for (final BigSurd s : terms) {
|
||||
tmp = BigDecimalMath.addRound(tmp, s.pref.BigDecimalValue(new MathContext(Utils.scale, Utils.scaleMode2)));
|
||||
}
|
||||
return tmp.toBigInteger();
|
||||
} /* BigSurd.toRational */
|
||||
|
||||
/**
|
||||
* Convert to a BigDecimal value if possible
|
||||
*
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
public BigDecimal toBigDecimal() {
|
||||
BigDecimal tmp = BigDecimal.ZERO.setScale(Utils.scale, Utils.scaleMode);
|
||||
for (final BigSurd s : terms) {
|
||||
tmp = BigDecimalMath.addRound(tmp, s.BigDecimalValue(new MathContext(Utils.scale, Utils.scaleMode2)));
|
||||
}
|
||||
return tmp;
|
||||
} /* BigSurd.toBigDecimal */
|
||||
|
||||
/**
|
||||
* Return a string in the format (number/denom)*()^(1/2). If the
|
||||
* discriminant equals 1, print just the prefactor.
|
||||
*
|
||||
* @return the human-readable version in base 10
|
||||
* @since 2012-02-16
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
/*
|
||||
* simple cases with one term forwarded to the BigSurd class
|
||||
*/
|
||||
if (terms.size() == 0) {
|
||||
return new String("0");
|
||||
} else {
|
||||
String s = new String();
|
||||
for (int t = 0; t < terms.size(); t++) {
|
||||
final BigSurd bs = terms.elementAt(t);
|
||||
if (bs.signum() > 0) {
|
||||
s += "+";
|
||||
}
|
||||
s += bs.toString();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
} /* toString */
|
||||
|
||||
public String toFancyString() {
|
||||
if (terms.size() == 0) {
|
||||
return new String("0");
|
||||
} else {
|
||||
BigInteger denominator = BigInteger.ONE;
|
||||
for (int i = 0; i < terms.size(); i++) {
|
||||
denominator = denominator.multiply(terms.elementAt(i).pref.b);
|
||||
}
|
||||
String s = "";
|
||||
if (denominator.compareTo(BigInteger.ONE) != 0) {
|
||||
s += "(";
|
||||
}
|
||||
for (int t = 0; t < terms.size(); t++) {
|
||||
final BigSurd bs = terms.elementAt(t);
|
||||
if (bs.signum() > 0 && t > 0) {
|
||||
s += "+";
|
||||
}
|
||||
if (bs.isBigInteger()) {
|
||||
s += bs.BigDecimalValue(new MathContext(Utils.scale, Utils.scaleMode2)).toBigInteger().toString();
|
||||
} else if (bs.isRational()) {
|
||||
s += bs.toRational().toString();
|
||||
} else {
|
||||
final BigInteger numerator = bs.pref.multiply(denominator).numer();
|
||||
if (numerator.compareTo(BigInteger.ONE) != 0) {
|
||||
s += numerator.toString();
|
||||
s += "*";
|
||||
// s += "("; Radice quadrata. non servono le parentesi.
|
||||
}
|
||||
s += "Ⓐ";
|
||||
if (bs.disc.isInteger()) {
|
||||
s += bs.disc.toString();
|
||||
} else {
|
||||
s += "(" + bs.disc.toString() + ")";
|
||||
}
|
||||
if (numerator.compareTo(BigInteger.ONE) != 0) {
|
||||
// s += ")"; Radice quadrata. non servono le parentesi.
|
||||
}
|
||||
}
|
||||
}
|
||||
if (denominator.compareTo(BigInteger.ONE) != 0) {
|
||||
s += ")";
|
||||
s += "/";
|
||||
s += denominator;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
} /* BigSurdVec */
|
@ -1,73 +0,0 @@
|
||||
package org.nevec.rjm;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* Euler numbers
|
||||
*
|
||||
* @see <a href="http://oeis.org/A000364">A000364</a> in the OEIS.
|
||||
* @since 2008-10-30
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class Euler {
|
||||
/*
|
||||
* The list of all Euler numbers as a vector, n=0,2,4,....
|
||||
*/
|
||||
static protected Vector<BigInteger> a = new Vector<>();
|
||||
|
||||
/**
|
||||
* Ctor(). Fill the hash list initially with E_0 to E_3.
|
||||
*/
|
||||
public Euler() {
|
||||
if (Euler.a.size() == 0) {
|
||||
Euler.a.add(BigInteger.ONE);
|
||||
Euler.a.add(BigInteger.ONE);
|
||||
Euler.a.add(new BigInteger("5"));
|
||||
Euler.a.add(new BigInteger("61"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute a coefficient in the internal table.
|
||||
*
|
||||
* @param n
|
||||
* the zero-based index of the coefficient. n=0 for the E_0 term.
|
||||
*/
|
||||
protected void set(final int n) {
|
||||
while (n >= Euler.a.size()) {
|
||||
BigInteger val = BigInteger.ZERO;
|
||||
boolean sigPos = true;
|
||||
final int thisn = Euler.a.size();
|
||||
for (int i = thisn - 1; i > 0; i--) {
|
||||
BigInteger f = new BigInteger("" + Euler.a.elementAt(i).toString());
|
||||
f = f.multiply(BigIntegerMath.binomial(2 * thisn, 2 * i));
|
||||
if (sigPos) {
|
||||
val = val.add(f);
|
||||
} else {
|
||||
val = val.subtract(f);
|
||||
}
|
||||
sigPos = !sigPos;
|
||||
}
|
||||
if (thisn % 2 == 0) {
|
||||
val = val.subtract(BigInteger.ONE);
|
||||
} else {
|
||||
val = val.add(BigInteger.ONE);
|
||||
}
|
||||
Euler.a.add(val);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The Euler number at the index provided.
|
||||
*
|
||||
* @param n
|
||||
* the index, non-negative.
|
||||
* @return the E_0=E_1=1 , E_2=5, E_3=61 etc
|
||||
*/
|
||||
public BigInteger at(final int n) {
|
||||
set(n);
|
||||
return Euler.a.elementAt(n);
|
||||
}
|
||||
|
||||
} /* Euler */
|
@ -1,66 +0,0 @@
|
||||
package org.nevec.rjm;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Euler totient function.
|
||||
*
|
||||
* @see <a href="http://oeis.org/A000010">A000010</a> in the OEIS.
|
||||
* @since 2008-10-14
|
||||
* @since 2012-03-04 Adapted to new Ifactor representation.
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class EulerPhi {
|
||||
/**
|
||||
* Default constructor.
|
||||
* Does nothing().
|
||||
*/
|
||||
public EulerPhi() {}
|
||||
|
||||
/**
|
||||
* Compute phi(n).
|
||||
*
|
||||
* @param n
|
||||
* The positive argument of the function.
|
||||
* @return phi(n)
|
||||
*/
|
||||
public BigInteger at(final int n) {
|
||||
return at(new BigInteger("" + n));
|
||||
} /* at */
|
||||
|
||||
/**
|
||||
* Compute phi(n).
|
||||
*
|
||||
* @param n
|
||||
* The positive argument of the function.
|
||||
* @return phi(n)
|
||||
*/
|
||||
public BigInteger at(final BigInteger n) {
|
||||
if (n.compareTo(BigInteger.ZERO) <= 0) {
|
||||
throw new ArithmeticException("negative argument " + n + " of EulerPhi");
|
||||
}
|
||||
final Ifactor prFact = new Ifactor(n);
|
||||
BigInteger phi = n;
|
||||
if (n.compareTo(BigInteger.ONE) > 0) {
|
||||
for (int i = 0; i < prFact.primeexp.size(); i += 2) {
|
||||
final BigInteger p = new BigInteger(prFact.primeexp.elementAt(i).toString());
|
||||
final BigInteger p_1 = p.subtract(BigInteger.ONE);
|
||||
phi = phi.multiply(p_1).divide(p);
|
||||
}
|
||||
}
|
||||
return phi;
|
||||
} /* at */
|
||||
|
||||
/**
|
||||
* Test program.
|
||||
* It takes one argument n and prints the value phi(n).<br>
|
||||
* java -cp . org.nevec.rjm.EulerPhi n<br>
|
||||
*
|
||||
* @since 2006-08-14
|
||||
*/
|
||||
public static void main(final String[] args) throws ArithmeticException {
|
||||
final EulerPhi a = new EulerPhi();
|
||||
final int n = new Integer(args[0]).intValue();
|
||||
System.out.println("phi(" + n + ") = " + a.at(n));
|
||||
}
|
||||
} /* EulerPhi */
|
@ -1,79 +0,0 @@
|
||||
package org.nevec.rjm;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* Factorials.
|
||||
*
|
||||
* @since 2006-06-25
|
||||
* @since 2012-02-15 Storage of the values based on Ifactor, not BigInteger.
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class Factorial {
|
||||
/**
|
||||
* The list of all factorials as a vector.
|
||||
*/
|
||||
static Vector<Ifactor> a = new Vector<>();
|
||||
|
||||
/**
|
||||
* ctor().
|
||||
* Initialize the vector of the factorials with 0!=1 and 1!=1.
|
||||
*/
|
||||
public Factorial() {
|
||||
if (Factorial.a.size() == 0) {
|
||||
Factorial.a.add(Ifactor.ONE);
|
||||
Factorial.a.add(Ifactor.ONE);
|
||||
}
|
||||
} /* ctor */
|
||||
|
||||
/**
|
||||
* Compute the factorial of the non-negative integer.
|
||||
*
|
||||
* @param n
|
||||
* the argument to the factorial, non-negative.
|
||||
* @return the factorial of n.
|
||||
*/
|
||||
public BigInteger at(final int n) {
|
||||
/*
|
||||
* extend the internal list if needed.
|
||||
*/
|
||||
growto(n);
|
||||
return Factorial.a.elementAt(n).n;
|
||||
} /* at */
|
||||
|
||||
/**
|
||||
* Compute the factorial of the non-negative integer.
|
||||
*
|
||||
* @param n
|
||||
* the argument to the factorial, non-negative.
|
||||
* @return the factorial of n.
|
||||
*/
|
||||
public Ifactor toIfactor(final int n) {
|
||||
/*
|
||||
* extend the internal list if needed.
|
||||
*/
|
||||
growto(n);
|
||||
return Factorial.a.elementAt(n);
|
||||
} /* at */
|
||||
|
||||
/**
|
||||
* Extend the internal table to cover up to n!
|
||||
*
|
||||
* @param n
|
||||
* The maximum factorial to be supported.
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
private void growto(final int n) {
|
||||
/*
|
||||
* extend the internal list if needed. Size to be 2 for n<=1, 3 for n<=2
|
||||
* etc.
|
||||
*/
|
||||
while (Factorial.a.size() <= n) {
|
||||
final int lastn = Factorial.a.size() - 1;
|
||||
final Ifactor nextn = new Ifactor(lastn + 1);
|
||||
Factorial.a.add(Factorial.a.elementAt(lastn).multiply(nextn));
|
||||
}
|
||||
} /* growto */
|
||||
|
||||
} /* Factorial */
|
@ -1,43 +0,0 @@
|
||||
package org.nevec.rjm;
|
||||
|
||||
/**
|
||||
* Harmonic numbers.
|
||||
* H(n) is the sum of the inverses of the integers from 1 to n.
|
||||
*
|
||||
* @since 2008-10-19
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class Harmonic {
|
||||
/**
|
||||
* ctor()
|
||||
* Does nothing.
|
||||
*/
|
||||
public Harmonic() {}
|
||||
|
||||
/**
|
||||
* The Harmonic number at the index specified
|
||||
*
|
||||
* @param n
|
||||
* the index, non-negative.
|
||||
* @return the H_1=1 for n=1, H_2=3/2 for n=2 etc.
|
||||
* For values of n less than 1, zero is returned.
|
||||
*/
|
||||
public Rational at(final int n) {
|
||||
if (n < 1) {
|
||||
return new Rational(0, 1);
|
||||
} else {
|
||||
/*
|
||||
* start with 1 as the result
|
||||
*/
|
||||
Rational a = new Rational(1, 1);
|
||||
|
||||
/*
|
||||
* add 1/i for i=2..n
|
||||
*/
|
||||
for (int i = 2; i <= n; i++) {
|
||||
a = a.add(new Rational(1, i));
|
||||
}
|
||||
return a;
|
||||
}
|
||||
}
|
||||
} /* Harmonic */
|
@ -1,835 +0,0 @@
|
||||
package org.nevec.rjm;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Collections;
|
||||
import java.util.Vector;
|
||||
|
||||
import it.cavallium.warppi.util.Error;
|
||||
|
||||
/**
|
||||
* Factored integers.
|
||||
* This class contains a non-negative integer with the prime factor
|
||||
* decomposition attached.
|
||||
*
|
||||
* @since 2006-08-14
|
||||
* @since 2012-02-14 The internal representation contains the bases, and becomes
|
||||
* sparser if few
|
||||
* prime factors are present.
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class Ifactor implements Cloneable, Comparable<Ifactor> {
|
||||
/**
|
||||
* The standard representation of the number
|
||||
*/
|
||||
public BigInteger n;
|
||||
|
||||
/*
|
||||
* The bases and powers of the prime factorization.
|
||||
* representation n = primeexp[0]^primeexp[1]*primeexp[2]^primeexp[3]*...
|
||||
* The value 0 is represented by an empty vector, the value 1 by a vector of
|
||||
* length 1
|
||||
* with a single power of 0.
|
||||
*/
|
||||
public Vector<Integer> primeexp;
|
||||
|
||||
final public static Ifactor ONE = new Ifactor(1);
|
||||
|
||||
final public static Ifactor ZERO = new Ifactor(0);
|
||||
|
||||
/**
|
||||
* Constructor given an integer.
|
||||
* constructor with an ordinary integer
|
||||
*
|
||||
* @param number
|
||||
* the standard representation of the integer
|
||||
*/
|
||||
public Ifactor(int number) {
|
||||
n = new BigInteger("" + number);
|
||||
primeexp = new Vector<>();
|
||||
if (number > 1) {
|
||||
int primindx = 0;
|
||||
final Prime primes = new Prime();
|
||||
/*
|
||||
* Test division against all primes.
|
||||
*/
|
||||
while (number > 1) {
|
||||
int ex = 0;
|
||||
/*
|
||||
* primindx=0 refers to 2, =1 to 3, =2 to 5, =3 to 7 etc
|
||||
*/
|
||||
final int p = primes.at(primindx).intValue();
|
||||
while (number % p == 0) {
|
||||
ex++;
|
||||
number /= p;
|
||||
if (number == 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ex > 0) {
|
||||
primeexp.add(new Integer(p));
|
||||
primeexp.add(new Integer(ex));
|
||||
}
|
||||
primindx++;
|
||||
}
|
||||
} else if (number == 1) {
|
||||
primeexp.add(new Integer(1));
|
||||
primeexp.add(new Integer(0));
|
||||
}
|
||||
} /* Ifactor */
|
||||
|
||||
/**
|
||||
* Constructor given a BigInteger .
|
||||
* Constructor with an ordinary integer, calling a prime factor
|
||||
* decomposition.
|
||||
*
|
||||
* @param number
|
||||
* the BigInteger representation of the integer
|
||||
*/
|
||||
public Ifactor(BigInteger number) {
|
||||
n = number;
|
||||
primeexp = new Vector<>();
|
||||
if (number.compareTo(BigInteger.ONE) == 0) {
|
||||
primeexp.add(new Integer(1));
|
||||
primeexp.add(new Integer(0));
|
||||
} else {
|
||||
int primindx = 0;
|
||||
final Prime primes = new Prime();
|
||||
/*
|
||||
* Test for division against all primes.
|
||||
*/
|
||||
while (number.compareTo(BigInteger.ONE) == 1) {
|
||||
int ex = 0;
|
||||
final BigInteger p = primes.at(primindx);
|
||||
while (number.remainder(p).compareTo(BigInteger.ZERO) == 0) {
|
||||
ex++;
|
||||
number = number.divide(p);
|
||||
if (number.compareTo(BigInteger.ONE) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ex > 0) {
|
||||
primeexp.add(new Integer(p.intValue()));
|
||||
primeexp.add(new Integer(ex));
|
||||
}
|
||||
primindx++;
|
||||
}
|
||||
}
|
||||
} /* Ifactor */
|
||||
|
||||
/**
|
||||
* Constructor given a list of exponents of the prime factor decomposition.
|
||||
*
|
||||
* @param pows
|
||||
* the vector with the sorted list of exponents.
|
||||
* pows[0] is the exponent of 2, pows[1] the exponent of 3,
|
||||
* pows[2] the exponent of 5 etc.
|
||||
* Note that this list does not include the primes, but assumes a
|
||||
* continuous prime-smooth basis.
|
||||
*/
|
||||
public Ifactor(final Vector<Integer> pows) {
|
||||
primeexp = new Vector<>(2 * pows.size());
|
||||
if (pows.size() > 0) {
|
||||
n = BigInteger.ONE;
|
||||
final Prime primes = new Prime();
|
||||
/*
|
||||
* Build the full number by the product of all powers of the primes.
|
||||
*/
|
||||
for (int primindx = 0; primindx < pows.size(); primindx++) {
|
||||
final int ex = pows.elementAt(primindx).intValue();
|
||||
final BigInteger p = primes.at(primindx);
|
||||
n = n.multiply(p.pow(ex));
|
||||
primeexp.add(new Integer(p.intValue()));
|
||||
primeexp.add(new Integer(ex));
|
||||
}
|
||||
} else {
|
||||
n = BigInteger.ZERO;
|
||||
}
|
||||
} /* Ifactor */
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
*
|
||||
* @param oth
|
||||
* the value to be copied
|
||||
*/
|
||||
public Ifactor(final Ifactor oth) {
|
||||
n = oth.n;
|
||||
primeexp = oth.primeexp;
|
||||
} /* Ifactor */
|
||||
|
||||
/**
|
||||
* Deep copy.
|
||||
*
|
||||
* @since 2009-08-14
|
||||
*/
|
||||
@Override
|
||||
public Ifactor clone() {
|
||||
/*
|
||||
* Line not used:
|
||||
*
|
||||
* Vector<Integer> p = (Vector<Integer>)primeexp.clone();
|
||||
*
|
||||
*/
|
||||
final Ifactor cl = new Ifactor(0);
|
||||
cl.n = new BigInteger("" + n);
|
||||
return cl;
|
||||
} /* Ifactor.clone */
|
||||
|
||||
/**
|
||||
* Comparison of two numbers.
|
||||
* The value of this method is in allowing the Vector<>.contains() calls
|
||||
* that use the value,
|
||||
* not the reference for comparison.
|
||||
*
|
||||
* @param oth
|
||||
* the number to compare this with.
|
||||
* @return true if both are the same numbers, false otherwise.
|
||||
*/
|
||||
public boolean equals(final Ifactor oth) {
|
||||
return n.compareTo(oth.n) == 0;
|
||||
} /* Ifactor.equals */
|
||||
|
||||
/**
|
||||
* Multiply with another positive integer.
|
||||
*
|
||||
* @param oth
|
||||
* the second factor.
|
||||
* @return the product of both numbers.
|
||||
*/
|
||||
public Ifactor multiply(final BigInteger oth) {
|
||||
/*
|
||||
* the optimization is to factorize oth _before_ multiplying
|
||||
*/
|
||||
return multiply(new Ifactor(oth));
|
||||
} /* Ifactor.multiply */
|
||||
|
||||
/**
|
||||
* Multiply with another positive integer.
|
||||
*
|
||||
* @param oth
|
||||
* the second factor.
|
||||
* @return the product of both numbers.
|
||||
*/
|
||||
public Ifactor multiply(final int oth) {
|
||||
/*
|
||||
* the optimization is to factorize oth _before_ multiplying
|
||||
*/
|
||||
return multiply(new Ifactor(oth));
|
||||
} /* Ifactor.multiply */
|
||||
|
||||
/**
|
||||
* Multiply with another positive integer.
|
||||
*
|
||||
* @param oth
|
||||
* the second factor.
|
||||
* @return the product of both numbers.
|
||||
*/
|
||||
public Ifactor multiply(final Ifactor oth) {
|
||||
/*
|
||||
* This might be done similar to the lcm() implementation by adding
|
||||
* the powers of the components and calling the constructor with the
|
||||
* list of exponents. This here is the simplest implementation, but slow
|
||||
* because
|
||||
* it calls another prime factorization of the product:
|
||||
* return( new Ifactor(n.multiply(oth.n))) ;
|
||||
*/
|
||||
return multGcdLcm(oth, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lowest common multiple of this with oth.
|
||||
*
|
||||
* @param oth
|
||||
* the second parameter of lcm(this,oth)
|
||||
* @return the lowest common multiple of both numbers. Returns zero
|
||||
* if any of both arguments is zero.
|
||||
*/
|
||||
public Ifactor lcm(final Ifactor oth) {
|
||||
return multGcdLcm(oth, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Greatest common divisor of this and oth.
|
||||
*
|
||||
* @param oth
|
||||
* the second parameter of gcd(this,oth)
|
||||
* @return the lowest common multiple of both numbers. Returns zero
|
||||
* if any of both arguments is zero.
|
||||
*/
|
||||
public Ifactor gcd(final Ifactor oth) {
|
||||
return multGcdLcm(oth, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply with another positive integer.
|
||||
*
|
||||
* @param oth
|
||||
* the second factor.
|
||||
* @param type
|
||||
* 0 to multiply, 1 for gcd, 2 for lcm
|
||||
* @return the product, gcd or lcm of both numbers.
|
||||
*/
|
||||
protected Ifactor multGcdLcm(final Ifactor oth, final int type) {
|
||||
final Ifactor prod = new Ifactor(0);
|
||||
/*
|
||||
* skip the case where 0*something =0, falling thru to the empty
|
||||
* representation for 0
|
||||
*/
|
||||
if (primeexp.size() != 0 && oth.primeexp.size() != 0) {
|
||||
/*
|
||||
* Cases of 1 times something return something.
|
||||
* Cases of lcm(1, something) return something.
|
||||
* Cases of gcd(1, something) return 1.
|
||||
*/
|
||||
if (primeexp.firstElement().intValue() == 1 && type == 0) {
|
||||
return oth;
|
||||
} else if (primeexp.firstElement().intValue() == 1 && type == 2) {
|
||||
return oth;
|
||||
} else if (primeexp.firstElement().intValue() == 1 && type == 1) {
|
||||
return this;
|
||||
} else if (oth.primeexp.firstElement().intValue() == 1 && type == 0) {
|
||||
return this;
|
||||
} else if (oth.primeexp.firstElement().intValue() == 1 && type == 2) {
|
||||
return this;
|
||||
} else if (oth.primeexp.firstElement().intValue() == 1 && type == 1) {
|
||||
return oth;
|
||||
} else {
|
||||
int idxThis = 0;
|
||||
int idxOth = 0;
|
||||
switch (type) {
|
||||
case 0:
|
||||
prod.n = n.multiply(oth.n);
|
||||
break;
|
||||
case 1:
|
||||
prod.n = n.gcd(oth.n);
|
||||
break;
|
||||
case 2:
|
||||
/*
|
||||
* the awkward way, lcm = product divided by gcd
|
||||
*/
|
||||
prod.n = n.multiply(oth.n).divide(n.gcd(oth.n));
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* scan both representations left to right, increasing prime
|
||||
* powers
|
||||
*/
|
||||
while (idxOth < oth.primeexp.size() || idxThis < primeexp.size()) {
|
||||
if (idxOth >= oth.primeexp.size()) {
|
||||
/*
|
||||
* exhausted the list in oth.primeexp; copy over the
|
||||
* remaining 'this'
|
||||
* if multiplying or lcm, discard if gcd.
|
||||
*/
|
||||
if (type == 0 || type == 2) {
|
||||
prod.primeexp.add(primeexp.elementAt(idxThis));
|
||||
prod.primeexp.add(primeexp.elementAt(idxThis + 1));
|
||||
}
|
||||
idxThis += 2;
|
||||
} else if (idxThis >= primeexp.size()) {
|
||||
/*
|
||||
* exhausted the list in primeexp; copy over the
|
||||
* remaining 'oth'
|
||||
*/
|
||||
if (type == 0 || type == 2) {
|
||||
prod.primeexp.add(oth.primeexp.elementAt(idxOth));
|
||||
prod.primeexp.add(oth.primeexp.elementAt(idxOth + 1));
|
||||
}
|
||||
idxOth += 2;
|
||||
} else {
|
||||
Integer p;
|
||||
int ex;
|
||||
switch (primeexp.elementAt(idxThis).compareTo(oth.primeexp.elementAt(idxOth))) {
|
||||
case 0:
|
||||
/* same prime bases p in both factors */
|
||||
p = primeexp.elementAt(idxThis);
|
||||
switch (type) {
|
||||
case 0:
|
||||
/* product means adding exponents */
|
||||
ex = primeexp.elementAt(idxThis + 1).intValue() + oth.primeexp.elementAt(idxOth + 1).intValue();
|
||||
break;
|
||||
case 1:
|
||||
/* gcd means minimum of exponents */
|
||||
ex = Math.min(primeexp.elementAt(idxThis + 1).intValue(), oth.primeexp.elementAt(idxOth + 1).intValue());
|
||||
break;
|
||||
default:
|
||||
/* lcm means maximum of exponents */
|
||||
ex = Math.max(primeexp.elementAt(idxThis + 1).intValue(), oth.primeexp.elementAt(idxOth + 1).intValue());
|
||||
break;
|
||||
}
|
||||
prod.primeexp.add(p);
|
||||
prod.primeexp.add(new Integer(ex));
|
||||
idxOth += 2;
|
||||
idxThis += 2;
|
||||
break;
|
||||
case 1:
|
||||
/*
|
||||
* this prime base bigger than the other and
|
||||
* taken later
|
||||
*/
|
||||
if (type == 0 || type == 2) {
|
||||
prod.primeexp.add(oth.primeexp.elementAt(idxOth));
|
||||
prod.primeexp.add(oth.primeexp.elementAt(idxOth + 1));
|
||||
}
|
||||
idxOth += 2;
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* this prime base smaller than the other and
|
||||
* taken now
|
||||
*/
|
||||
if (type == 0 || type == 2) {
|
||||
prod.primeexp.add(primeexp.elementAt(idxThis));
|
||||
prod.primeexp.add(primeexp.elementAt(idxThis + 1));
|
||||
}
|
||||
idxThis += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return prod;
|
||||
} /* Ifactor.multGcdLcm */
|
||||
|
||||
/**
|
||||
* Integer division through another positive integer.
|
||||
*
|
||||
* @param oth
|
||||
* the denominator.
|
||||
* @return the division of this through the oth, discarding the remainder.
|
||||
*/
|
||||
public Ifactor divide(final Ifactor oth) {
|
||||
/*
|
||||
* todo: it'd probably be faster to cancel the gcd(this,oth) first in
|
||||
* the prime power
|
||||
* representation, which would avoid a more strenous factorization of
|
||||
* the integer ratio
|
||||
*/
|
||||
return new Ifactor(n.divide(oth.n));
|
||||
} /* Ifactor.divide */
|
||||
|
||||
/**
|
||||
* Summation with another positive integer
|
||||
*
|
||||
* @param oth
|
||||
* the other term.
|
||||
* @return the sum of both numbers
|
||||
*/
|
||||
public Ifactor add(final BigInteger oth) {
|
||||
/*
|
||||
* avoid refactorization if oth is zero...
|
||||
*/
|
||||
if (oth.compareTo(BigInteger.ZERO) != 0) {
|
||||
return new Ifactor(n.add(oth));
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
} /* Ifactor.add */
|
||||
|
||||
/**
|
||||
* Exponentiation with a positive integer.
|
||||
*
|
||||
* @param exponent
|
||||
* the non-negative exponent
|
||||
* @return n^exponent. If exponent=0, the result is 1.
|
||||
*/
|
||||
public Ifactor pow(final int exponent) throws ArithmeticException {
|
||||
/*
|
||||
* three simple cases first
|
||||
*/
|
||||
if (exponent < 0) {
|
||||
throw new ArithmeticException("Cannot raise " + toString() + " to negative " + exponent);
|
||||
} else if (exponent == 0) {
|
||||
return new Ifactor(1);
|
||||
} else if (exponent == 1) {
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* general case, the vector with the prime factor powers, which are
|
||||
* component-wise
|
||||
* exponentiation of the individual prime factor powers.
|
||||
*/
|
||||
final Ifactor pows = new Ifactor(0);
|
||||
for (int i = 0; i < primeexp.size(); i += 2) {
|
||||
final Integer p = primeexp.elementAt(i);
|
||||
final int ex = primeexp.elementAt(i + 1).intValue();
|
||||
pows.primeexp.add(p);
|
||||
pows.primeexp.add(new Integer(ex * exponent));
|
||||
}
|
||||
return pows;
|
||||
} /* Ifactor.pow */
|
||||
|
||||
/**
|
||||
* Pulling the r-th root.
|
||||
*
|
||||
* @param r
|
||||
* the positive or negative (nonzero) root.
|
||||
* @return n^(1/r).
|
||||
* The return value falls into the Ifactor class if r is positive,
|
||||
* but if r is negative
|
||||
* a Rational type is needed.
|
||||
* @throws Error
|
||||
* @since 2009-05-18
|
||||
*/
|
||||
public Rational root(final int r) throws ArithmeticException, Error {
|
||||
if (r == 0) {
|
||||
throw new ArithmeticException("Cannot pull zeroth root of " + toString());
|
||||
} else if (r < 0) {
|
||||
/*
|
||||
* a^(-1/b)= 1/(a^(1/b))
|
||||
*/
|
||||
final Rational invRoot = root(-r);
|
||||
return Rational.ONE.divide(invRoot);
|
||||
} else {
|
||||
final BigInteger pows = BigInteger.ONE;
|
||||
for (int i = 0; i < primeexp.size(); i += 2) {
|
||||
/*
|
||||
* all exponents must be multiples of r to succeed (that is, to
|
||||
* stay in the range of rational results).
|
||||
*/
|
||||
final int ex = primeexp.elementAt(i + 1).intValue();
|
||||
if (ex % r != 0) {
|
||||
throw new ArithmeticException("Cannot pull " + r + "th root of " + toString());
|
||||
}
|
||||
|
||||
pows.multiply(new BigInteger("" + primeexp.elementAt(i)).pow(ex / r));
|
||||
}
|
||||
/*
|
||||
* convert result to a Rational; unfortunately this will loose the
|
||||
* prime factorization
|
||||
*/
|
||||
return new Rational(pows);
|
||||
}
|
||||
} /* Ifactor.root */
|
||||
|
||||
/**
|
||||
* The set of positive divisors.
|
||||
*
|
||||
* @return the vector of divisors of the absolute value, sorted.
|
||||
* @since 2010-08-27
|
||||
*/
|
||||
public Vector<BigInteger> divisors() {
|
||||
/*
|
||||
* Recursive approach: the divisors of p1^e1*p2^e2*..*py^ey*pz^ez are
|
||||
* the divisors that don't contain the factor pz, and the
|
||||
* the divisors that contain any power of pz between 1 and up to ez
|
||||
* multiplied
|
||||
* by 1 or by a product that contains the factors p1..py.
|
||||
*/
|
||||
final Vector<BigInteger> d = new Vector<>();
|
||||
if (n.compareTo(BigInteger.ZERO) == 0) {
|
||||
return d;
|
||||
}
|
||||
d.add(BigInteger.ONE);
|
||||
if (n.compareTo(BigInteger.ONE) > 0) {
|
||||
/* Computes sigmaIncopml(p1^e*p2^e2...*py^ey) */
|
||||
final Ifactor dp = dropPrime();
|
||||
|
||||
/* get ez */
|
||||
final int ez = primeexp.lastElement().intValue();
|
||||
|
||||
final Vector<BigInteger> partd = dp.divisors();
|
||||
|
||||
/* obtain pz by lookup in the prime list */
|
||||
final BigInteger pz = new BigInteger(primeexp.elementAt(primeexp.size() - 2).toString());
|
||||
|
||||
/*
|
||||
* the output contains all products of the form partd[]*pz^ez, ez>0,
|
||||
* and with the exception of the 1, all these are appended.
|
||||
*/
|
||||
for (int i = 1; i < partd.size(); i++) {
|
||||
d.add(partd.elementAt(i));
|
||||
}
|
||||
for (int e = 1; e <= ez; e++) {
|
||||
final BigInteger pzez = pz.pow(e);
|
||||
for (int i = 0; i < partd.size(); i++) {
|
||||
d.add(partd.elementAt(i).multiply(pzez));
|
||||
}
|
||||
}
|
||||
}
|
||||
Collections.sort(d);
|
||||
return d;
|
||||
} /* Ifactor.divisors */
|
||||
|
||||
/**
|
||||
* Sum of the divisors of the number.
|
||||
*
|
||||
* @return the sum of all divisors of the number, 1+....+n.
|
||||
*/
|
||||
public Ifactor sigma() {
|
||||
return sigma(1);
|
||||
} /* Ifactor.sigma */
|
||||
|
||||
/**
|
||||
* Sum of the k-th powers of divisors of the number.
|
||||
*
|
||||
* @return the sum of all divisors of the number, 1^k+....+n^k.
|
||||
*/
|
||||
public Ifactor sigma(final int k) {
|
||||
/*
|
||||
* the question is whether keeping a factorization is worth the effort
|
||||
* or whether one should simply multiply these to return a BigInteger...
|
||||
*/
|
||||
if (n.compareTo(BigInteger.ONE) == 0) {
|
||||
return Ifactor.ONE;
|
||||
} else if (n.compareTo(BigInteger.ZERO) == 0) {
|
||||
return Ifactor.ZERO;
|
||||
} else {
|
||||
/*
|
||||
* multiplicative: sigma_k(p^e) = [p^(k*(e+1))-1]/[p^k-1]
|
||||
* sigma_0(p^e) = e+1.
|
||||
*/
|
||||
Ifactor resul = Ifactor.ONE;
|
||||
for (int i = 0; i < primeexp.size(); i += 2) {
|
||||
final int ex = primeexp.elementAt(i + 1).intValue();
|
||||
if (k == 0) {
|
||||
resul = resul.multiply(ex + 1);
|
||||
} else {
|
||||
final Integer p = primeexp.elementAt(i);
|
||||
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);
|
||||
/*
|
||||
* This division is of course exact, no remainder
|
||||
* The costly prime factorization is hidden here.
|
||||
*/
|
||||
final Ifactor f = new Ifactor(num.divide(deno));
|
||||
resul = resul.multiply(f);
|
||||
}
|
||||
}
|
||||
return resul;
|
||||
}
|
||||
} /* Ifactor.sigma */
|
||||
|
||||
/**
|
||||
* Divide through the highest possible power of the highest prime.
|
||||
* If the current number is the prime factor product p1^e1 * p2*e2*
|
||||
* p3^e3*...*py^ey * pz^ez,
|
||||
* the value returned has the final factor pz^ez eliminated, which gives
|
||||
* p1^e1 * p2*e2* p3^e3*...*py^ey.
|
||||
*
|
||||
* @return the new integer obtained by removing the highest prime power.
|
||||
* If this here represents 0 or 1, it is returned without change.
|
||||
* @since 2006-08-20
|
||||
*/
|
||||
public Ifactor dropPrime() {
|
||||
/*
|
||||
* the cases n==1 or n ==0
|
||||
*/
|
||||
if (n.compareTo(BigInteger.ONE) <= 0) {
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* The cases n>1
|
||||
* Start empty. Copy all but the last factor over to the result
|
||||
* the vector with the new prime factor powers, which contain the
|
||||
* old prime factor powers up to but not including the last one.
|
||||
*/
|
||||
final Ifactor pows = new Ifactor(0);
|
||||
pows.n = BigInteger.ONE;
|
||||
for (int i = 0; i < primeexp.size() - 2; i += 2) {
|
||||
pows.primeexp.add(primeexp.elementAt(i));
|
||||
pows.primeexp.add(primeexp.elementAt(i + 1));
|
||||
final BigInteger p = new BigInteger(primeexp.elementAt(i).toString());
|
||||
final int ex = primeexp.elementAt(i + 1).intValue();
|
||||
pows.n = pows.n.multiply(p.pow(ex));
|
||||
}
|
||||
return pows;
|
||||
} /* Ifactor.dropPrime */
|
||||
|
||||
/**
|
||||
* Test whether this is a square of an integer (perfect square).
|
||||
*
|
||||
* @return true if this is an integer squared (including 0), else false
|
||||
*/
|
||||
public boolean issquare() {
|
||||
/*
|
||||
* check the exponents, located at the odd-indexed positions
|
||||
*/
|
||||
for (int i = 1; i < primeexp.size(); i += 2) {
|
||||
if (primeexp.elementAt(i).intValue() % 2 != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} /* Ifactor.issquare */
|
||||
|
||||
/**
|
||||
* The sum of the prime factor exponents, with multiplicity.
|
||||
*
|
||||
* @return the sum over the primeexp numbers
|
||||
*/
|
||||
public int bigomega() {
|
||||
int resul = 0;
|
||||
for (int i = 1; i < primeexp.size(); i += 2) {
|
||||
resul += primeexp.elementAt(i).intValue();
|
||||
}
|
||||
return resul;
|
||||
} /* Ifactor.bigomega */
|
||||
|
||||
/**
|
||||
* The sum of the prime factor exponents, without multiplicity.
|
||||
*
|
||||
* @return the number of distinct prime factors.
|
||||
* @since 2008-10-16
|
||||
*/
|
||||
public int omega() {
|
||||
return primeexp.size() / 2;
|
||||
} /* Ifactor.omega */
|
||||
|
||||
/**
|
||||
* The square-free part.
|
||||
*
|
||||
* @return the minimum m such that m times this number is a square.
|
||||
* @since 2008-10-16
|
||||
*/
|
||||
public BigInteger core() {
|
||||
BigInteger resul = BigInteger.ONE;
|
||||
for (int i = 0; i < primeexp.size(); i += 2) {
|
||||
if (primeexp.elementAt(i + 1).intValue() % 2 != 0) {
|
||||
resul = resul.multiply(new BigInteger(primeexp.elementAt(i).toString()));
|
||||
}
|
||||
}
|
||||
return resul;
|
||||
} /* Ifactor.core */
|
||||
|
||||
/**
|
||||
* The Moebius function.
|
||||
* 1 if n=1, else, if k is the number of distinct prime factors, return
|
||||
* (-1)^k,
|
||||
* else, if k has repeated prime factors, return 0.
|
||||
*
|
||||
* @return the moebius function.
|
||||
*/
|
||||
public int moebius() {
|
||||
if (n.compareTo(BigInteger.ONE) <= 0) {
|
||||
return 1;
|
||||
}
|
||||
/* accumulate number of different primes in k */
|
||||
int k = 1;
|
||||
for (int i = 0; i < primeexp.size(); i += 2) {
|
||||
final int e = primeexp.elementAt(i + 1).intValue();
|
||||
if (e > 1) {
|
||||
return 0;
|
||||
} else if (e == 1) {
|
||||
/* accumulates (-1)^k */
|
||||
k *= -1;
|
||||
}
|
||||
|
||||
}
|
||||
return k;
|
||||
} /* Ifactor.moebius */
|
||||
|
||||
/**
|
||||
* Maximum of two values.
|
||||
*
|
||||
* @param oth
|
||||
* the number to compare this with.
|
||||
* @return the larger of the two values.
|
||||
*/
|
||||
public Ifactor max(final Ifactor oth) {
|
||||
if (n.compareTo(oth.n) >= 0) {
|
||||
return this;
|
||||
} else {
|
||||
return oth;
|
||||
}
|
||||
} /* Ifactor.max */
|
||||
|
||||
/**
|
||||
* Minimum of two values.
|
||||
*
|
||||
* @param oth
|
||||
* the number to compare this with.
|
||||
* @return the smaller of the two values.
|
||||
*/
|
||||
public Ifactor min(final Ifactor oth) {
|
||||
if (n.compareTo(oth.n) <= 0) {
|
||||
return this;
|
||||
} else {
|
||||
return oth;
|
||||
}
|
||||
} /* Ifactor.min */
|
||||
|
||||
/**
|
||||
* Maximum of a list of values.
|
||||
*
|
||||
* @param set
|
||||
* list of numbers.
|
||||
* @return the largest in the list.
|
||||
*/
|
||||
public static Ifactor max(final Vector<Ifactor> set) {
|
||||
Ifactor resul = set.elementAt(0);
|
||||
for (int i = 1; i < set.size(); i++) {
|
||||
resul = resul.max(set.elementAt(i));
|
||||
}
|
||||
return resul;
|
||||
} /* Ifactor.max */
|
||||
|
||||
/**
|
||||
* Minimum of a list of values.
|
||||
*
|
||||
* @param set
|
||||
* list of numbers.
|
||||
* @return the smallest in the list.
|
||||
*/
|
||||
public static Ifactor min(final Vector<Ifactor> set) {
|
||||
Ifactor resul = set.elementAt(0);
|
||||
for (int i = 1; i < set.size(); i++) {
|
||||
resul = resul.min(set.elementAt(i));
|
||||
}
|
||||
return resul;
|
||||
} /* Ifactor.min */
|
||||
|
||||
/**
|
||||
* Compare value against another Ifactor
|
||||
*
|
||||
* @param oth
|
||||
* The value to be compared agains.
|
||||
* @return 1, 0 or -1 according to being larger, equal to or smaller than
|
||||
* oth.
|
||||
* @since 2012-02-15
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(final Ifactor oth) {
|
||||
return n.compareTo(oth.n);
|
||||
} /* compareTo */
|
||||
|
||||
/**
|
||||
* Convert to printable format
|
||||
*
|
||||
* @return a string of the form n:prime^pow*prime^pow*prime^pow...
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
String resul = new String(n.toString() + ":");
|
||||
if (n.compareTo(BigInteger.ONE) == 0) {
|
||||
resul += "1";
|
||||
} else {
|
||||
boolean firstMul = true;
|
||||
for (int i = 0; i < primeexp.size(); i += 2) {
|
||||
if (!firstMul) {
|
||||
resul += "*";
|
||||
}
|
||||
if (primeexp.elementAt(i + 1).intValue() > 1) {
|
||||
resul += primeexp.elementAt(i).toString() + "^" + primeexp.elementAt(i + 1).toString();
|
||||
} else {
|
||||
resul += primeexp.elementAt(i).toString();
|
||||
}
|
||||
firstMul = false;
|
||||
}
|
||||
}
|
||||
return resul;
|
||||
} /* Ifactor.toString */
|
||||
|
||||
/**
|
||||
* Test program.
|
||||
* It takes a single argument n and prints the integer factorizaton.<br>
|
||||
* java -cp . org.nevec.rjm.Ifactor n<br>
|
||||
*/
|
||||
public static void main(final String[] args) throws Exception {
|
||||
final BigInteger n = new BigInteger(args[0]);
|
||||
System.out.println(new Ifactor(n));
|
||||
} /* Ifactor.main */
|
||||
} /* Ifactor */
|
@ -1,88 +0,0 @@
|
||||
package org.nevec.rjm;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* Number of partitions.
|
||||
*
|
||||
* @since 2008-10-15
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class PartitionsP {
|
||||
/**
|
||||
* The list of all partitions as a vector.
|
||||
*/
|
||||
static protected Vector<BigInteger> a = new Vector<>();
|
||||
|
||||
/**
|
||||
* The maximum integer covered by the high end of the list.
|
||||
*/
|
||||
static protected BigInteger nMax = new BigInteger("-1");
|
||||
|
||||
/**
|
||||
* Default constructor initializing a list of partitions up to 7.
|
||||
*/
|
||||
public PartitionsP() {
|
||||
if (PartitionsP.a.size() == 0) {
|
||||
PartitionsP.a.add(new BigInteger("" + 1));
|
||||
PartitionsP.a.add(new BigInteger("" + 1));
|
||||
PartitionsP.a.add(new BigInteger("" + 2));
|
||||
PartitionsP.a.add(new BigInteger("" + 3));
|
||||
PartitionsP.a.add(new BigInteger("" + 5));
|
||||
PartitionsP.a.add(new BigInteger("" + 7));
|
||||
}
|
||||
PartitionsP.nMax = new BigInteger("" + (PartitionsP.a.size() - 1));
|
||||
} /* ctor */
|
||||
|
||||
/**
|
||||
* return the number of partitions of i
|
||||
*
|
||||
* @param i
|
||||
* the zero-based index into the list of partitions
|
||||
* @return the ith partition number. This is 1 if i=0 or 1, 2 if i=2 and so
|
||||
* forth.
|
||||
*/
|
||||
public BigInteger at(final int i) {
|
||||
/*
|
||||
* If the current list is too small, increase in intervals
|
||||
* of 3 until the list has at least i elements.
|
||||
*/
|
||||
while (i > PartitionsP.nMax.intValue()) {
|
||||
growto(PartitionsP.nMax.add(new BigInteger("" + 3)));
|
||||
}
|
||||
return PartitionsP.a.elementAt(i);
|
||||
} /* at */
|
||||
|
||||
/**
|
||||
* extend the list of known partitions up to n
|
||||
*
|
||||
* @param n
|
||||
* the maximum integer hashed after the call.
|
||||
*/
|
||||
private void growto(final BigInteger n) {
|
||||
while (PartitionsP.a.size() <= n.intValue()) {
|
||||
BigInteger per = new BigInteger("0");
|
||||
final BigInteger cursiz = new BigInteger("" + PartitionsP.a.size());
|
||||
for (int k = 0; k < PartitionsP.a.size(); k++) {
|
||||
final BigInteger tmp = PartitionsP.a.elementAt(k).multiply(BigIntegerMath.sigma(PartitionsP.a.size() - k));
|
||||
per = per.add(tmp);
|
||||
}
|
||||
PartitionsP.a.add(per.divide(cursiz));
|
||||
}
|
||||
PartitionsP.nMax = new BigInteger("" + (PartitionsP.a.size() - 1));
|
||||
} /* growto */
|
||||
|
||||
/**
|
||||
* Test program.
|
||||
* It takes one integer argument n and prints P(n).<br>
|
||||
* java -cp . org.nevec.rjm.PartitionsP n<br>
|
||||
*
|
||||
* @since 2008-10-15
|
||||
*/
|
||||
public static void main(final String[] args) throws Exception {
|
||||
final PartitionsP a = new PartitionsP();
|
||||
final int n = new Integer(args[0]).intValue();
|
||||
System.out.println("P(" + n + ")=" + a.at(n));
|
||||
}
|
||||
}
|
@ -1,321 +0,0 @@
|
||||
package org.nevec.rjm;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* Prime numbers.
|
||||
* The implementation is a very basic computation of the set of all primes
|
||||
* on demand, growing infinitely without any defined upper limit.
|
||||
* The effects of such scheme are (i) the lookup-times become shorter after
|
||||
* a while as more and more primes have been used and stored. The applications
|
||||
* appear to become faster. (ii) Using the implementation for factorizations
|
||||
* may easily require all available memory and stall finally, because indeed
|
||||
* a dense list of primes with growing upper bound is kept without any hashing
|
||||
* or lagging scheme.
|
||||
*
|
||||
* @since 2006-08-11
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class Prime {
|
||||
/**
|
||||
* The list of all numbers as a vector.
|
||||
*/
|
||||
static Vector<BigInteger> a = new Vector<>();
|
||||
|
||||
/**
|
||||
* The maximum integer covered by the high end of the list.
|
||||
*/
|
||||
static protected BigInteger nMax = new BigInteger("-1");
|
||||
|
||||
/**
|
||||
* Default constructor initializing a list of primes up to 17.
|
||||
* 17 is enough to call the Miller-Rabin tests on the first 7 primes without
|
||||
* further
|
||||
* action.
|
||||
*/
|
||||
public Prime() {
|
||||
if (Prime.a.size() == 0) {
|
||||
Prime.a.add(new BigInteger("" + 2));
|
||||
Prime.a.add(new BigInteger("" + 3));
|
||||
Prime.a.add(new BigInteger("" + 5));
|
||||
Prime.a.add(new BigInteger("" + 7));
|
||||
Prime.a.add(new BigInteger("" + 11));
|
||||
Prime.a.add(new BigInteger("" + 13));
|
||||
Prime.a.add(new BigInteger("" + 17));
|
||||
}
|
||||
Prime.nMax = Prime.a.lastElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a number is a prime.
|
||||
*
|
||||
* @param n
|
||||
* the integer to be tested for primality
|
||||
* @return true if prime, false if not
|
||||
*/
|
||||
public boolean contains(final BigInteger n) {
|
||||
/*
|
||||
* not documented
|
||||
* return ( n.isProbablePrime() ) ;
|
||||
*/
|
||||
switch (millerRabin(n)) {
|
||||
case -1:
|
||||
return false;
|
||||
case 1:
|
||||
return true;
|
||||
}
|
||||
growto(n);
|
||||
return Prime.a.contains(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether a number n is a strong pseudoprime to base a.
|
||||
*
|
||||
* @param n
|
||||
* the integer to be tested for primality
|
||||
* @param a
|
||||
* the base
|
||||
* @return true if the test is passed, so n may be a prime.
|
||||
* false if the test is not passed, so n is not a prime.
|
||||
* @since 2010-02-25
|
||||
*/
|
||||
public boolean isSPP(final BigInteger n, final BigInteger a) {
|
||||
final BigInteger two = new BigInteger("" + 2);
|
||||
|
||||
/*
|
||||
* numbers less than 2 are not prime
|
||||
*/
|
||||
if (n.compareTo(two) == -1) {
|
||||
return false;
|
||||
} else if (n.compareTo(two) == 0) {
|
||||
return true;
|
||||
} else if (n.remainder(two).compareTo(BigInteger.ZERO) == 0) {
|
||||
return false;
|
||||
} else {
|
||||
/*
|
||||
* q= n- 1 = d *2^s with d odd
|
||||
*/
|
||||
final BigInteger q = n.subtract(BigInteger.ONE);
|
||||
final int s = q.getLowestSetBit();
|
||||
final BigInteger d = q.shiftRight(s);
|
||||
|
||||
/*
|
||||
* test whether a^d = 1 (mod n)
|
||||
*/
|
||||
if (a.modPow(d, n).compareTo(BigInteger.ONE) == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* test whether a^(d*2^r) = -1 (mod n), 0<=r<s
|
||||
*/
|
||||
for (int r = 0; r < s; r++) {
|
||||
if (a.modPow(d.shiftLeft(r), n).compareTo(q) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Miller-Rabin primality tests.
|
||||
*
|
||||
* @param n
|
||||
* The prime candidate
|
||||
* @return -1 if n is a composite, 1 if it is a prime, 0 if it may be a
|
||||
* prime.
|
||||
* @since 2010-02-25
|
||||
*/
|
||||
public int millerRabin(final BigInteger n) {
|
||||
/*
|
||||
* list of limiting numbers which fail tests on k primes, A014233 in the
|
||||
* OEIS
|
||||
*/
|
||||
final String[] mr = { "2047", "1373653", "25326001", "3215031751", "2152302898747", "3474749660383", "341550071728321" };
|
||||
int mrLim = 0;
|
||||
while (mrLim < mr.length) {
|
||||
final int l = n.compareTo(new BigInteger(mr[mrLim]));
|
||||
if (l < 0) {
|
||||
break;
|
||||
} else if (l == 0) {
|
||||
return -1;
|
||||
}
|
||||
mrLim++;
|
||||
}
|
||||
/*
|
||||
* cannot test candidates larger than the last in the mr list
|
||||
*/
|
||||
if (mrLim == mr.length) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* test the bases prime(1), prime(2) up to prime(mrLim+1)
|
||||
*/
|
||||
for (int p = 0; p <= mrLim; p++) {
|
||||
if (isSPP(n, at(p)) == false) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the ithprime
|
||||
*
|
||||
* @param i
|
||||
* the zero-based index into the list of primes
|
||||
* @return the ith prime. This is 2 if i=0, 3 if i=1 and so forth.
|
||||
*/
|
||||
public BigInteger at(final int i) {
|
||||
/*
|
||||
* If the current list is too small, increase in intervals
|
||||
* of 5 until the list has at least i elements.
|
||||
*/
|
||||
while (i >= Prime.a.size()) {
|
||||
growto(Prime.nMax.add(new BigInteger("" + 5)));
|
||||
}
|
||||
return Prime.a.elementAt(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* return the count of primes <= n
|
||||
*
|
||||
* @param n
|
||||
* the upper limit of the scan
|
||||
* @return the ith prime. This is 2 if i=0, 3 if i=1 and so forth.
|
||||
*/
|
||||
public BigInteger pi(final BigInteger n) {
|
||||
/*
|
||||
* If the current list is too small, increase in intervals
|
||||
* of 5 until the list has at least i elements.
|
||||
*/
|
||||
growto(n);
|
||||
BigInteger r = new BigInteger("0");
|
||||
for (int i = 0; i < Prime.a.size(); i++) {
|
||||
if (Prime.a.elementAt(i).compareTo(n) <= 0) {
|
||||
r = r.add(BigInteger.ONE);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the smallest prime larger than n
|
||||
*
|
||||
* @param n
|
||||
* lower limit of the search
|
||||
* @return the next larger prime.
|
||||
* @since 2008-10-16
|
||||
*/
|
||||
public BigInteger nextprime(final BigInteger n) {
|
||||
/* if n <=1, return 2 */
|
||||
if (n.compareTo(BigInteger.ONE) <= 0) {
|
||||
return Prime.a.elementAt(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the currently largest element in the list is too small, increase
|
||||
* in intervals
|
||||
* of 5 until the list has at least i elements.
|
||||
*/
|
||||
while (Prime.a.lastElement().compareTo(n) <= 0) {
|
||||
growto(Prime.nMax.add(new BigInteger("" + 5)));
|
||||
}
|
||||
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.lastElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* return the largest prime smaller than n
|
||||
*
|
||||
* @param n
|
||||
* upper limit of the search
|
||||
* @return the next smaller prime.
|
||||
* @since 2008-10-17
|
||||
*/
|
||||
public BigInteger prevprime(final BigInteger n) {
|
||||
/* if n <=2, return 0 */
|
||||
if (n.compareTo(BigInteger.ONE) <= 0) {
|
||||
return BigInteger.ZERO;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the currently largest element in the list is too small, increase
|
||||
* in intervals
|
||||
* of 5 until the list has at least i elements.
|
||||
*/
|
||||
while (Prime.a.lastElement().compareTo(n) < 0) {
|
||||
growto(Prime.nMax.add(new BigInteger("" + 5)));
|
||||
}
|
||||
|
||||
for (int i = 0; i < Prime.a.size(); i++) {
|
||||
if (Prime.a.elementAt(i).compareTo(n) >= 0) {
|
||||
return Prime.a.elementAt(i - 1);
|
||||
}
|
||||
}
|
||||
return Prime.a.lastElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* extend the list of known primes up to n
|
||||
*
|
||||
* @param n
|
||||
* the maximum integer known to be prime or not prime after the
|
||||
* call.
|
||||
*/
|
||||
protected void growto(final BigInteger n) {
|
||||
while (Prime.nMax.compareTo(n) == -1) {
|
||||
Prime.nMax = Prime.nMax.add(BigInteger.ONE);
|
||||
boolean isp = true;
|
||||
for (int p = 0; p < Prime.a.size(); p++) {
|
||||
/*
|
||||
* 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) {
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* The next case means that the p'th number in the list of known
|
||||
* primes divides
|
||||
* nMax and nMax cannot be a prime.
|
||||
*/
|
||||
if (Prime.nMax.remainder(Prime.a.get(p)).compareTo(BigInteger.ZERO) == 0) {
|
||||
isp = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isp) {
|
||||
Prime.a.add(Prime.nMax);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test program.
|
||||
* Usage: java -cp . org.nevec.rjm.Prime n<br>
|
||||
* This takes a single argument (n) and prints prime(n), the previous and
|
||||
* next prime, and pi(n).
|
||||
*
|
||||
* @since 2006-08-14
|
||||
*/
|
||||
public static void main(final String[] args) throws Exception {
|
||||
final Prime a = new Prime();
|
||||
final int n = new Integer(args[0]).intValue();
|
||||
if (n >= 1) {
|
||||
if (n >= 2) {
|
||||
System.out.println("prime(" + (n - 1) + ") = " + a.at(n - 1));
|
||||
}
|
||||
System.out.println("prime(" + n + ") = " + a.at(n));
|
||||
System.out.println("prime(" + (n + 1) + ") = " + a.at(n + 1));
|
||||
System.out.println("pi(" + n + ") = " + a.pi(new BigInteger("" + n)));
|
||||
}
|
||||
}
|
||||
} /* Prime */
|
File diff suppressed because it is too large
Load Diff
@ -1,900 +0,0 @@
|
||||
package org.nevec.rjm;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.math.MathContext;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
import it.cavallium.warppi.util.Error;
|
||||
import it.cavallium.warppi.util.Errors;
|
||||
|
||||
/**
|
||||
* Fractions (rational numbers). They are divisions of two BigInteger numbers,
|
||||
* reduced to coprime numerator and denominator.
|
||||
*
|
||||
* @since 2006-06-25
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class Rational implements Cloneable, Comparable<Rational> {
|
||||
/**
|
||||
* numerator
|
||||
*/
|
||||
BigInteger a;
|
||||
|
||||
/**
|
||||
* denominator, always larger than zero.
|
||||
*/
|
||||
BigInteger b;
|
||||
|
||||
/**
|
||||
* The maximum and minimum value of a standard Java integer, 2^31.
|
||||
*
|
||||
* @since 2009-05-18
|
||||
*/
|
||||
static public BigInteger MAX_INT = new BigInteger("2147483647");
|
||||
static public BigInteger MIN_INT = new BigInteger("-2147483648");
|
||||
|
||||
/**
|
||||
* The constant 1.
|
||||
*/
|
||||
public static Rational ONE = new Rational(1, 1);
|
||||
/**
|
||||
* The constant 0.
|
||||
*/
|
||||
static public Rational ZERO = new Rational();
|
||||
|
||||
/**
|
||||
* The constant 1/2
|
||||
*
|
||||
* @since 2010-05-25
|
||||
*/
|
||||
static public Rational HALF = new Rational(1, 2);
|
||||
|
||||
/**
|
||||
* Default ctor, which represents the zero.
|
||||
*
|
||||
* @since 2007-11-17
|
||||
*/
|
||||
public Rational() {
|
||||
a = BigInteger.ZERO;
|
||||
b = BigInteger.ONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* ctor from a numerator and denominator.
|
||||
*
|
||||
* @param a
|
||||
* the numerator.
|
||||
* @param b
|
||||
* the denominator.
|
||||
*/
|
||||
public Rational(final BigInteger a, final BigInteger b) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
normalize();
|
||||
}
|
||||
|
||||
/**
|
||||
* ctor from a numerator.
|
||||
*
|
||||
* @param a
|
||||
* the BigInteger.
|
||||
*/
|
||||
public Rational(final BigInteger a) {
|
||||
this.a = a;
|
||||
b = new BigInteger("1");
|
||||
}
|
||||
|
||||
/**
|
||||
* ctor from a numerator and denominator.
|
||||
*
|
||||
* @param a
|
||||
* the numerator.
|
||||
* @param b
|
||||
* the denominator.
|
||||
*/
|
||||
public Rational(final int a, final int b) {
|
||||
this(new BigInteger("" + a), new BigInteger("" + b));
|
||||
}
|
||||
|
||||
/**
|
||||
* ctor from an integer.
|
||||
*
|
||||
* @param n
|
||||
* the integer to be represented by the new instance.
|
||||
* @since 2010-07-18
|
||||
*/
|
||||
public Rational(final int n) {
|
||||
this(n, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* ctor from a string representation.
|
||||
*
|
||||
* @param str
|
||||
* the string. This either has a slash in it, separating two
|
||||
* integers, or, if there is no slash, is representing the
|
||||
* numerator with implicit denominator equal to 1. Warning: this
|
||||
* does not yet test for a denominator equal to zero
|
||||
*/
|
||||
public Rational(final String str) {
|
||||
this(str, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* ctor from a string representation in a specified base.
|
||||
*
|
||||
* @param str
|
||||
* the string. This either has a slash in it, separating two
|
||||
* integers, or, if there is no slash, is just representing the
|
||||
* numerator.
|
||||
* @param radix
|
||||
* the number base for numerator and denominator Warning: this
|
||||
* does not yet test for a denominator equal to zero
|
||||
*/
|
||||
public Rational(final String str, final int radix) {
|
||||
final int hasslah = str.indexOf("/");
|
||||
if (hasslah == -1) {
|
||||
a = new BigInteger(str, radix);
|
||||
b = new BigInteger("1", radix);
|
||||
/* no normalization necessary here */
|
||||
} else {
|
||||
/*
|
||||
* create numerator and denominator separately
|
||||
*/
|
||||
a = new BigInteger(str.substring(0, hasslah), radix);
|
||||
b = new BigInteger(str.substring(hasslah + 1), radix);
|
||||
normalize();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a copy.
|
||||
*
|
||||
* @since 2008-11-07
|
||||
*/
|
||||
@Override
|
||||
public Rational clone() {
|
||||
/*
|
||||
* protected access means this does not work return new
|
||||
* Rational(a.clone(), b.clone()) ;
|
||||
*/
|
||||
final BigInteger aclon = new BigInteger("" + a);
|
||||
final BigInteger bclon = new BigInteger("" + b);
|
||||
return new Rational(aclon, bclon);
|
||||
} /* Rational.clone */
|
||||
|
||||
/**
|
||||
* Multiply by another fraction.
|
||||
*
|
||||
* @param val
|
||||
* a second rational number.
|
||||
* @return the product of this with the val.
|
||||
*/
|
||||
public Rational multiply(final Rational val) {
|
||||
final BigInteger num = a.multiply(val.a);
|
||||
final BigInteger deno = b.multiply(val.b);
|
||||
/*
|
||||
* Normalization to an coprime format will be done inside the ctor() and
|
||||
* is not duplicated here.
|
||||
*/
|
||||
return new Rational(num, deno);
|
||||
} /* Rational.multiply */
|
||||
|
||||
/**
|
||||
* Multiply by a BigInteger.
|
||||
*
|
||||
* @param val
|
||||
* a second number.
|
||||
* @return the product of this with the value.
|
||||
*/
|
||||
public Rational multiply(final BigInteger val) {
|
||||
final Rational val2 = new Rational(val, BigInteger.ONE);
|
||||
return multiply(val2);
|
||||
} /* Rational.multiply */
|
||||
|
||||
/**
|
||||
* Multiply by an integer.
|
||||
*
|
||||
* @param val
|
||||
* a second number.
|
||||
* @return the product of this with the value.
|
||||
*/
|
||||
public Rational multiply(final int val) {
|
||||
final BigInteger tmp = new BigInteger("" + val);
|
||||
return multiply(tmp);
|
||||
} /* Rational.multiply */
|
||||
|
||||
/**
|
||||
* Power to an integer.
|
||||
*
|
||||
* @param exponent
|
||||
* the exponent.
|
||||
* @return this value raised to the power given by the exponent. If the
|
||||
* exponent is 0, the value 1 is returned.
|
||||
*/
|
||||
public Rational pow(final int exponent) {
|
||||
if (exponent == 0) {
|
||||
return new Rational(1, 1);
|
||||
}
|
||||
|
||||
final BigInteger num = a.pow(Math.abs(exponent));
|
||||
final BigInteger deno = b.pow(Math.abs(exponent));
|
||||
if (exponent > 0) {
|
||||
return new Rational(num, deno);
|
||||
} else {
|
||||
return new Rational(deno, num);
|
||||
}
|
||||
} /* Rational.pow */
|
||||
|
||||
/**
|
||||
* Power to an integer.
|
||||
*
|
||||
* @param exponent
|
||||
* the exponent.
|
||||
* @return this value raised to the power given by the exponent. If the
|
||||
* exponent is 0, the value 1 is returned.
|
||||
* @throws Error
|
||||
* @since 2009-05-18
|
||||
*/
|
||||
public Rational pow(final BigInteger exponent) throws Error {
|
||||
/* test for overflow */
|
||||
if (exponent.compareTo(Rational.MAX_INT) == 1) {
|
||||
throw new Error(Errors.NUMBER_TOO_LARGE);
|
||||
}
|
||||
if (exponent.compareTo(Rational.MIN_INT) == -1) {
|
||||
throw new Error(Errors.NUMBER_TOO_SMALL);
|
||||
}
|
||||
|
||||
/* promote to the simpler interface above */
|
||||
return pow(exponent.intValue());
|
||||
} /* Rational.pow */
|
||||
|
||||
/**
|
||||
* r-th root.
|
||||
*
|
||||
* @param r
|
||||
* the inverse of the exponent. 2 for the square root, 3 for the
|
||||
* third root etc
|
||||
* @return this value raised to the inverse power given by the root
|
||||
* argument, this^(1/r).
|
||||
* @throws Error
|
||||
* @since 2009-05-18
|
||||
*/
|
||||
public Rational root(final BigInteger r) throws Error {
|
||||
/* test for overflow */
|
||||
if (r.compareTo(Rational.MAX_INT) == 1) {
|
||||
throw new Error(Errors.NUMBER_TOO_LARGE);
|
||||
}
|
||||
if (r.compareTo(Rational.MIN_INT) == -1) {
|
||||
throw new Error(Errors.NUMBER_TOO_SMALL);
|
||||
}
|
||||
|
||||
final int rthroot = r.intValue();
|
||||
/* cannot pull root of a negative value with even-valued root */
|
||||
if (compareTo(Rational.ZERO) == -1 && rthroot % 2 == 0) {
|
||||
throw new Error(Errors.NEGATIVE_PARAMETER);
|
||||
}
|
||||
|
||||
/*
|
||||
* extract a sign such that we calculate |n|^(1/r), still r carrying any
|
||||
* sign
|
||||
*/
|
||||
final boolean flipsign = compareTo(Rational.ZERO) == -1 && rthroot % 2 != 0 ? true : false;
|
||||
|
||||
/*
|
||||
* delegate the main work to ifactor#root()
|
||||
*/
|
||||
final Ifactor num = new Ifactor(a.abs());
|
||||
final Ifactor deno = new Ifactor(b);
|
||||
final Rational resul = num.root(rthroot).divide(deno.root(rthroot));
|
||||
if (flipsign) {
|
||||
return resul.negate();
|
||||
} else {
|
||||
return resul;
|
||||
}
|
||||
} /* Rational.root */
|
||||
|
||||
/**
|
||||
* Raise to a rational power.
|
||||
*
|
||||
* @param exponent
|
||||
* The exponent.
|
||||
* @return This value raised to the power given by the exponent. If the
|
||||
* exponent is 0, the value 1 is returned.
|
||||
* @throws Error
|
||||
* @since 2009-05-18
|
||||
*/
|
||||
public Rational pow(final Rational exponent) throws Error {
|
||||
if (exponent.a.compareTo(BigInteger.ZERO) == 0) {
|
||||
return new Rational(1, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* calculate (a/b)^(exponent.a/exponent.b) as
|
||||
* ((a/b)^exponent.a)^(1/exponent.b) = tmp^(1/exponent.b)
|
||||
*/
|
||||
final Rational tmp = pow(exponent.a);
|
||||
return tmp.root(exponent.b);
|
||||
} /* Rational.pow */
|
||||
|
||||
/**
|
||||
* Divide by another fraction.
|
||||
*
|
||||
* @param val
|
||||
* A second rational number.
|
||||
* @return The value of this/val
|
||||
* @throws Error
|
||||
*/
|
||||
public Rational divide(final Rational val) throws Error {
|
||||
if (val.compareTo(Rational.ZERO) == 0) {
|
||||
throw new Error(Errors.DIVISION_BY_ZERO);
|
||||
}
|
||||
final BigInteger num = a.multiply(val.b);
|
||||
final BigInteger deno = b.multiply(val.a);
|
||||
/*
|
||||
* Reduction to a coprime format is done inside the ctor, and not
|
||||
* repeated here.
|
||||
*/
|
||||
return new Rational(num, deno);
|
||||
} /* Rational.divide */
|
||||
|
||||
/**
|
||||
* Divide by an integer.
|
||||
*
|
||||
* @param val
|
||||
* a second number.
|
||||
* @return the value of this/val
|
||||
* @throws Error
|
||||
*/
|
||||
public Rational divide(final BigInteger val) throws Error {
|
||||
if (val.compareTo(BigInteger.ZERO) == 0) {
|
||||
throw new Error(Errors.DIVISION_BY_ZERO);
|
||||
}
|
||||
final Rational val2 = new Rational(val, BigInteger.ONE);
|
||||
return divide(val2);
|
||||
} /* Rational.divide */
|
||||
|
||||
/**
|
||||
* Divide by an integer.
|
||||
*
|
||||
* @param val
|
||||
* A second number.
|
||||
* @return The value of this/val
|
||||
* @throws Error
|
||||
*/
|
||||
public Rational divide(final int val) throws Error {
|
||||
if (val == 0) {
|
||||
throw new Error(Errors.DIVISION_BY_ZERO);
|
||||
}
|
||||
final Rational val2 = new Rational(val, 1);
|
||||
return divide(val2);
|
||||
} /* Rational.divide */
|
||||
|
||||
/**
|
||||
* Add another fraction.
|
||||
*
|
||||
* @param val
|
||||
* The number to be added
|
||||
* @return this+val.
|
||||
*/
|
||||
public Rational add(final Rational val) {
|
||||
final BigInteger num = a.multiply(val.b).add(b.multiply(val.a));
|
||||
final BigInteger deno = b.multiply(val.b);
|
||||
return new Rational(num, deno);
|
||||
} /* Rational.add */
|
||||
|
||||
/**
|
||||
* Add another integer.
|
||||
*
|
||||
* @param val
|
||||
* The number to be added
|
||||
* @return this+val.
|
||||
*/
|
||||
public Rational add(final BigInteger val) {
|
||||
final Rational val2 = new Rational(val, BigInteger.ONE);
|
||||
return add(val2);
|
||||
} /* Rational.add */
|
||||
|
||||
/**
|
||||
* Add another integer.
|
||||
*
|
||||
* @param val
|
||||
* The number to be added
|
||||
* @return this+val.
|
||||
* @since May 26 2010
|
||||
*/
|
||||
public Rational add(final int val) {
|
||||
final BigInteger val2 = a.add(b.multiply(new BigInteger("" + val)));
|
||||
return new Rational(val2, b);
|
||||
} /* Rational.add */
|
||||
|
||||
/**
|
||||
* Compute the negative.
|
||||
*
|
||||
* @return -this.
|
||||
*/
|
||||
public Rational negate() {
|
||||
return new Rational(a.negate(), b);
|
||||
} /* Rational.negate */
|
||||
|
||||
/**
|
||||
* Subtract another fraction.
|
||||
*
|
||||
* @param val
|
||||
* the number to be subtracted from this
|
||||
* @return this - val.
|
||||
*/
|
||||
public Rational subtract(final Rational val) {
|
||||
final Rational val2 = val.negate();
|
||||
return add(val2);
|
||||
} /* Rational.subtract */
|
||||
|
||||
/**
|
||||
* Subtract an integer.
|
||||
*
|
||||
* @param val
|
||||
* the number to be subtracted from this
|
||||
* @return this - val.
|
||||
*/
|
||||
public Rational subtract(final BigInteger val) {
|
||||
final Rational val2 = new Rational(val, BigInteger.ONE);
|
||||
return subtract(val2);
|
||||
} /* Rational.subtract */
|
||||
|
||||
/**
|
||||
* Subtract an integer.
|
||||
*
|
||||
* @param val
|
||||
* the number to be subtracted from this
|
||||
* @return this - val.
|
||||
*/
|
||||
public Rational subtract(final int val) {
|
||||
final Rational val2 = new Rational(val, 1);
|
||||
return subtract(val2);
|
||||
} /* Rational.subtract */
|
||||
|
||||
/**
|
||||
* binomial (n choose m).
|
||||
*
|
||||
* @param n
|
||||
* the numerator. Equals the size of the set to choose from.
|
||||
* @param m
|
||||
* the denominator. Equals the number of elements to select.
|
||||
* @return the binomial coefficient.
|
||||
* @since 2006-06-27
|
||||
* @author Richard J. Mathar
|
||||
* @throws Error
|
||||
*/
|
||||
public static Rational binomial(final Rational n, final BigInteger m) throws Error {
|
||||
if (m.compareTo(BigInteger.ZERO) == 0) {
|
||||
return Rational.ONE;
|
||||
}
|
||||
Rational bin = n;
|
||||
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);
|
||||
}
|
||||
return bin;
|
||||
} /* Rational.binomial */
|
||||
|
||||
/**
|
||||
* binomial (n choose m).
|
||||
*
|
||||
* @param n
|
||||
* the numerator. Equals the size of the set to choose from.
|
||||
* @param m
|
||||
* the denominator. Equals the number of elements to select.
|
||||
* @return the binomial coefficient.
|
||||
* @since 2009-05-19
|
||||
* @author Richard J. Mathar
|
||||
* @throws Error
|
||||
*/
|
||||
public static Rational binomial(final Rational n, final int m) throws Error {
|
||||
if (m == 0) {
|
||||
return Rational.ONE;
|
||||
}
|
||||
Rational bin = n;
|
||||
for (int i = 2; i <= m; i++) {
|
||||
bin = bin.multiply(n.subtract(i - 1)).divide(i);
|
||||
}
|
||||
return bin;
|
||||
} /* Rational.binomial */
|
||||
|
||||
/**
|
||||
* Hankel's symbol (n,k)
|
||||
*
|
||||
* @param n
|
||||
* the first parameter.
|
||||
* @param k
|
||||
* the second parameter, greater or equal to 0.
|
||||
* @return Gamma(n+k+1/2)/k!/GAMMA(n-k+1/2)
|
||||
* @since 2010-07-18
|
||||
* @author Richard J. Mathar
|
||||
* @throws Error
|
||||
*/
|
||||
public static Rational hankelSymb(final Rational n, final int k) throws Error {
|
||||
if (k == 0) {
|
||||
return Rational.ONE;
|
||||
} else if (k < 0) {
|
||||
throw new Error(Errors.NEGATIVE_PARAMETER);
|
||||
}
|
||||
Rational nkhalf = n.subtract(k).add(Rational.HALF);
|
||||
nkhalf = nkhalf.Pochhammer(2 * k);
|
||||
final Factorial f = new Factorial();
|
||||
return nkhalf.divide(f.at(k));
|
||||
} /* Rational.binomial */
|
||||
|
||||
/**
|
||||
* Get the numerator.
|
||||
*
|
||||
* @return The numerator of the reduced fraction.
|
||||
*/
|
||||
public BigInteger numer() {
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the denominator.
|
||||
*
|
||||
* @return The denominator of the reduced fraction.
|
||||
*/
|
||||
public BigInteger denom() {
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Absolute value.
|
||||
*
|
||||
* @return The absolute (non-negative) value of this.
|
||||
*/
|
||||
public Rational abs() {
|
||||
return new Rational(a.abs(), b.abs());
|
||||
}
|
||||
|
||||
/**
|
||||
* floor(): the nearest integer not greater than this.
|
||||
*
|
||||
* @return The integer rounded towards negative infinity.
|
||||
*/
|
||||
public BigInteger floor() {
|
||||
/*
|
||||
* is already integer: return the numerator
|
||||
*/
|
||||
if (b.compareTo(BigInteger.ONE) == 0) {
|
||||
return a;
|
||||
} else if (a.compareTo(BigInteger.ZERO) > 0) {
|
||||
return a.divide(b);
|
||||
} else {
|
||||
return a.divide(b).subtract(BigInteger.ONE);
|
||||
}
|
||||
} /* Rational.floor */
|
||||
|
||||
/**
|
||||
* ceil(): the nearest integer not smaller than this.
|
||||
*
|
||||
* @return The integer rounded towards positive infinity.
|
||||
* @since 2010-05-26
|
||||
*/
|
||||
public BigInteger ceil() {
|
||||
/*
|
||||
* is already integer: return the numerator
|
||||
*/
|
||||
if (b.compareTo(BigInteger.ONE) == 0) {
|
||||
return a;
|
||||
} else if (a.compareTo(BigInteger.ZERO) > 0) {
|
||||
return a.divide(b).add(BigInteger.ONE);
|
||||
} else {
|
||||
return a.divide(b);
|
||||
}
|
||||
} /* Rational.ceil */
|
||||
|
||||
/**
|
||||
* Remove the fractional part.
|
||||
*
|
||||
* @return The integer rounded towards zero.
|
||||
*/
|
||||
public BigInteger trunc() {
|
||||
/*
|
||||
* is already integer: return the numerator
|
||||
*/
|
||||
if (b.compareTo(BigInteger.ONE) == 0) {
|
||||
return a;
|
||||
} else {
|
||||
return a.divide(b);
|
||||
}
|
||||
} /* Rational.trunc */
|
||||
|
||||
/**
|
||||
* Compares the value of this with another constant.
|
||||
*
|
||||
* @param val
|
||||
* the other constant to compare with
|
||||
* @return -1, 0 or 1 if this number is numerically less than, equal to, or
|
||||
* greater than val.
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(final Rational val) {
|
||||
/*
|
||||
* Since we have always kept the denominators positive, simple
|
||||
* cross-multiplying works without changing the sign.
|
||||
*/
|
||||
final BigInteger left = a.multiply(val.b);
|
||||
final BigInteger right = val.a.multiply(b);
|
||||
return left.compareTo(right);
|
||||
} /* Rational.compareTo */
|
||||
|
||||
/**
|
||||
* Compares the value of this with another constant.
|
||||
*
|
||||
* @param val
|
||||
* the other constant to compare with
|
||||
* @return -1, 0 or 1 if this number is numerically less than, equal to, or
|
||||
* greater than val.
|
||||
*/
|
||||
public int compareTo(final BigInteger val) {
|
||||
final Rational val2 = new Rational(val, BigInteger.ONE);
|
||||
return compareTo(val2);
|
||||
} /* Rational.compareTo */
|
||||
|
||||
/**
|
||||
* Return a string in the format number/denom. If the denominator equals 1,
|
||||
* print just the numerator without a slash.
|
||||
*
|
||||
* @return the human-readable version in base 10
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
if (b.compareTo(BigInteger.ONE) != 0) {
|
||||
return a.toString() + "/" + b.toString();
|
||||
} else {
|
||||
return a.toString();
|
||||
}
|
||||
} /* Rational.toString */
|
||||
|
||||
/**
|
||||
* Return a double value representation.
|
||||
*
|
||||
* @return The value with double precision.
|
||||
* @since 2008-10-26
|
||||
*/
|
||||
public double doubleValue() {
|
||||
/*
|
||||
* To meet the risk of individual overflows of the exponents of a
|
||||
* separate invocation a.doubleValue() or b.doubleValue(), we divide
|
||||
* first in a BigDecimal environment and convert the result.
|
||||
*/
|
||||
final BigDecimal adivb = new BigDecimal(a).divide(new BigDecimal(b), MathContext.DECIMAL128);
|
||||
return adivb.doubleValue();
|
||||
} /* Rational.doubleValue */
|
||||
|
||||
/**
|
||||
* Return a float value representation.
|
||||
*
|
||||
* @return The value with single precision.
|
||||
* @since 2009-08-06
|
||||
*/
|
||||
public float floatValue() {
|
||||
final BigDecimal adivb = new BigDecimal(a).divide(new BigDecimal(b), MathContext.DECIMAL128);
|
||||
return adivb.floatValue();
|
||||
} /* Rational.floatValue */
|
||||
|
||||
/**
|
||||
* Return a representation as BigDecimal.
|
||||
*
|
||||
* @param mc
|
||||
* the mathematical context which determines precision, rounding
|
||||
* mode etc
|
||||
* @return A representation as a BigDecimal floating point number.
|
||||
* @since 2008-10-26
|
||||
*/
|
||||
public BigDecimal BigDecimalValue(final MathContext mc) {
|
||||
/*
|
||||
* numerator and denominator individually rephrased
|
||||
*/
|
||||
final BigDecimal n = new BigDecimal(a);
|
||||
final BigDecimal d = new BigDecimal(b);
|
||||
/*
|
||||
* the problem with n.divide(d,mc) is that the apparent precision might
|
||||
* be smaller than what is set by mc if the value has a precise
|
||||
* truncated representation. 1/4 will appear as 0.25, independent of mc
|
||||
*/
|
||||
return BigDecimalMath.scalePrec(n.divide(d, mc), mc);
|
||||
} /* Rational.BigDecimalValue */
|
||||
|
||||
/**
|
||||
* Return a string in floating point format.
|
||||
*
|
||||
* @param digits
|
||||
* The precision (number of digits)
|
||||
* @return The human-readable version in base 10.
|
||||
* @since 2008-10-25
|
||||
*/
|
||||
public String toFString(final int digits) {
|
||||
if (b.compareTo(BigInteger.ONE) != 0) {
|
||||
final MathContext mc = new MathContext(digits, RoundingMode.DOWN);
|
||||
final BigDecimal f = new BigDecimal(a).divide(new BigDecimal(b), mc);
|
||||
return f.toString();
|
||||
} else {
|
||||
return a.toString();
|
||||
}
|
||||
} /* Rational.toFString */
|
||||
|
||||
/**
|
||||
* Compares the value of this with another constant.
|
||||
*
|
||||
* @param val
|
||||
* The other constant to compare with
|
||||
* @return The arithmetic maximum of this and val.
|
||||
* @since 2008-10-19
|
||||
*/
|
||||
public Rational max(final Rational val) {
|
||||
if (compareTo(val) > 0) {
|
||||
return this;
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
} /* Rational.max */
|
||||
|
||||
/**
|
||||
* Compares the value of this with another constant.
|
||||
*
|
||||
* @param val
|
||||
* The other constant to compare with
|
||||
* @return The arithmetic minimum of this and val.
|
||||
* @since 2008-10-19
|
||||
*/
|
||||
public Rational min(final Rational val) {
|
||||
if (compareTo(val) < 0) {
|
||||
return this;
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
} /* Rational.min */
|
||||
|
||||
/**
|
||||
* Compute Pochhammer's symbol (this)_n.
|
||||
*
|
||||
* @param n
|
||||
* The number of product terms in the evaluation.
|
||||
* @return Gamma(this+n)/Gamma(this) = this*(this+1)*...*(this+n-1).
|
||||
* @since 2008-10-25
|
||||
*/
|
||||
public Rational Pochhammer(final BigInteger n) {
|
||||
if (n.compareTo(BigInteger.ZERO) < 0) {
|
||||
return null;
|
||||
} else if (n.compareTo(BigInteger.ZERO) == 0) {
|
||||
return Rational.ONE;
|
||||
} else {
|
||||
/*
|
||||
* initialize results with the current value
|
||||
*/
|
||||
Rational res = new Rational(a, b);
|
||||
BigInteger i = BigInteger.ONE;
|
||||
for (; i.compareTo(n) < 0; i = i.add(BigInteger.ONE)) {
|
||||
res = res.multiply(add(i));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
} /* Rational.pochhammer */
|
||||
|
||||
/**
|
||||
* Compute pochhammer's symbol (this)_n.
|
||||
*
|
||||
* @param n
|
||||
* The number of product terms in the evaluation.
|
||||
* @return Gamma(this+n)/GAMMA(this).
|
||||
* @since 2008-11-13
|
||||
*/
|
||||
public Rational Pochhammer(final int n) {
|
||||
return Pochhammer(new BigInteger("" + n));
|
||||
} /* Rational.pochhammer */
|
||||
|
||||
/**
|
||||
* True if the value is integer. Equivalent to the indication whether a
|
||||
* conversion to an integer can be exact.
|
||||
*
|
||||
* @since 2010-05-26
|
||||
*/
|
||||
public boolean isBigInteger() {
|
||||
return b.abs().compareTo(BigInteger.ONE) == 0;
|
||||
} /* Rational.isBigInteger */
|
||||
|
||||
/**
|
||||
* True if the value is integer and in the range of the standard integer.
|
||||
* Equivalent to the indication whether a conversion to an integer can be
|
||||
* exact.
|
||||
*
|
||||
* @since 2010-05-26
|
||||
*/
|
||||
public boolean isInteger() {
|
||||
if (!isBigInteger()) {
|
||||
return false;
|
||||
}
|
||||
return a.compareTo(Rational.MAX_INT) <= 0 && a.compareTo(Rational.MIN_INT) >= 0;
|
||||
} /* Rational.isInteger */
|
||||
|
||||
/**
|
||||
* Conversion to an integer value, if this can be done exactly.
|
||||
*
|
||||
* @throws Error
|
||||
*
|
||||
* @since 2011-02-13
|
||||
*/
|
||||
int intValue() throws Error {
|
||||
if (!isInteger()) {
|
||||
throw new Error(Errors.CONVERSION_ERROR);
|
||||
}
|
||||
return a.intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversion to a BigInteger value, if this can be done exactly.
|
||||
*
|
||||
* @throws Error
|
||||
*
|
||||
* @since 2012-03-02
|
||||
*/
|
||||
BigInteger BigIntegerValue() throws Error {
|
||||
if (!isBigInteger()) {
|
||||
throw new Error(Errors.CONVERSION_ERROR);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if the value is a fraction of two integers in the range of the
|
||||
* standard integer.
|
||||
*
|
||||
* @since 2010-05-26
|
||||
*/
|
||||
public boolean isIntegerFrac() {
|
||||
return a.compareTo(Rational.MAX_INT) <= 0 && a.compareTo(Rational.MIN_INT) >= 0 && b.compareTo(Rational.MAX_INT) <= 0 && b.compareTo(Rational.MIN_INT) >= 0;
|
||||
} /* Rational.isIntegerFrac */
|
||||
|
||||
/**
|
||||
* The sign: 1 if the number is >0, 0 if ==0, -1 if <0
|
||||
*
|
||||
* @return the signum of the value.
|
||||
* @since 2010-05-26
|
||||
*/
|
||||
public int signum() {
|
||||
return b.signum() * a.signum();
|
||||
} /* Rational.signum */
|
||||
|
||||
/**
|
||||
* Common lcm of the denominators of a set of rational values.
|
||||
*
|
||||
* @param vals
|
||||
* The list/set of the rational values.
|
||||
* @return LCM(denom of first, denom of second, ..,denom of last)
|
||||
* @since 2012-03-02
|
||||
*/
|
||||
static public BigInteger lcmDenom(final Rational[] vals) {
|
||||
BigInteger l = BigInteger.ONE;
|
||||
for (final Rational val : vals) {
|
||||
l = BigIntegerMath.lcm(l, val.b);
|
||||
}
|
||||
return l;
|
||||
} /* Rational.lcmDenom */
|
||||
|
||||
/**
|
||||
* Normalize to coprime numerator and denominator. Also copy a negative sign
|
||||
* of the denominator to the numerator.
|
||||
*
|
||||
* @since 2008-10-19
|
||||
*/
|
||||
protected void normalize() {
|
||||
/*
|
||||
* compute greatest common divisor of numerator and denominator
|
||||
*/
|
||||
final BigInteger g = a.gcd(b);
|
||||
if (g.compareTo(BigInteger.ONE) > 0) {
|
||||
a = a.divide(g);
|
||||
b = b.divide(g);
|
||||
}
|
||||
if (b.compareTo(BigInteger.ZERO) == -1) {
|
||||
a = a.negate();
|
||||
b = b.negate();
|
||||
}
|
||||
} /* Rational.normalize */
|
||||
} /* Rational */
|
@ -1,27 +0,0 @@
|
||||
package org.nevec.rjm;
|
||||
|
||||
import java.math.MathContext;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
import it.cavallium.warppi.Engine;
|
||||
import it.cavallium.warppi.Platform.ConsoleUtils;
|
||||
|
||||
public final class SafeMathContext {
|
||||
|
||||
public static MathContext newMathContext(int precision) {
|
||||
if (precision <= 0) {
|
||||
Engine.getPlatform().getConsoleUtils().out().print(ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN, "Warning! MathContext precision is <= 0 (" + precision + ")");
|
||||
precision = 1;
|
||||
}
|
||||
return new MathContext(precision);
|
||||
}
|
||||
|
||||
public static MathContext newMathContext(int precision, final RoundingMode roundingMode) {
|
||||
if (precision <= 0) {
|
||||
Engine.getPlatform().getConsoleUtils().out().print(ConsoleUtils.OUTPUTLEVEL_DEBUG_MIN, "Warning! MathContext precision is <= 0 (" + precision + ")");
|
||||
precision = 1;
|
||||
}
|
||||
return new MathContext(precision, roundingMode);
|
||||
}
|
||||
|
||||
}
|
@ -1,628 +0,0 @@
|
||||
package org.nevec.rjm;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Scanner;
|
||||
|
||||
import it.cavallium.warppi.util.Error;
|
||||
|
||||
/**
|
||||
* Exact representations of Wigner 3jm and 3nj values of half-integer arguments.
|
||||
*
|
||||
* @see R. J. Mathar, <a href="http://arxiv.org/abs/1102.5125">Corrigendum to
|
||||
* "Universal factorzation fo 3n-j (j>2) symbols ..[J. Phys. A: Math. Gen.37 (2004) 3259]"
|
||||
* </a>
|
||||
* @see R. J. Mathar, <a href="http://vixra.org/abs/1202.0093">Symmetries in
|
||||
* Wigner 18-j and 21-j Symbols</a>
|
||||
* @since 2011-02-15
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public class Wigner3j {
|
||||
/**
|
||||
* Test programs. This supports three types of direct evaluations:<br>
|
||||
* java -cp . org.nevec.rjm.Wigner3j 3jm 2j1+1 2j2+1 2j3+1 2m1+1 2m2+1 2m3+1
|
||||
* <br>
|
||||
* java -cp . org.nevec.rjm.Wigner3j 6j 2j1+1 2j2+2 .. 2j6+1<br>
|
||||
* java -cp . org.nevec.rjm.Wigner3j 9j 2j1+1 2j2+2 .. 2j9+1<br>
|
||||
* The first command line argument is one of the three tags which determine
|
||||
* whether a 3jm, a 6j or a 9j symbol will be computed. The other arguments
|
||||
* are 6 or 9 integer values, which are the physical (half-integer) values
|
||||
* multplied by 2 and augmented by 1. The order of the 6 or 9 values is as
|
||||
* reading the corresponding standard symbol as first row, then second row
|
||||
* (and for the 9j symbol) third row.
|
||||
*
|
||||
* @since 2011-02-15
|
||||
* @author Richard J. Mathar
|
||||
* @throws Error
|
||||
*/
|
||||
static public void main(final String args[]) throws Error {
|
||||
if (args[0].compareTo("6j") == 0) {
|
||||
try {
|
||||
final String m1 = "6";
|
||||
final String t1 = "1 2 -3 -1 5 6";
|
||||
final String t2 = "4 -5 3 -4 -2 -6";
|
||||
String j = "";
|
||||
for (int i = 1; i <= 6; i++) {
|
||||
j += args[i] + " ";
|
||||
}
|
||||
final BigSurdVec w = Wigner3j.wigner3j(m1, t1, t2, j);
|
||||
System.out.println(w.toString());
|
||||
} catch (final Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
} else if (args[0].compareTo("9j") == 0) {
|
||||
try {
|
||||
final String m1 = "9";
|
||||
final String t1 = "1 3 2 4 6 5 7 9 8";
|
||||
final String t2 = "2 8 5 6 3 9 7 4 1";
|
||||
String j = "";
|
||||
for (int i = 1; i <= 9; i++) {
|
||||
j += args[i] + " ";
|
||||
}
|
||||
final BigSurdVec w = Wigner3j.wigner3j(m1, t1, t2, j);
|
||||
System.out.println(w.toString());
|
||||
} catch (final Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
} else if (args[0].compareTo("3jm") == 0) {
|
||||
final int j1 = new Integer(args[1]).intValue();
|
||||
final int j2 = new Integer(args[2]).intValue();
|
||||
final int j3 = new Integer(args[3]).intValue();
|
||||
final int m1 = new Integer(args[4]).intValue();
|
||||
final int m2 = new Integer(args[5]).intValue();
|
||||
final int m3 = new Integer(args[6]).intValue();
|
||||
try {
|
||||
BigSurd w = Wigner3j.wigner3jm(j1, j2, j3, m1, m2, m3);
|
||||
System.out.println(w.toString());
|
||||
w = w.multiply(new BigSurd(j3 + 1, 1));
|
||||
System.out.println("CG factor sqrt" + (j3 + 1) + "sign " + (j2 - j2 - m3) / 2 + " " + w.toString());
|
||||
} catch (final Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
} else {
|
||||
System.out.println("usage:");
|
||||
System.out.println(args[0] + " 6j 2j1+1 2j2+1 2j3+1 2j4+1 2j5+1 2j6+1");
|
||||
System.out.println(args[0] + " 9j 2j1+1 2j2+1 2j3+1 2j4+1 2j5+1 2j6+1.. 2j9+1 ");
|
||||
System.out.println(args[0] + " 3jm 2j1+1 2j2+1 2j3+1 2m1+1 2m2+1 2m3+1 ");
|
||||
}
|
||||
} /* Wigner3j.main */
|
||||
|
||||
/**
|
||||
* The Wigner 3jm symbol (j1,j2,j3,m1,m2,m3). All arguments of the function
|
||||
* are the actual parameters multiplied by 2, so they all allow an integer
|
||||
* representation.
|
||||
*
|
||||
* @param j1
|
||||
* integer representing 2*j1
|
||||
* @param j2
|
||||
* integer representing 2*j2
|
||||
* @param j3
|
||||
* integer representing 2*j3
|
||||
* @param m1
|
||||
* integer representing 2*m1
|
||||
* @param m2
|
||||
* integer representing 2*m2
|
||||
* @param m3
|
||||
* integer representing 2*m3
|
||||
* @return The value of the symbol. Zero if any of the triangular
|
||||
* inequalities is violated or some parameters are out of range.
|
||||
* @since 2011-02-13
|
||||
* @author Richard J. Mathar
|
||||
* @throws Error
|
||||
*/
|
||||
static public BigSurd wigner3jm(final int j1, final int j2, final int j3, final int m1, final int m2, final int m3)
|
||||
throws Error {
|
||||
final Rational J1 = new Rational(j1, 2);
|
||||
final Rational J2 = new Rational(j2, 2);
|
||||
final Rational J3 = new Rational(j3, 2);
|
||||
final Rational M1 = new Rational(m1, 2);
|
||||
final Rational M2 = new Rational(m2, 2);
|
||||
final Rational M3 = new Rational(m3, 2);
|
||||
return Wigner3j.wigner3jm(J1, J2, J3, M1, M2, M3);
|
||||
} /* wigner3jm */
|
||||
|
||||
/**
|
||||
* Wigner 3jn symbol. For the 6j symbol, the input of the 3 lines is
|
||||
* "1 2 3 1 5 6", "4 5 3 4 2 6" "2j1+1 2j2+1 2j3+1 2l1+1 2l2+1 2l3+1"
|
||||
*
|
||||
* @param m1
|
||||
* The information on the number of angular momenta.
|
||||
* @param t1
|
||||
* The list of one half of the triads, indexing j, whitespace
|
||||
* separated
|
||||
* @param t2
|
||||
* The list of the second half of the triads, indexing j,
|
||||
* whitespace separated
|
||||
* @param j
|
||||
* The list of the integer values of the angular momenta. They
|
||||
* are actually the doubled j-values plus 1, whitespace
|
||||
* separated. Only as many as announced by the m1 parameter are
|
||||
* used; trailing numbers are ignored.
|
||||
* @see A. Bar-Shalom and M. Klapisch,
|
||||
* <a href="https://doi.org/10.1016/0010-4655(88)90192-0">NJGRAF...
|
||||
* </a>, Comp. Phys Comm. 50 (3) (1988) 375
|
||||
* @since 2011-02-13
|
||||
* @since 2012-02-15 Upgraded return value to BigSurdVec
|
||||
* @author Richard J. Mathar
|
||||
* @throws Error
|
||||
*/
|
||||
static public BigSurdVec wigner3j(final String m1, final String t1, final String t2, final String j) throws Error {
|
||||
/*
|
||||
* The first number in the line "m" is the number of angular momenta.
|
||||
* The rest of the line is ignored.
|
||||
*/
|
||||
Scanner s = new Scanner(m1);
|
||||
final int m = s.nextInt();
|
||||
if (m % 3 != 0) {
|
||||
s.close();
|
||||
throw new IllegalArgumentException("Angular momenta " + m + " not a multiple of three.");
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan the numbers in the line "j". Excess numbers beyond what has been
|
||||
* announced in the "m" line are ignored.
|
||||
*/
|
||||
final int[] jvec = new int[m];
|
||||
final int[] tvec = new int[2 * m];
|
||||
|
||||
s.close();
|
||||
|
||||
/*
|
||||
* the third row contains positive 2j+1.
|
||||
*/
|
||||
s = new Scanner(j);
|
||||
int ji = 0;
|
||||
while (s.hasNextInt() && ji < m) {
|
||||
jvec[ji++] = s.nextInt();
|
||||
if (jvec[ji - 1] < 1) {
|
||||
s.close();
|
||||
throw new IllegalArgumentException("Illegal value " + jvec[ji - 1] + " for 2j+1.");
|
||||
}
|
||||
}
|
||||
|
||||
s.close();
|
||||
|
||||
/*
|
||||
* the first two rows contain signed values of indices into the j list
|
||||
*/
|
||||
s = new Scanner(t1);
|
||||
int ti = 0;
|
||||
while (s.hasNextInt()) {
|
||||
tvec[ti++] = s.nextInt();
|
||||
}
|
||||
|
||||
s.close();
|
||||
|
||||
s = new Scanner(t2);
|
||||
while (s.hasNextInt()) {
|
||||
tvec[ti++] = s.nextInt();
|
||||
}
|
||||
|
||||
/*
|
||||
* Basic sanity checks. All indices in the first two lines address a
|
||||
* number in the third line, and each index occurs exactly twice.
|
||||
*/
|
||||
if (ji % 3 != 0) {
|
||||
s.close();
|
||||
throw new IllegalArgumentException("j-count " + ji + " not a multiple of three.");
|
||||
}
|
||||
if (ti != 2 * ji) {
|
||||
s.close();
|
||||
throw new IllegalArgumentException("triad-count " + ti + " not twice j-count " + ji);
|
||||
}
|
||||
|
||||
final int[] jfreq = new int[m];
|
||||
for (ji = 0; ji < jfreq.length; ji++) {
|
||||
jfreq[ji] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* maintain a 0-based index which shows where the j-value has its first
|
||||
* and second occurrence in the flattened list of triads.
|
||||
*/
|
||||
final int[][] jhash = new int[m][2];
|
||||
|
||||
for (ti = 0; ti < 2 * m; ti++) {
|
||||
final int t = tvec[ti];
|
||||
if (t == 0 || Math.abs(t) > jvec.length) {
|
||||
s.close();
|
||||
throw new IllegalArgumentException("Triad index " + t + " out of bounds");
|
||||
}
|
||||
if (jfreq[Math.abs(t) - 1] >= 2) {
|
||||
s.close();
|
||||
throw new IllegalArgumentException("Node " + t + " referenced more than twice");
|
||||
}
|
||||
jhash[Math.abs(t) - 1][jfreq[Math.abs(t) - 1]] = ti;
|
||||
jfreq[Math.abs(t) - 1]++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Move on from the 2j+1 values of the input to the j-values. Subtract
|
||||
* one and divide through 2.
|
||||
*/
|
||||
final Rational[] J = new Rational[jvec.length];
|
||||
for (ji = 0; ji < jvec.length; ji++) {
|
||||
J[ji] = new Rational(jvec[ji] - 1, 2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the 1-based indices to 0-based indices, loosing the sign
|
||||
* information.
|
||||
*/
|
||||
final int[] triadidx = new int[tvec.length];
|
||||
for (ti = 0; ti < tvec.length; ti++) {
|
||||
triadidx[ti] = Math.abs(tvec[ti]) - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The M-values are all null (undetermined) at the start.
|
||||
*/
|
||||
final Rational[] M = new Rational[J.length];
|
||||
s.close();
|
||||
return Wigner3j.wigner3j(tvec, J, M, triadidx);
|
||||
} /* wigner3j */
|
||||
|
||||
/**
|
||||
* Wigner 3jn symbol. Computes sum_{mi} (-1)^(j1-m1+j2-m2+...)
|
||||
* triad(triadidx[0..2])*triad(triadidx[3..5])*... where each factor is a
|
||||
* Wigner-3jm symbol with each sign of m_i occurring once at the
|
||||
* corresponding l-value.
|
||||
*
|
||||
* @param triadidx
|
||||
* 0-based indices into the list of J
|
||||
* @param J
|
||||
* The list of J-values
|
||||
* @param M
|
||||
* The list of M-values associated with the J. This contains null
|
||||
* where the parameter has not yet been set by an outer loop.
|
||||
* @since 2011-02-13
|
||||
* @since 2012-02-15 Upgraded to return BigSurdVec
|
||||
* @author Richard J. Mathar
|
||||
* @throws Error
|
||||
*/
|
||||
static private BigSurdVec wigner3j(final int[] tvec, final Rational[] J, final Rational[] M, final int[] triadidx)
|
||||
throws Error {
|
||||
/*
|
||||
* The result of the computation. The sum over all m-combinations of the
|
||||
* triads.
|
||||
*/
|
||||
BigSurdVec res = new BigSurdVec();
|
||||
|
||||
/*
|
||||
* First step is to monitor the triangular conditions on the J. If at
|
||||
* least one is violated, the result is zero. Loop over the triads.
|
||||
*/
|
||||
for (int t = 0; t < triadidx.length; t += 3) {
|
||||
/* 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) {
|
||||
return res;
|
||||
}
|
||||
if (J[triadidx[t]].add(J[triadidx[t + 1]]).compareTo(J[triadidx[t + 2]]) < 0) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* the index of the preferred member of the triad list. Preference given
|
||||
* to those dangling in triads where alreaday two others are fixed, then
|
||||
* to members where at least one is fixed, then to smallest associated
|
||||
* J-values.
|
||||
*/
|
||||
int freeM = -1;
|
||||
int freeMrank = -1;
|
||||
for (int i = 0; i < triadidx.length; i++) {
|
||||
/*
|
||||
* found an m-value which has not yet been summed over.
|
||||
*/
|
||||
if (M[triadidx[i]] == null) {
|
||||
/*
|
||||
* two cases: value is fixed implicitly because already two
|
||||
* others values are set in the triad. or it is still to
|
||||
* maintain its own explicit loop.
|
||||
*/
|
||||
final int triadn = i / 3;
|
||||
final int triadr = i % 3;
|
||||
/*
|
||||
* the neighbors in the triad have indices triadn*3+ (tiradr+1)
|
||||
* mod 3 and triadn*3+(triadr+2) mod3
|
||||
*/
|
||||
final int nei1 = 3 * triadn + (triadr + 1) % 3;
|
||||
final int nei2 = 3 * triadn + (triadr + 2) % 3;
|
||||
|
||||
/*
|
||||
* found a candidate for which the two other values are already
|
||||
* set.
|
||||
*/
|
||||
if (M[triadidx[nei1]] != null && M[triadidx[nei2]] != null) {
|
||||
freeM = i;
|
||||
break;
|
||||
} else {
|
||||
/*
|
||||
* rough work load estimator: basically (2J1+1)*(2J2+1)
|
||||
*/
|
||||
Rational wt = J[triadidx[i]].multiply(2).add(1);
|
||||
if (M[triadidx[nei1]] == null) {
|
||||
wt = wt.multiply(J[triadidx[nei1]].multiply(2).add(1));
|
||||
}
|
||||
if (M[triadidx[nei2]] == null) {
|
||||
wt = wt.multiply(J[triadidx[nei2]].multiply(2).add(1));
|
||||
}
|
||||
final int thiswt = wt.intValue();
|
||||
if (freeM < 0 || thiswt < freeMrank) {
|
||||
freeM = i;
|
||||
freeMrank = thiswt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (freeM >= 0) {
|
||||
/*
|
||||
* found an m-value which has not yet been summed over.
|
||||
*/
|
||||
if (M[triadidx[freeM]] == null) {
|
||||
final Rational[] childM = new Rational[M.length];
|
||||
for (int ji = 0; ji < M.length; ji++) {
|
||||
if (M[ji] != null) {
|
||||
childM[ji] = M[ji];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* two cases: value is fixed implicitly because already two
|
||||
* others values are set in the triad. or it is still to
|
||||
* maintain its own explicit loop.
|
||||
*/
|
||||
final int triadn = freeM / 3;
|
||||
final int triadr = freeM % 3;
|
||||
/*
|
||||
* the neighbors in the triad have indices triadn*3+ (triadr+1)
|
||||
* mod 3 and triadn*3+(triadr+2) mod3
|
||||
*/
|
||||
final int nei1 = 3 * triadn + (triadr + 1) % 3;
|
||||
final int nei2 = 3 * triadn + (triadr + 2) % 3;
|
||||
if (M[triadidx[nei1]] == null || M[triadidx[nei2]] == null) {
|
||||
/*
|
||||
* The J-value is J[triadidx[freeM]]. Loop from -J to +J,
|
||||
* the allowed range.
|
||||
*/
|
||||
Rational newm = J[triadidx[freeM]].negate();
|
||||
while (newm.compareTo(J[triadidx[freeM]]) <= 0) {
|
||||
childM[triadidx[freeM]] = tvec[freeM] > 0 ? newm : newm.negate();
|
||||
res = res.add(Wigner3j.wigner3j(tvec, J, childM, triadidx));
|
||||
newm = newm.add(Rational.ONE);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Set its value and the value at its companion j-value. Sum
|
||||
* of the three m-values in the triad is to be zero for a
|
||||
* non-zero contribution.
|
||||
*/
|
||||
Rational m1 = M[triadidx[nei1]];
|
||||
Rational m2 = M[triadidx[nei2]];
|
||||
/*
|
||||
* negate if these are the second occurrences of the J in
|
||||
* the triads
|
||||
*/
|
||||
if (tvec[nei1] < 0) {
|
||||
m1 = m1.negate();
|
||||
}
|
||||
if (tvec[nei2] < 0) {
|
||||
m2 = m2.negate();
|
||||
}
|
||||
/* m3 = -(m1+m2) */
|
||||
final Rational newm = tvec[freeM] > 0 ? m1.add(m2).negate() : m1.add(m2);
|
||||
/*
|
||||
* No contribution if the m-value enforced by the other two
|
||||
* entries is outside the range -|J|..|J| enforced by its
|
||||
* associated J-value. One could essentially remove this
|
||||
* branching and let wigner3j() decide on this, but this is
|
||||
* inefficient.
|
||||
*/
|
||||
if (newm.abs().compareTo(J[triadidx[freeM]]) <= 0) {
|
||||
childM[triadidx[freeM]] = newm;
|
||||
res = res.add(Wigner3j.wigner3j(tvec, J, childM, triadidx));
|
||||
}
|
||||
/*
|
||||
* zero contribution if this m-value cannot be set to any
|
||||
* value compatible with the triangular conditions.
|
||||
*/
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* reached the bottom of the loop where all M-values are assigned. Build
|
||||
* the product over all Wigner-3jm values and the associated sign.
|
||||
*/
|
||||
res = BigSurdVec.ONE;
|
||||
for (int ji = 0; ji < triadidx.length; ji += 3) {
|
||||
Rational m1 = M[triadidx[ji]];
|
||||
Rational m2 = M[triadidx[ji + 1]];
|
||||
Rational m3 = M[triadidx[ji + 2]];
|
||||
/*
|
||||
* negate if these are associated with in-flowing vectors in the
|
||||
* triads
|
||||
*/
|
||||
if (tvec[ji] < 0) {
|
||||
m1 = m1.negate();
|
||||
}
|
||||
if (tvec[ji + 1] < 0) {
|
||||
m2 = m2.negate();
|
||||
}
|
||||
if (tvec[ji + 2] < 0) {
|
||||
m3 = m3.negate();
|
||||
}
|
||||
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,
|
||||
* and offers an early exit.
|
||||
*/
|
||||
if (res.signum() == 0) {
|
||||
return BigSurdVec.ZERO;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* The overal sign is product_{J-Mpairs} (-1)^(J-M). This is an integer
|
||||
* because all the J-M are integer.
|
||||
*/
|
||||
Rational sig = new Rational();
|
||||
for (int ji = 0; ji < J.length; ji++) {
|
||||
sig = sig.add(J[ji]).subtract(M[ji]);
|
||||
}
|
||||
/*
|
||||
* sign depends on the sum being even or odd. We assume that "sig" is
|
||||
* integer and look only at the numerator
|
||||
*/
|
||||
if (sig.a.abs().testBit(0)) {
|
||||
res = res.negate();
|
||||
}
|
||||
return res;
|
||||
} /* wigner3j */
|
||||
|
||||
/**
|
||||
* The Wigner 3jm symbol (j1,j2,j3,m1,m2,m3). Warning: there is no check
|
||||
* that each argument is indeed half-integer.
|
||||
*
|
||||
* @param j1
|
||||
* integer or half-integer j1
|
||||
* @param j2
|
||||
* integer or half-integer j2
|
||||
* @param j3
|
||||
* integer or half-integer j3
|
||||
* @param m1
|
||||
* integer or half-integer m1
|
||||
* @param m2
|
||||
* integer or half-integer m2
|
||||
* @param m3
|
||||
* integer or half-integer m3
|
||||
* @return The value of the symbol. Zero if any of the triangular
|
||||
* inequalities is violated or some parameters are out of range.
|
||||
* @since 2011-02-13
|
||||
* @author Richard J. Mathar
|
||||
* @throws Error
|
||||
*/
|
||||
static protected BigSurd wigner3jm(final Rational j1, final Rational j2, final Rational j3, final Rational m1,
|
||||
final Rational m2, final Rational m3) throws Error {
|
||||
/*
|
||||
* Check that m1+m2+m3 = 0
|
||||
*/
|
||||
if (m1.add(m2).add(m3).signum() != 0) {
|
||||
return BigSurd.ZERO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that j1+j2+j3 is integer
|
||||
*/
|
||||
if (j1.add(j2).add(j3).isBigInteger() == false) {
|
||||
return BigSurd.ZERO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that |j1-j2|<=j3 <= |j1+j2|
|
||||
*/
|
||||
final Rational j1m2 = j1.subtract(j2);
|
||||
if (j1m2.abs().compareTo(j3) > 0) {
|
||||
return BigSurd.ZERO;
|
||||
}
|
||||
final Rational j1p2 = j1.add(j2);
|
||||
if (j1p2.abs().compareTo(j3) < 0) {
|
||||
return BigSurd.ZERO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that |m_i| <= j_i
|
||||
*/
|
||||
if (m1.abs().compareTo(j1) > 0 || m2.abs().compareTo(j2) > 0 || m3.abs().compareTo(j3) > 0) {
|
||||
return BigSurd.ZERO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that m_i-j_i are integer.
|
||||
*/
|
||||
if (!m1.subtract(j1).isBigInteger() || !m2.subtract(j2).isBigInteger() || !m3.subtract(j3).isBigInteger()) {
|
||||
return BigSurd.ZERO;
|
||||
}
|
||||
|
||||
/*
|
||||
* (-)^(j1-j2-m3)*delta(-m3,m1+m2)*sqrt[ (j3+j1-j2)! (j3-j1+j2)!
|
||||
* (j1+j2-j3)! /(j1+j2+j3+1)!
|
||||
* *(j3-m)!*(j3+m)!(j1-m1)!*(j1+m1)!*(j2-m2)!*(j2+m2)!] *sum_k
|
||||
* (-1)^k/[k!(j1+j2-j3-k)!(j1-m1-k)!(j2+m2-k)!(j3-j2+m1+k)!)*(j3-j1-m2+k
|
||||
* )!]
|
||||
*/
|
||||
|
||||
/*
|
||||
* It is tacitly assumed that all the major j_i, m_i values are in the
|
||||
* integer range. This is implicitly plausible since otherwise the
|
||||
* execution times of the following loop over the k-values would be
|
||||
* immense.
|
||||
*/
|
||||
int j1j2jk = j1p2.subtract(j3).intValue();
|
||||
int j1m1k = j1.subtract(m1).intValue();
|
||||
int j2m2k = j2.add(m2).intValue();
|
||||
int jj2m1k = j3.subtract(j2).add(m1).intValue();
|
||||
int jj1m2k = j3.subtract(j1).subtract(m2).intValue();
|
||||
|
||||
int k = Math.max(0, -jj2m1k);
|
||||
k = Math.max(k, -jj1m2k);
|
||||
if (k > 0) {
|
||||
j1j2jk -= k;
|
||||
j1m1k -= k;
|
||||
j2m2k -= k;
|
||||
jj2m1k += k;
|
||||
jj1m2k += k;
|
||||
}
|
||||
|
||||
final Factorial f = new Factorial();
|
||||
Rational sumk = new Rational();
|
||||
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));
|
||||
if (k % 2 == 0) {
|
||||
sumk = sumk.add(new Rational(BigInteger.ONE, d));
|
||||
} else {
|
||||
sumk = sumk.subtract(new Rational(BigInteger.ONE, d));
|
||||
}
|
||||
j1j2jk--;
|
||||
j1m1k--;
|
||||
j2m2k--;
|
||||
jj2m1k++;
|
||||
jj1m2k++;
|
||||
if (j1j2jk < 0 || j1m1k < 0 || j2m2k < 0) {
|
||||
break;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
/*
|
||||
* sign factor (-1)^(j1-j2-m3)
|
||||
*/
|
||||
if (j1m2.subtract(m3).intValue() % 2 != 0) {
|
||||
sumk = sumk.negate();
|
||||
}
|
||||
|
||||
k = j1m2.add(j3).intValue();
|
||||
BigInteger s = f.at(k);
|
||||
k = j3.subtract(j1m2).intValue();
|
||||
s = s.multiply(f.at(k));
|
||||
k = j1p2.subtract(j3).intValue();
|
||||
s = s.multiply(f.at(k));
|
||||
k = j3.add(m3).intValue();
|
||||
s = s.multiply(f.at(k));
|
||||
k = j3.subtract(m3).intValue();
|
||||
s = s.multiply(f.at(k));
|
||||
k = j1.add(m1).intValue();
|
||||
s = s.multiply(f.at(k));
|
||||
k = j1.subtract(m1).intValue();
|
||||
s = s.multiply(f.at(k));
|
||||
k = j2.add(m2).intValue();
|
||||
s = s.multiply(f.at(k));
|
||||
k = j2.subtract(m2).intValue();
|
||||
s = s.multiply(f.at(k));
|
||||
k = j1p2.add(j3).intValue();
|
||||
k++;
|
||||
final Rational disc = new Rational(s, f.at(k));
|
||||
return new BigSurd(sumk, disc);
|
||||
} /* wigner3jm */
|
||||
|
||||
} /* Wigner3j */
|
@ -1,335 +0,0 @@
|
||||
package org.nevec.rjm;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Label;
|
||||
import java.awt.TextArea;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.Scanner;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
|
||||
import it.cavallium.warppi.util.Error;
|
||||
|
||||
/**
|
||||
* An interactive interface to the Wigner3j class. The GUI allows to preselect
|
||||
* one of the symbols if the number of j-terms is small (6j up to 15j), or to
|
||||
* enter any other connectivity for the triads of j-values. The actual j-values
|
||||
* are entered as integers (2j+1) and the computation of one value (in exact
|
||||
* square root representation) is started manually.
|
||||
*
|
||||
* @since 2011-02-15
|
||||
*/
|
||||
public class Wigner3jGUI implements ActionListener, ListSelectionListener {
|
||||
/**
|
||||
* The master window of the session
|
||||
*/
|
||||
JFrame fram;
|
||||
|
||||
/*
|
||||
* global labels
|
||||
*/
|
||||
Label Lbl0;
|
||||
Label Lbl1;
|
||||
|
||||
JButton sear;
|
||||
JList<?> searJ;
|
||||
String[] searOpt = { "6j", "9j", "12j 1st", "12j 2nd (not symm)", "15j 1st", "15j 2nd", "15j 3rd", "15j 4th", "15j 5th" };
|
||||
|
||||
/**
|
||||
* Field with the triads inputs
|
||||
*/
|
||||
TextArea inpGtria;
|
||||
|
||||
/**
|
||||
* Field with the J-value inputs
|
||||
*/
|
||||
TextArea inpGjval;
|
||||
|
||||
/**
|
||||
* Field of the outputs.
|
||||
*/
|
||||
TextArea outG;
|
||||
|
||||
GridBagLayout gridbag;
|
||||
GridBagConstraints gridconstr;
|
||||
|
||||
/**
|
||||
* @since 2011-02-15
|
||||
*/
|
||||
public void init() {
|
||||
fram = new JFrame("Wigner3jGUI");
|
||||
|
||||
Lbl0 = new Label("Input: (Triads upper area, values 2J+1 second area");
|
||||
Lbl1 = new Label("Output:");
|
||||
|
||||
sear = new JButton("Compute");
|
||||
sear.setActionCommand("compute");
|
||||
sear.addActionListener(this);
|
||||
sear.setToolTipText("Compute a general 3jn value");
|
||||
|
||||
searJ = new JList<Object>(searOpt);
|
||||
searJ.setLayoutOrientation(JList.HORIZONTAL_WRAP);
|
||||
searJ.addListSelectionListener(this);
|
||||
|
||||
final Font defFont = new Font("Monospaced", Font.PLAIN, 11);
|
||||
|
||||
fram.setBackground(new Color(250, 250, 250));
|
||||
fram.setForeground(new Color(0, 0, 0));
|
||||
final Color fg = new Color(0, 200, 0);
|
||||
final Color bg = new Color(10, 10, 10);
|
||||
|
||||
gridbag = new GridBagLayout();
|
||||
fram.setLayout(gridbag);
|
||||
|
||||
gridconstr = new GridBagConstraints();
|
||||
gridconstr.gridx = 0;
|
||||
gridconstr.gridy = GridBagConstraints.RELATIVE;
|
||||
|
||||
inpGtria = new TextArea("", 4, 80);
|
||||
inpGtria.setFont(defFont);
|
||||
inpGtria.setForeground(fg);
|
||||
inpGtria.setBackground(bg);
|
||||
|
||||
inpGjval = new TextArea("", 10, 80);
|
||||
inpGjval.setFont(defFont);
|
||||
inpGjval.setForeground(fg);
|
||||
inpGjval.setBackground(bg);
|
||||
|
||||
outG = new TextArea("", 12, 80);
|
||||
outG.setEditable(false);
|
||||
outG.setFont(defFont);
|
||||
outG.setForeground(fg);
|
||||
outG.setBackground(bg);
|
||||
|
||||
fram.add(Lbl0);
|
||||
gridbag.setConstraints(Lbl0, gridconstr);
|
||||
|
||||
fram.add(inpGtria);
|
||||
gridbag.setConstraints(inpGtria, gridconstr);
|
||||
|
||||
fram.add(inpGjval);
|
||||
gridbag.setConstraints(inpGjval, gridconstr);
|
||||
|
||||
fram.add(sear);
|
||||
gridbag.setConstraints(sear, gridconstr);
|
||||
fram.add(searJ);
|
||||
gridbag.setConstraints(searJ, gridconstr);
|
||||
|
||||
fram.add(Lbl1);
|
||||
gridbag.setConstraints(Lbl1, gridconstr);
|
||||
|
||||
fram.add(outG);
|
||||
gridbag.setConstraints(outG, gridconstr);
|
||||
|
||||
fram.pack();
|
||||
fram.setVisible(true);
|
||||
} /* init */
|
||||
|
||||
/**
|
||||
* @throws Error
|
||||
* @since 2010-08-27
|
||||
*/
|
||||
public void compute() throws Error {
|
||||
final String tr = inpGtria.getText();
|
||||
final String[] trias = new String[4];
|
||||
|
||||
/*
|
||||
* Read the trias configuration from inpGtria into trias[0..2], skipping
|
||||
* lines that start with a hash mark.
|
||||
*/
|
||||
Scanner s = new Scanner(tr);
|
||||
for (int l = 0; l < 3;) {
|
||||
try {
|
||||
trias[l] = s.nextLine().trim();
|
||||
if (!trias[l].startsWith("#")) {
|
||||
l++;
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
s.close();
|
||||
outG.setText("ERROR: less than 3 lines in the triad definition");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
s.close();
|
||||
|
||||
/*
|
||||
* Read the J values from inpGjval into trias[3] in a loop
|
||||
*/
|
||||
final String j = inpGjval.getText();
|
||||
s = new Scanner(j);
|
||||
while (true) {
|
||||
try {
|
||||
trias[3] = s.nextLine().trim();
|
||||
} catch (final Exception e) {
|
||||
s.close();
|
||||
return;
|
||||
}
|
||||
if (!trias[3].startsWith("#")) {
|
||||
try {
|
||||
final BigSurdVec w = Wigner3j.wigner3j(trias[0], trias[1], trias[2], trias[3]);
|
||||
outG.append(w.toString() + " = " + w.doubleValue());
|
||||
} catch (final Exception e) {
|
||||
outG.append(e.toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
outG.append(" # J = ");
|
||||
final Scanner num = new Scanner(trias[3]);
|
||||
while (num.hasNextInt()) {
|
||||
final int twoj1 = num.nextInt();
|
||||
final Rational jfrac = new Rational(twoj1 - 1, 2);
|
||||
outG.append(jfrac.toString() + " ");
|
||||
}
|
||||
outG.append("\n");
|
||||
num.close();
|
||||
}
|
||||
}
|
||||
} /* compute */
|
||||
|
||||
/**
|
||||
* Interpreter parser loop.
|
||||
*
|
||||
* @param e
|
||||
* the information on which button had been pressed in the GUI
|
||||
* @since 2011-02-15
|
||||
*/
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
final String lin = e.getActionCommand();
|
||||
/*
|
||||
* debugging System.out.println("Ac"+e.paramString()) ;
|
||||
* System.out.println(lin) ;
|
||||
*/
|
||||
if (lin == "compute") {
|
||||
outG.setText("");
|
||||
try {
|
||||
compute();
|
||||
} catch (final Error e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
} /* actionPerformed */
|
||||
|
||||
/**
|
||||
* Interpreter parser loop.
|
||||
*
|
||||
* @param e
|
||||
* the information on which of the 3jn templates had been
|
||||
* selected in the Menu
|
||||
* @since 2011-02-18
|
||||
*/
|
||||
@Override
|
||||
public void valueChanged(final ListSelectionEvent e) {
|
||||
switch (searJ.getMinSelectionIndex()) {
|
||||
case 0:
|
||||
inpGtria.setText("6\n");
|
||||
inpGtria.append("1 2 -3 -1 5 6\n");
|
||||
inpGtria.append("4 -5 3 -4 -2 -6");
|
||||
outG.setText("");
|
||||
break;
|
||||
case 1:
|
||||
/*
|
||||
* Yutsis Figure 18.1 index map. j1=1, j2=2, j3=3 k1=4, k2=5,
|
||||
* k3=6
|
||||
* l1=7, l2=8, l3=9
|
||||
*/
|
||||
inpGtria.setText("9\n");
|
||||
inpGtria.append("1 3 2 4 6 5 7 9 8 # (j1 j3 j2) (k1 k3 k2) (l1 l3 l2)\n");
|
||||
inpGtria.append("-2 -8 -5 -6 -3 -9 -7 -4 -1 # (j2 l2 k2) (k3 j3 l3) (l1 k1 j1)");
|
||||
outG.setText("");
|
||||
break;
|
||||
case 2:
|
||||
/*
|
||||
* Yutsis Figure 19.1 and 19.2, index map, including the sign
|
||||
* reveral of the l. Assume input order j1..j4, l1..l4, k1..k4.
|
||||
* j1=1, j2=2, j3=3, j4=4 l1=5, l2=6, l3=7, l4=8 k1=9, k2=10,
|
||||
* k3=11,
|
||||
* k4=12
|
||||
*/
|
||||
inpGtria.setText("12\n");
|
||||
inpGtria.append("1 12 -8 -1 5 -2 2 6 -3 3 7 -4 # (j1 k4 l4) (j1 l1 j2) (j2 l2 j3) (j3 l3 j4)\n");
|
||||
inpGtria.append("4 8 -9 9 -5 -10 10 -6 -11 11 -7 -12 # (j4 l4 k1) (k1 l1 k2) (k2 l2 k3) (k3 l3 k4)");
|
||||
outG.setText("");
|
||||
break;
|
||||
case 3:
|
||||
inpGtria.setText("12\n");
|
||||
inpGtria.append("1 5 9 -9 -2 -7 2 11 8 -8 -12 -4 # (j1 l1 k1) (k1 j2 l3 ) (j2 k3 l4) (l4 k4 j4)\n");
|
||||
inpGtria.append("4 7 10 -10 -3 -5 3 6 12 -6 -11 -1 # (j4 l3 k2) (k2 j3 l1) (j3 l2 k4) (l2 k3 j1)");
|
||||
outG.setText("");
|
||||
break;
|
||||
case 4:
|
||||
/*
|
||||
* Yutsis Figure 20.2 to 20.3, index map. j1=1, j2=2, j3=3,
|
||||
* j4=4,
|
||||
* j5=5 l1=6, l2=7, l3=8, l4=9, l5=10 k1=11, k2=12, k3=13,
|
||||
* k4=14,
|
||||
* k5=15
|
||||
*/
|
||||
inpGtria.setText("15\n");
|
||||
inpGtria.append("1 -6 2 -2 -7 3 -3 -8 4 -4 -9 5 -5 -10 11 # (j1 l1 j2)(j2 l2 j3)(j3 l3 j4)(j4 l4 j5)(j5 l5 k1)\n");
|
||||
inpGtria.append("-11 6 12 -12 7 13 -13 8 14 -14 9 15 -15 10 -1 # (k1 l1 k2)(k2 l2 k3)(k3 l3 k4)(k4 l4 k5)(k5 l5 j1)");
|
||||
outG.setText("");
|
||||
break;
|
||||
case 5:
|
||||
inpGtria.setText("15\n");
|
||||
inpGtria.append("-1 -6 2 -2 -7 3 -3 -8 4 -4 -9 5 1 -5 -10 # (j1 l1 j2)(j2 l2 j3)(j3 l3 j4)(j4 l4 j5)(j1 j5 l5)\n");
|
||||
inpGtria.append("11 -15 10 9 15 -14 8 14 -13 7 13 -12 6 12 -11 # (k1 k5 l5)(l4 k5 k4)(l3 k4 k3)(l2 k3 k2)(l1 k2 k1)");
|
||||
outG.setText("");
|
||||
break;
|
||||
case 6:
|
||||
/*
|
||||
* Yutsis Figure 20.4a, index map. k1=1, k1'=2, k=3, k'=4, k2=5,
|
||||
* k2'=6 p1=7, p=8, p2=9, j1=10, j1'=11 j=12 j'=13 j2=14 j2'=15
|
||||
*/
|
||||
inpGtria.setText("15\n");
|
||||
inpGtria.append("-13 -12 -8 12 14 10 -10 -1 7 -7 -11 -2 2 4 6 # (j' j p)(j j2 j1)(j1 k1 p1)(p1 j1' k1')(k1' k' k2')\n");
|
||||
inpGtria.append("-4 -3 8 1 3 5 -14 -5 9 -15 -6 -9 15 11 13 # (k' k p)(k1 k k2)(j2 k2 p2)(j2' k2' p2)(j2' j1' j')");
|
||||
outG.setText("");
|
||||
break;
|
||||
case 7:
|
||||
/*
|
||||
* Yutsis Figure 20.5a, index map. j1=1, k1=2 s1=3 k1'=4 j1'=5
|
||||
* p=6
|
||||
* l=7 s=8 l'=9 p'=10 j2=11 k2=12 s2=13 k2'=14 j2'=15
|
||||
*/
|
||||
inpGtria.setText("15\n");
|
||||
inpGtria.append("-14 -12 -8 12 11 -10 -11 13 -7 7 -1 3 2 1 6 # (k2' k2 s)(k2 j2 p')(j2 s2 l)(l j1 s1)(k1 j1 p)\n");
|
||||
inpGtria.append("-4 -2 8 10 4 5 9 -5 -3 -13 -9 -15 15 -6 14 # (k1' k1 s)(p' k1' j1')(l' j1' s1)(s2 l' j2')(j2' p k2')");
|
||||
outG.setText("");
|
||||
break;
|
||||
case 8:
|
||||
/*
|
||||
* Yutsis Figure 20.6, index map. k1=1 k1'=2 j1=3 l1=4 l1'=5
|
||||
* k2=6
|
||||
* k2'=7 j2=8 l2=9 l2'=10 k3=11 k3'=12 j3=13 l3=14 l3'=15
|
||||
*/
|
||||
inpGtria.setText("15\n");
|
||||
inpGtria.append("-15 1 -7 -4 -11 7 5 4 -3 -12 -5 6 12 -9 -1 # (l3' k1 k2')(l1 k3 k2')(l1' l1 j1)(k3' l1' k2)(k3' l2 k1)\n");
|
||||
inpGtria.append("9 -8 10 -10 11 -2 -14 -6 2 14 -13 15 3 8 13 # (l2 j2 l2')(l2' k3 k1')(l3 k2 k1')(l3 j3 l3')(j1 j2 j3)");
|
||||
outG.setText("");
|
||||
break;
|
||||
}
|
||||
} /* valueChanged */
|
||||
|
||||
/**
|
||||
* Main entry point. not taking any command line options:<br>
|
||||
* java -jar Wigner3jGUI.jar<br>
|
||||
*
|
||||
* @since 2012-02-16
|
||||
* @author Richard J. Mathar
|
||||
*/
|
||||
public static void main(final String[] args) {
|
||||
final Wigner3jGUI g = new Wigner3jGUI();
|
||||
g.init();
|
||||
} /* main */
|
||||
|
||||
} /* Wigner3jGUI */
|
BIN
core/src/main/resources/tetrisskin.png
Normal file
BIN
core/src/main/resources/tetrisskin.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
BIN
core/src/main/resources/tetrisskin.xcf
Normal file
BIN
core/src/main/resources/tetrisskin.xcf
Normal file
Binary file not shown.
@ -6,24 +6,22 @@
|
||||
<parent>
|
||||
<groupId>it.cavallium</groupId>
|
||||
<artifactId>warppi</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<version>0.9.0a3</version>
|
||||
</parent>
|
||||
<artifactId>warppi-desktop</artifactId>
|
||||
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<name>WarpPI Calculator Desktop</name>
|
||||
<description>WarpPI Calculator desktop project</description>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>it.cavallium</groupId>
|
||||
<artifactId>warppi-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<version>0.9.0a3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>it.cavallium</groupId>
|
||||
<artifactId>warppi-engine-jogl</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<version>0.9.0a3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.fusesource.jansi</groupId>
|
||||
@ -55,23 +53,15 @@
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Import-Package>*</Import-Package>
|
||||
<Export-Package>it.cavallium.warppi.*</Export-Package>
|
||||
<Bundle-SymbolicName>warppi-desktop</Bundle-SymbolicName>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- Maven Assembly Plugin -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
|
@ -1,16 +1,30 @@
|
||||
package it.cavallium.warppi.desktop;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import ar.com.hjg.pngj.ImageLineInt;
|
||||
import it.cavallium.warppi.Platform.PngUtils.PngReader;
|
||||
import it.cavallium.warppi.Engine;
|
||||
import it.cavallium.warppi.Platform.ImageUtils.ImageReader;
|
||||
|
||||
public class DesktopPngReader implements PngReader {
|
||||
public class DesktopImageReader implements ImageReader {
|
||||
|
||||
private final ar.com.hjg.pngj.PngReader r;
|
||||
private ar.com.hjg.pngj.PngReader r;
|
||||
|
||||
public DesktopPngReader(final InputStream resourceStream) {
|
||||
public DesktopImageReader(final InputStream resourceStream) throws IOException {
|
||||
r = new ar.com.hjg.pngj.PngReader(resourceStream);
|
||||
// Try to read image converting it to png
|
||||
if (r == null) {
|
||||
final File f = File.createTempFile("picalculator-png", ".png");
|
||||
f.deleteOnExit();
|
||||
final BufferedImage img = ImageIO.read(resourceStream);
|
||||
ImageIO.write(img, "PNG", f);
|
||||
r = new ar.com.hjg.pngj.PngReader(f);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
@ -0,0 +1,16 @@
|
||||
package it.cavallium.warppi.desktop;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import it.cavallium.warppi.Platform.ImageUtils.ImageReader;
|
||||
import it.cavallium.warppi.Platform.ImageUtils;
|
||||
|
||||
public class DesktopImageUtils implements ImageUtils {
|
||||
|
||||
@Override
|
||||
public ImageReader load(final InputStream resourceStream) throws IOException {
|
||||
return new DesktopImageReader(resourceStream);
|
||||
}
|
||||
|
||||
}
|
@ -26,16 +26,17 @@ public class DesktopPlatform implements Platform {
|
||||
private final DesktopConsoleUtils cu;
|
||||
private final DesktopGpio gi;
|
||||
private final DesktopStorageUtils su;
|
||||
private final PngUtils pu;
|
||||
private final ImageUtils pu;
|
||||
private final String on;
|
||||
private final Map<String, GraphicEngine> el;
|
||||
private final DesktopSettings settings;
|
||||
private Boolean runningOnRaspberryOverride = null;
|
||||
|
||||
public DesktopPlatform() {
|
||||
cu = new DesktopConsoleUtils();
|
||||
gi = new DesktopGpio();
|
||||
su = new DesktopStorageUtils();
|
||||
pu = new DesktopPngUtils();
|
||||
pu = new DesktopImageUtils();
|
||||
on = System.getProperty("os.name").toLowerCase();
|
||||
el = new HashMap<>();
|
||||
el.put("CPU engine", new SwingEngine());
|
||||
@ -59,7 +60,7 @@ public class DesktopPlatform implements Platform {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PngUtils getPngUtils() {
|
||||
public ImageUtils getImageUtils() {
|
||||
return pu;
|
||||
}
|
||||
|
||||
@ -205,8 +206,18 @@ public class DesktopPlatform implements Platform {
|
||||
return org.eclipse.jdt.internal.compiler.batch.Main.compile(command, printWriter, errors, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRunningOnRaspberry(boolean b) {
|
||||
if (isRunningOnRaspberry()) {
|
||||
runningOnRaspberryOverride = b;
|
||||
} else {
|
||||
runningOnRaspberryOverride = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunningOnRaspberry() {
|
||||
if (runningOnRaspberryOverride != null) return runningOnRaspberryOverride;
|
||||
return CacheUtils.get("isRunningOnRaspberry", 24 * 60 * 60 * 1000, () -> {
|
||||
if (Engine.getPlatform().isJavascript())
|
||||
return false;
|
||||
|
@ -1,14 +0,0 @@
|
||||
package it.cavallium.warppi.desktop;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import it.cavallium.warppi.Platform.PngUtils;
|
||||
|
||||
public class DesktopPngUtils implements PngUtils {
|
||||
|
||||
@Override
|
||||
public PngReader load(final InputStream resourceStream) {
|
||||
return new DesktopPngReader(resourceStream);
|
||||
}
|
||||
|
||||
}
|
@ -54,7 +54,7 @@ public class SwingEngine implements GraphicEngine {
|
||||
exitSemaphore = new Semaphore(0);
|
||||
INSTANCE = new SwingWindow(this);
|
||||
setResizable(Engine.getPlatform().getSettings().isDebugEnabled());
|
||||
setDisplayMode(StaticVars.screenSize[0], StaticVars.screenSize[1]);
|
||||
setDisplayMode((int) (StaticVars.screenSize[0] / StaticVars.windowZoom.getLastValue()), (int) (StaticVars.screenSize[1] / StaticVars.windowZoom.getLastValue()));
|
||||
INSTANCE.setVisible(true);
|
||||
initialized = true;
|
||||
if (onInitialized != null)
|
||||
|
@ -244,21 +244,16 @@ public class SwingWindow extends JFrame {
|
||||
b.setFont(f);
|
||||
b.setBackground(new Color(200, 200, 200));
|
||||
b.setFocusable(true);
|
||||
b.addActionListener(e -> {
|
||||
Keyboard.keyPressedRaw(row, col);
|
||||
Keyboard.keyReleasedRaw(row, col);
|
||||
c.grabFocus();
|
||||
});
|
||||
b.addMouseListener(new MouseListener() {
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
Keyboard.keyRaw(row, col, true);
|
||||
c.grabFocus();
|
||||
}
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
Keyboard.keyRaw(row, col, false);
|
||||
c.grabFocus();
|
||||
}
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
@ -377,6 +372,7 @@ public class SwingWindow extends JFrame {
|
||||
if (renderingLoop != null) {
|
||||
renderingLoop.refresh();
|
||||
|
||||
|
||||
final int[] a = ((DataBufferInt) display.g.getRaster().getDataBuffer()).getData();
|
||||
SwingRenderer.canvas2d = a;
|
||||
g.clearRect(0, 0, display.r.size[0] * mult, display.r.size[1] * mult);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user