Some FPS and TPS fixes

This commit is contained in:
PeytonPlayz595 2024-06-01 17:21:40 -04:00
parent 1824fdd15b
commit 0dfb8cf3cc
26 changed files with 12896 additions and 24 deletions

View File

@ -55,6 +55,12 @@ public class ClientPlatformSingleplayer {
} else if(s.equals("smoothWorld:false")) { } else if(s.equals("smoothWorld:false")) {
MinecraftServer.smoothWorld = false; MinecraftServer.smoothWorld = false;
return; return;
} else if(s.contains("fullbright:true")) {
MinecraftServer.isFullBright = true;
return;
} else if(s.contains("fullbright:false")) {
MinecraftServer.isFullBright = false;
return;
} else if(s.contains("ofTrees")) { } else if(s.contains("ofTrees")) {
String[] value = s.split(":"); String[] value = s.split(":");
int i = Integer.parseInt(value[1]); int i = Integer.parseInt(value[1]);

View File

@ -53,6 +53,12 @@ public class ServerPlatformSingleplayer {
} else if(s.equals("smoothWorld:false")) { } else if(s.equals("smoothWorld:false")) {
MinecraftServer.smoothWorld = false; MinecraftServer.smoothWorld = false;
return; return;
} else if(s.contains("fullbright:true")) {
MinecraftServer.isFullBright = true;
return;
} else if(s.contains("fullbright:false")) {
MinecraftServer.isFullBright = false;
return;
} else if(s.contains("ofTrees")) { } else if(s.contains("ofTrees")) {
String[] value = s.split(":"); String[] value = s.split(":");
int i = Integer.parseInt(value[1]); int i = Integer.parseInt(value[1]);

View File

@ -1241,6 +1241,7 @@ public class Minecraft implements IThreadListener {
/**+ /**+
* Runs the current tick. * Runs the current tick.
*/ */
public boolean packetsSent = false;
public void runTick() throws IOException { public void runTick() throws IOException {
if (this.rightClickDelayTimer > 0) { if (this.rightClickDelayTimer > 0) {
--this.rightClickDelayTimer; --this.rightClickDelayTimer;
@ -1663,20 +1664,24 @@ public class Minecraft implements IThreadListener {
this.fixWorldTime(); this.fixWorldTime();
} }
if(Config.isWeatherEnabled()) { if(!packetsSent) {
ClientPlatformSingleplayer.sendPacket(new IPCPacketData("iFuckingHateWebworkers", "weather:true".getBytes())); if(Config.isWeatherEnabled()) {
} else { ClientPlatformSingleplayer.sendPacket(new IPCPacketData("iFuckingHateWebworkers", "weather:true".getBytes()));
ClientPlatformSingleplayer.sendPacket(new IPCPacketData("iFuckingHateWebworkers", "weather:false".getBytes())); } else {
} ClientPlatformSingleplayer.sendPacket(new IPCPacketData("iFuckingHateWebworkers", "weather:false".getBytes()));
}
if(Config.isSmoothWorld()) { if(Config.isSmoothWorld()) {
ClientPlatformSingleplayer.sendPacket(new IPCPacketData("iFuckingHateWebworkers", "smoothWorld:true".getBytes())); ClientPlatformSingleplayer.sendPacket(new IPCPacketData("iFuckingHateWebworkers", "smoothWorld:true".getBytes()));
} else { } else {
ClientPlatformSingleplayer.sendPacket(new IPCPacketData("iFuckingHateWebworkers", "smoothWorld:false".getBytes())); ClientPlatformSingleplayer.sendPacket(new IPCPacketData("iFuckingHateWebworkers", "smoothWorld:false".getBytes()));
} }
ClientPlatformSingleplayer.sendPacket(new IPCPacketData("iFuckingHateWebworkers", new String("ofTrees:" + gameSettings.ofTrees).getBytes())); ClientPlatformSingleplayer.sendPacket(new IPCPacketData("iFuckingHateWebworkers", new String("ofTrees:" + gameSettings.ofTrees).getBytes()));
ClientPlatformSingleplayer.sendPacket(new IPCPacketData("iFuckingHateWebworkers", new String("graphics:" + gameSettings.fancyGraphics).getBytes())); ClientPlatformSingleplayer.sendPacket(new IPCPacketData("iFuckingHateWebworkers", new String("graphics:" + gameSettings.fancyGraphics).getBytes()));
ClientPlatformSingleplayer.sendPacket(new IPCPacketData("iFuckingHateWebworkers", new String("fullbright:" + gameSettings.fullBright).getBytes()));
packetsSent = true;
}
if (Config.waterOpacityChanged) { if (Config.waterOpacityChanged) {
Config.waterOpacityChanged = false; Config.waterOpacityChanged = false;
@ -1812,6 +1817,7 @@ public class Minecraft implements IThreadListener {
this.guiAchievement.clearAchievements(); this.guiAchievement.clearAchievements();
this.entityRenderer.getMapItemRenderer().clearLoadedMaps(); this.entityRenderer.getMapItemRenderer().clearLoadedMaps();
packetsSent = false;
} }
this.renderViewEntity = null; this.renderViewEntity = null;

View File

@ -332,6 +332,8 @@ public class GameSettings {
* value), this will set the float value. * value), this will set the float value.
*/ */
public void setOptionFloatValue(GameSettings.Options parOptions, float parFloat1) { public void setOptionFloatValue(GameSettings.Options parOptions, float parFloat1) {
Minecraft.getMinecraft().packetsSent = false;
if (parOptions == GameSettings.Options.SENSITIVITY) { if (parOptions == GameSettings.Options.SENSITIVITY) {
this.mouseSensitivity = parFloat1; this.mouseSensitivity = parFloat1;
} }
@ -451,6 +453,8 @@ public class GameSettings {
* through the list i.e. render distances. * through the list i.e. render distances.
*/ */
public void setOptionValue(GameSettings.Options parOptions, int parInt1) { public void setOptionValue(GameSettings.Options parOptions, int parInt1) {
Minecraft.getMinecraft().packetsSent = false;
if (parOptions == GameSettings.Options.INVERT_MOUSE) { if (parOptions == GameSettings.Options.INVERT_MOUSE) {
this.invertMouse = !this.invertMouse; this.invertMouse = !this.invertMouse;
} }

View File

@ -505,6 +505,10 @@ public class RenderGlobal implements IWorldAccess, IResourceManagerReloadListene
} }
public void renderEntities(Entity renderViewEntity, ICamera camera, float partialTicks) { public void renderEntities(Entity renderViewEntity, ICamera camera, float partialTicks) {
boolean b = true;
if(entityCantBeSeen(renderViewEntity)) {
return;
}
if (this.renderEntitiesStartupCounter > 0) { if (this.renderEntitiesStartupCounter > 0) {
--this.renderEntitiesStartupCounter; --this.renderEntitiesStartupCounter;
} else { } else {
@ -2289,6 +2293,10 @@ public class RenderGlobal implements IWorldAccess, IResourceManagerReloadListene
private EntityFX spawnEntityFX(int p_174974_1_, boolean ignoreRange, double p_174974_3_, double p_174974_5_, double p_174974_7_, double p_174974_9_, double p_174974_11_, double p_174974_13_, int... p_174974_15_) { private EntityFX spawnEntityFX(int p_174974_1_, boolean ignoreRange, double p_174974_3_, double p_174974_5_, double p_174974_7_, double p_174974_9_, double p_174974_11_, double p_174974_13_, int... p_174974_15_) {
if (this.mc != null && this.mc.getRenderViewEntity() != null && this.mc.effectRenderer != null) { if (this.mc != null && this.mc.getRenderViewEntity() != null && this.mc.effectRenderer != null) {
if(isBehindPlayer(new BlockPos(p_174974_3_, p_174974_5_, p_174974_7_))) {
return null;
}
int i = this.mc.gameSettings.particleSetting; int i = this.mc.gameSettings.particleSetting;
if (i == 1 && this.theWorld.rand.nextInt(3) == 0) { if (i == 1 && this.theWorld.rand.nextInt(3) == 0) {
@ -2384,6 +2392,22 @@ public class RenderGlobal implements IWorldAccess, IResourceManagerReloadListene
} }
} }
private boolean isBehindPlayer(BlockPos target) {
final Vec3 playerToBlock = new Vec3 (target.getX() - this.mc.thePlayer.posX, target.getY() - this.mc.thePlayer.posY, target.getZ() - this.mc.thePlayer.posZ).normalize();
final Vec3 direction = (this.mc.thePlayer.getLookVec()).normalize();
return playerToBlock.dotProduct(direction) > 0.5;
}
private boolean entityCantBeSeen(Entity target) {
if (mc.gameSettings.thirdPersonView != 1)
return false;
final Vec3 direction = (this.mc.thePlayer.getLookVec()).normalize();
final Vec3 targetToPlayer = (target.getPositionVector().subtract(this.mc.thePlayer.getPositionVector())).normalize();
return (direction.dotProduct(targetToPlayer) < 0.0) ;
}
/**+ /**+
* Called on all IWorldAccesses when an entity is created or * Called on all IWorldAccesses when an entity is created or
* loaded. On client worlds, starts downloading any necessary * loaded. On client worlds, starts downloading any necessary

View File

@ -1066,5 +1066,6 @@ public abstract class MinecraftServer implements Runnable, ICommandSender, IThre
public static boolean weather = true; public static boolean weather = true;
public static boolean smoothWorld = false; public static boolean smoothWorld = false;
public static boolean fancyGraphics = false; public static boolean fancyGraphics = false;
public static boolean isFullBright = false;
public static int trees = 0; public static int trees = 0;
} }

View File

@ -1,5 +1,7 @@
package net.minecraft.util; package net.minecraft.util;
import org.apache.commons.math3.util.FastMath;
import net.lax1dude.eaglercraft.v1_8.EaglercraftRandom; import net.lax1dude.eaglercraft.v1_8.EaglercraftRandom;
import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID; import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
@ -41,6 +43,9 @@ public class MathHelper {
* sin looked up in a table * sin looked up in a table
*/ */
public static float sin(float parFloat1) { public static float sin(float parFloat1) {
if(fastMath) {
return (float) FastMath.sin(parFloat1);
}
return fastMath ? SIN_TABLE_FAST[(int)(parFloat1 * 651.8986F) & 4095] : SIN_TABLE[(int)(parFloat1 * 10430.378F) & 65535]; return fastMath ? SIN_TABLE_FAST[(int)(parFloat1 * 651.8986F) & 4095] : SIN_TABLE[(int)(parFloat1 * 10430.378F) & 65535];
} }
@ -48,14 +53,23 @@ public class MathHelper {
* cos looked up in the sin table with the appropriate offset * cos looked up in the sin table with the appropriate offset
*/ */
public static float cos(float value) { public static float cos(float value) {
if(fastMath) {
return (float) FastMath.cos(value);
}
return fastMath ? SIN_TABLE_FAST[(int)((value + ((float)Math.PI / 2F)) * 651.8986F) & 4095] : SIN_TABLE[(int)(value * 10430.378F + 16384.0F) & 65535]; return fastMath ? SIN_TABLE_FAST[(int)((value + ((float)Math.PI / 2F)) * 651.8986F) & 4095] : SIN_TABLE[(int)(value * 10430.378F + 16384.0F) & 65535];
} }
public static float sqrt_float(float value) { public static float sqrt_float(float value) {
if(fastMath) {
return (float) FastMath.sqrt(value);
}
return (float) Math.sqrt((double) value); return (float) Math.sqrt((double) value);
} }
public static float sqrt_double(double value) { public static float sqrt_double(double value) {
if(fastMath) {
return (float) FastMath.sqrt(value);
}
return (float) Math.sqrt(value); return (float) Math.sqrt(value);
} }
@ -64,6 +78,9 @@ public class MathHelper {
* argument * argument
*/ */
public static int floor_float(float value) { public static int floor_float(float value) {
if(fastMath) {
return (int) FastMath.floor(value);
}
int i = (int) value; int i = (int) value;
return value < (float) i ? i - 1 : i; return value < (float) i ? i - 1 : i;
} }
@ -81,6 +98,9 @@ public class MathHelper {
* argument * argument
*/ */
public static int floor_double(double value) { public static int floor_double(double value) {
if(fastMath) {
return (int) FastMath.floor(value);
}
int i = (int) value; int i = (int) value;
return value < (double) i ? i - 1 : i; return value < (double) i ? i - 1 : i;
} }
@ -89,6 +109,9 @@ public class MathHelper {
* Long version of floor_double * Long version of floor_double
*/ */
public static long floor_double_long(double value) { public static long floor_double_long(double value) {
if(fastMath) {
return (long) FastMath.floor(value);
}
long i = (long) value; long i = (long) value;
return value < (double) i ? i - 1L : i; return value < (double) i ? i - 1L : i;
} }
@ -98,6 +121,9 @@ public class MathHelper {
} }
public static float abs(float value) { public static float abs(float value) {
if(fastMath) {
return (float) FastMath.abs(value);
}
return value >= 0.0F ? value : -value; return value >= 0.0F ? value : -value;
} }
@ -105,6 +131,9 @@ public class MathHelper {
* Returns the unsigned value of an int. * Returns the unsigned value of an int.
*/ */
public static int abs_int(int value) { public static int abs_int(int value) {
if(fastMath) {
return (int) FastMath.abs(value);
}
return value >= 0 ? value : -value; return value >= 0 ? value : -value;
} }

View File

@ -27,6 +27,7 @@ import net.minecraft.block.BlockSnow;
import net.minecraft.block.BlockStairs; import net.minecraft.block.BlockStairs;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.crash.CrashReport; import net.minecraft.crash.CrashReport;
import net.minecraft.crash.CrashReportCategory; import net.minecraft.crash.CrashReportCategory;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
@ -606,6 +607,16 @@ public abstract class World implements IBlockAccess {
} }
public int getLightFromNeighborsFor(EnumSkyBlock type, BlockPos pos) { public int getLightFromNeighborsFor(EnumSkyBlock type, BlockPos pos) {
if(MinecraftServer.getServer() != null) {
if(MinecraftServer.isFullBright) {
return 15;
}
} else {
if(Minecraft.getMinecraft().gameSettings.fullBright) {
return 15;
}
}
if (this.provider.getHasNoSky() && type == EnumSkyBlock.SKY) { if (this.provider.getHasNoSky() && type == EnumSkyBlock.SKY) {
return Chunk.getNoSkyLightValue(); return Chunk.getNoSkyLightValue();
} else { } else {
@ -2342,6 +2353,16 @@ public abstract class World implements IBlockAccess {
} }
public boolean checkLightFor(EnumSkyBlock lightType, BlockPos pos) { public boolean checkLightFor(EnumSkyBlock lightType, BlockPos pos) {
if(MinecraftServer.getServer() != null) {
if(MinecraftServer.isFullBright) {
return true;
}
} else {
if(Minecraft.getMinecraft().gameSettings.fullBright) {
return true;
}
}
if (!this.isAreaLoaded(pos, 17, false)) { if (!this.isAreaLoaded(pos, 17, false)) {
return false; return false;
} else { } else {

View File

@ -15,10 +15,12 @@ import net.minecraft.block.Block;
import net.minecraft.block.ITileEntityProvider; import net.minecraft.block.ITileEntityProvider;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.crash.CrashReport; import net.minecraft.crash.CrashReport;
import net.minecraft.crash.CrashReportCategory; import net.minecraft.crash.CrashReportCategory;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.server.MinecraftServer;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.BlockPos; import net.minecraft.util.BlockPos;
@ -678,6 +680,16 @@ public class Chunk {
} }
public int getLightSubtracted(BlockPos blockpos, int i) { public int getLightSubtracted(BlockPos blockpos, int i) {
if(MinecraftServer.getServer() != null) {
if(MinecraftServer.isFullBright) {
return 15;
}
} else {
if(Minecraft.getMinecraft().gameSettings.fullBright) {
return 15;
}
}
int j = blockpos.getX() & 15; int j = blockpos.getX() & 15;
int k = blockpos.getY(); int k = blockpos.getY();
int l = blockpos.getZ() & 15; int l = blockpos.getZ() & 15;

View File

@ -0,0 +1,64 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math3.exception;
import org.apache.commons.math3.exception.util.LocalizedFormats;
import org.apache.commons.math3.exception.util.Localizable;
/**
* Exception to be thrown when two dimensions differ.
*
* @since 2.2
*/
public class DimensionMismatchException extends MathIllegalNumberException {
/** Serializable version Id. */
private static final long serialVersionUID = -8415396756375798143L;
/** Correct dimension. */
private final int dimension;
/**
* Construct an exception from the mismatched dimensions.
*
* @param specific Specific context information pattern.
* @param wrong Wrong dimension.
* @param expected Expected dimension.
*/
public DimensionMismatchException(Localizable specific,
int wrong,
int expected) {
super(specific, Integer.valueOf(wrong), Integer.valueOf(expected));
dimension = expected;
}
/**
* Construct an exception from the mismatched dimensions.
*
* @param wrong Wrong dimension.
* @param expected Expected dimension.
*/
public DimensionMismatchException(int wrong,
int expected) {
this(LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, wrong, expected);
}
/**
* @return the expected dimension.
*/
public int getDimension() {
return dimension;
}
}

View File

@ -0,0 +1,76 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math3.exception;
import org.apache.commons.math3.exception.util.Localizable;
import org.apache.commons.math3.exception.util.LocalizedFormats;
import org.apache.commons.math3.exception.util.ExceptionContext;
import org.apache.commons.math3.exception.util.ExceptionContextProvider;
/**
* Base class for arithmetic exceptions.
* It is used for all the exceptions that have the semantics of the standard
* {@link ArithmeticException}, but must also provide a localized
* message.
*
* @since 3.0
*/
public class MathArithmeticException extends ArithmeticException
implements ExceptionContextProvider {
/** Serializable version Id. */
private static final long serialVersionUID = -6024911025449780478L;
/** Context. */
private final ExceptionContext context;
/**
* Default constructor.
*/
public MathArithmeticException() {
context = new ExceptionContext(this);
context.addMessage(LocalizedFormats.ARITHMETIC_EXCEPTION);
}
/**
* Constructor with a specific message.
*
* @param pattern Message pattern providing the specific context of
* the error.
* @param args Arguments.
*/
public MathArithmeticException(Localizable pattern,
Object ... args) {
context = new ExceptionContext(this);
context.addMessage(pattern, args);
}
/** {@inheritDoc} */
public ExceptionContext getContext() {
return context;
}
/** {@inheritDoc} */
@Override
public String getMessage() {
return context.getMessage();
}
/** {@inheritDoc} */
@Override
public String getLocalizedMessage() {
return context.getLocalizedMessage();
}
}

View File

@ -0,0 +1,64 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math3.exception;
import org.apache.commons.math3.exception.util.Localizable;
import org.apache.commons.math3.exception.util.ExceptionContext;
import org.apache.commons.math3.exception.util.ExceptionContextProvider;
/**
* Base class for all preconditions violation exceptions.
* In most cases, this class should not be instantiated directly: it should
* serve as a base class to create all the exceptions that have the semantics
* of the standard {@link IllegalArgumentException}.
*
* @since 2.2
*/
public class MathIllegalArgumentException extends IllegalArgumentException
implements ExceptionContextProvider {
/** Serializable version Id. */
private static final long serialVersionUID = -6024911025449780478L;
/** Context. */
private final ExceptionContext context;
/**
* @param pattern Message pattern explaining the cause of the error.
* @param args Arguments.
*/
public MathIllegalArgumentException(Localizable pattern,
Object ... args) {
context = new ExceptionContext(this);
context.addMessage(pattern, args);
}
/** {@inheritDoc} */
public ExceptionContext getContext() {
return context;
}
/** {@inheritDoc} */
@Override
public String getMessage() {
return context.getMessage();
}
/** {@inheritDoc} */
@Override
public String getLocalizedMessage() {
return context.getLocalizedMessage();
}
}

View File

@ -0,0 +1,60 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math3.exception;
import org.apache.commons.math3.exception.util.Localizable;
/**
* Base class for exceptions raised by a wrong number.
* This class is not intended to be instantiated directly: it should serve
* as a base class to create all the exceptions that are raised because some
* precondition is violated by a number argument.
*
* @since 2.2
*/
public class MathIllegalNumberException extends MathIllegalArgumentException {
/** Helper to avoid boxing warnings. @since 3.3 */
protected static final Integer INTEGER_ZERO = Integer.valueOf(0);
/** Serializable version Id. */
private static final long serialVersionUID = -7447085893598031110L;
/** Requested. */
private final Number argument;
/**
* Construct an exception.
*
* @param pattern Localizable pattern.
* @param wrong Wrong number.
* @param arguments Arguments.
*/
protected MathIllegalNumberException(Localizable pattern,
Number wrong,
Object ... arguments) {
super(pattern, wrong, arguments);
argument = wrong;
}
/**
* @return the requested value.
*/
public Number getArgument() {
return argument;
}
}

View File

@ -0,0 +1,55 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math3.exception.util;
import java.util.List;
import java.util.ArrayList;
/**
* Utility class for transforming the list of arguments passed to
* constructors of exceptions.
*
*/
public class ArgUtils {
/**
* Class contains only static methods.
*/
private ArgUtils() {}
/**
* Transform a multidimensional array into a one-dimensional list.
*
* @param array Array (possibly multidimensional).
* @return a list of all the {@code Object} instances contained in
* {@code array}.
*/
public static Object[] flatten(Object[] array) {
final List<Object> list = new ArrayList<Object>();
if (array != null) {
for (Object o : array) {
if (o instanceof Object[]) {
for (Object oR : flatten((Object[]) o)) {
list.add(oR);
}
} else {
list.add(o);
}
}
}
return list.toArray();
}
}

View File

@ -0,0 +1,195 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math3.exception.util;
import java.util.List;
import java.util.ArrayList;
import java.util.Set;
import java.util.Map;
import java.io.Serializable;
import java.util.HashMap;
import java.text.MessageFormat;
import java.util.Locale;
/**
* Class that contains the actual implementation of the functionality mandated
* by the {@link ExceptionContext} interface.
* All Commons Math exceptions delegate the interface's methods to this class.
*
* @since 3.0
*/
public class ExceptionContext implements Serializable {
/** Serializable version Id. */
private static final long serialVersionUID = -6024911025449780478L;
/**
* The throwable to which this context refers to.
*/
private Throwable throwable;
/**
* Various informations that enrich the informative message.
*/
private List<Localizable> msgPatterns;
/**
* Various informations that enrich the informative message.
* The arguments will replace the corresponding place-holders in
* {@link #msgPatterns}.
*/
private List<Object[]> msgArguments;
/**
* Arbitrary context information.
*/
private Map<String, Object> context;
/** Simple constructor.
* @param throwable the exception this context refers too
*/
public ExceptionContext(final Throwable throwable) {
this.throwable = throwable;
msgPatterns = new ArrayList<Localizable>();
msgArguments = new ArrayList<Object[]>();
context = new HashMap<String, Object>();
}
/** Get a reference to the exception to which the context relates.
* @return a reference to the exception to which the context relates
*/
public Throwable getThrowable() {
return throwable;
}
/**
* Adds a message.
*
* @param pattern Message pattern.
* @param arguments Values for replacing the placeholders in the message
* pattern.
*/
public void addMessage(Localizable pattern,
Object ... arguments) {
msgPatterns.add(pattern);
msgArguments.add(ArgUtils.flatten(arguments));
}
/**
* Sets the context (key, value) pair.
* Keys are assumed to be unique within an instance. If the same key is
* assigned a new value, the previous one will be lost.
*
* @param key Context key (not null).
* @param value Context value.
*/
public void setValue(String key, Object value) {
context.put(key, value);
}
/**
* Gets the value associated to the given context key.
*
* @param key Context key.
* @return the context value or {@code null} if the key does not exist.
*/
public Object getValue(String key) {
return context.get(key);
}
/**
* Gets all the keys stored in the exception
*
* @return the set of keys.
*/
public Set<String> getKeys() {
return context.keySet();
}
/**
* Gets the default message.
*
* @return the message.
*/
public String getMessage() {
return getMessage(Locale.US);
}
/**
* Gets the message in the default locale.
*
* @return the localized message.
*/
public String getLocalizedMessage() {
return getMessage(Locale.getDefault());
}
/**
* Gets the message in a specified locale.
*
* @param locale Locale in which the message should be translated.
* @return the localized message.
*/
public String getMessage(final Locale locale) {
return buildMessage(locale, ": ");
}
/**
* Gets the message in a specified locale.
*
* @param locale Locale in which the message should be translated.
* @param separator Separator inserted between the message parts.
* @return the localized message.
*/
public String getMessage(final Locale locale,
final String separator) {
return buildMessage(locale, separator);
}
/**
* Builds a message string.
*
* @param locale Locale in which the message should be translated.
* @param separator Message separator.
* @return a localized message string.
*/
private String buildMessage(Locale locale,
String separator) {
final StringBuilder sb = new StringBuilder();
int count = 0;
final int len = msgPatterns.size();
for (int i = 0; i < len; i++) {
final Localizable pat = msgPatterns.get(i);
final Object[] args = msgArguments.get(i);
final MessageFormat fmt = new MessageFormat(pat.getLocalizedString(locale),
locale);
sb.append(fmt.format(args));
if (++count < len) {
// Add a separator if there are other messages.
sb.append(separator);
}
}
return sb.toString();
}
/**
* Replaces a non-serializable object with an error message string.
*
* @param obj Object that does not implement the {@code Serializable}
* interface.
* @return a string that mentions which class could not be serialized.
*/
private String nonSerializableReplacement(Object obj) {
return "[Object could not be serialized: " + obj.getClass().getName() + "]";
}
}

View File

@ -0,0 +1,33 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math3.exception.util;
/**
* Interface for accessing the context data structure stored in Commons Math
* exceptions.
*
*/
public interface ExceptionContextProvider {
/**
* Gets a reference to the "rich context" data structure that allows to
* customize error messages and store key, value pairs in exceptions.
*
* @return a reference to the exception context.
*/
ExceptionContext getContext();
}

View File

@ -0,0 +1,43 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math3.exception.util;
import java.io.Serializable;
import java.util.Locale;
/**
* Interface for localizable strings.
*
* @since 2.2
*/
public interface Localizable extends Serializable {
/**
* Gets the source (non-localized) string.
*
* @return the source string.
*/
String getSourceString();
/**
* Gets the localized string.
*
* @param locale locale into which to get the string.
* @return the localized string or the source string if no
* localized version is available.
*/
String getLocalizedString(Locale locale);
}

View File

@ -0,0 +1,414 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math3.exception.util;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
/**
* Enumeration for localized messages formats used in exceptions messages.
* <p>
* The constants in this enumeration represent the available
* formats as localized strings. These formats are intended to be
* localized using simple properties files, using the constant
* name as the key and the property value as the message format.
* The source English format is provided in the constants themselves
* to serve both as a reminder for developers to understand the parameters
* needed by each format, as a basis for translators to create
* localized properties files, and as a default format if some
* translation is missing.
* </p>
* @since 2.2
*/
public enum LocalizedFormats implements Localizable {
// CHECKSTYLE: stop MultipleVariableDeclarations
// CHECKSTYLE: stop JavadocVariable
ARGUMENT_OUTSIDE_DOMAIN("Argument {0} outside domain [{1} ; {2}]"),
ARRAY_SIZE_EXCEEDS_MAX_VARIABLES("array size cannot be greater than {0}"),
ARRAY_SIZES_SHOULD_HAVE_DIFFERENCE_1("array sizes should have difference 1 ({0} != {1} + 1)"),
ARRAY_SUMS_TO_ZERO("array sums to zero"),
ASSYMETRIC_EIGEN_NOT_SUPPORTED("eigen decomposition of assymetric matrices not supported yet"),
AT_LEAST_ONE_COLUMN("matrix must have at least one column"),
AT_LEAST_ONE_ROW("matrix must have at least one row"),
BANDWIDTH("bandwidth ({0})"),
BESSEL_FUNCTION_BAD_ARGUMENT("Bessel function of order {0} cannot be computed for x = {1}"),
BESSEL_FUNCTION_FAILED_CONVERGENCE("Bessel function of order {0} failed to converge for x = {1}"),
BINOMIAL_INVALID_PARAMETERS_ORDER("must have n >= k for binomial coefficient (n, k), got k = {0}, n = {1}"),
BINOMIAL_NEGATIVE_PARAMETER("must have n >= 0 for binomial coefficient (n, k), got n = {0}"),
CANNOT_CLEAR_STATISTIC_CONSTRUCTED_FROM_EXTERNAL_MOMENTS("statistics constructed from external moments cannot be cleared"),
CANNOT_COMPUTE_0TH_ROOT_OF_UNITY("cannot compute 0-th root of unity, indefinite result"),
CANNOT_COMPUTE_BETA_DENSITY_AT_0_FOR_SOME_ALPHA("cannot compute beta density at 0 when alpha = {0,number}"),
CANNOT_COMPUTE_BETA_DENSITY_AT_1_FOR_SOME_BETA("cannot compute beta density at 1 when beta = %.3g"),
CANNOT_COMPUTE_NTH_ROOT_FOR_NEGATIVE_N("cannot compute nth root for null or negative n: {0}"),
CANNOT_DISCARD_NEGATIVE_NUMBER_OF_ELEMENTS("cannot discard a negative number of elements ({0})"),
CANNOT_FORMAT_INSTANCE_AS_3D_VECTOR("cannot format a {0} instance as a 3D vector"),
CANNOT_FORMAT_INSTANCE_AS_COMPLEX("cannot format a {0} instance as a complex number"),
CANNOT_FORMAT_INSTANCE_AS_REAL_VECTOR("cannot format a {0} instance as a real vector"),
CANNOT_FORMAT_OBJECT_TO_FRACTION("cannot format given object as a fraction number"),
CANNOT_INCREMENT_STATISTIC_CONSTRUCTED_FROM_EXTERNAL_MOMENTS("statistics constructed from external moments cannot be incremented"),
CANNOT_NORMALIZE_A_ZERO_NORM_VECTOR("cannot normalize a zero norm vector"),
CANNOT_RETRIEVE_AT_NEGATIVE_INDEX("elements cannot be retrieved from a negative array index {0}"),
CANNOT_SET_AT_NEGATIVE_INDEX("cannot set an element at a negative index {0}"),
CANNOT_SUBSTITUTE_ELEMENT_FROM_EMPTY_ARRAY("cannot substitute an element from an empty array"),
CANNOT_TRANSFORM_TO_DOUBLE("Conversion Exception in Transformation: {0}"),
CARDAN_ANGLES_SINGULARITY("Cardan angles singularity"),
CLASS_DOESNT_IMPLEMENT_COMPARABLE("class ({0}) does not implement Comparable"),
CLOSE_VERTICES("too close vertices near point ({0}, {1}, {2})"),
CLOSEST_ORTHOGONAL_MATRIX_HAS_NEGATIVE_DETERMINANT("the closest orthogonal matrix has a negative determinant {0}"),
COLUMN_INDEX_OUT_OF_RANGE("column index {0} out of allowed range [{1}, {2}]"),
COLUMN_INDEX("column index ({0})"), /* keep */
CONSTRAINT("constraint"), /* keep */
CONTINUED_FRACTION_INFINITY_DIVERGENCE("Continued fraction convergents diverged to +/- infinity for value {0}"),
CONTINUED_FRACTION_NAN_DIVERGENCE("Continued fraction diverged to NaN for value {0}"),
CONTRACTION_CRITERIA_SMALLER_THAN_EXPANSION_FACTOR("contraction criteria ({0}) smaller than the expansion factor ({1}). This would lead to a never ending loop of expansion and contraction as a newly expanded internal storage array would immediately satisfy the criteria for contraction."),
CONTRACTION_CRITERIA_SMALLER_THAN_ONE("contraction criteria smaller than one ({0}). This would lead to a never ending loop of expansion and contraction as an internal storage array length equal to the number of elements would satisfy the contraction criteria."),
CONVERGENCE_FAILED("convergence failed"), /* keep */
CROSSING_BOUNDARY_LOOPS("some outline boundary loops cross each other"),
CROSSOVER_RATE("crossover rate ({0})"),
CUMULATIVE_PROBABILITY_RETURNED_NAN("Cumulative probability function returned NaN for argument {0} p = {1}"),
DIFFERENT_ROWS_LENGTHS("some rows have length {0} while others have length {1}"),
DIFFERENT_ORIG_AND_PERMUTED_DATA("original and permuted data must contain the same elements"),
DIGEST_NOT_INITIALIZED("digest not initialized"),
DIMENSIONS_MISMATCH_2x2("got {0}x{1} but expected {2}x{3}"), /* keep */
DIMENSIONS_MISMATCH_SIMPLE("{0} != {1}"), /* keep */
DIMENSIONS_MISMATCH("dimensions mismatch"), /* keep */
DISCRETE_CUMULATIVE_PROBABILITY_RETURNED_NAN("Discrete cumulative probability function returned NaN for argument {0}"),
DISTRIBUTION_NOT_LOADED("distribution not loaded"),
DUPLICATED_ABSCISSA_DIVISION_BY_ZERO("duplicated abscissa {0} causes division by zero"),
EDGE_CONNECTED_TO_ONE_FACET("edge joining points ({0}, {1}, {2}) and ({3}, {4}, {5}) is connected to one facet only"),
ELITISM_RATE("elitism rate ({0})"),
EMPTY_CLUSTER_IN_K_MEANS("empty cluster in k-means"),
EMPTY_INTERPOLATION_SAMPLE("sample for interpolation is empty"),
EMPTY_POLYNOMIALS_COEFFICIENTS_ARRAY("empty polynomials coefficients array"), /* keep */
EMPTY_SELECTED_COLUMN_INDEX_ARRAY("empty selected column index array"),
EMPTY_SELECTED_ROW_INDEX_ARRAY("empty selected row index array"),
EMPTY_STRING_FOR_IMAGINARY_CHARACTER("empty string for imaginary character"),
ENDPOINTS_NOT_AN_INTERVAL("endpoints do not specify an interval: [{0}, {1}]"),
EQUAL_VERTICES_IN_SIMPLEX("equal vertices {0} and {1} in simplex configuration"),
EULER_ANGLES_SINGULARITY("Euler angles singularity"),
EVALUATION("evaluation"), /* keep */
EXPANSION_FACTOR_SMALLER_THAN_ONE("expansion factor smaller than one ({0})"),
FACET_ORIENTATION_MISMATCH("facets orientation mismatch around edge joining points ({0}, {1}, {2}) and ({3}, {4}, {5})"),
FACTORIAL_NEGATIVE_PARAMETER("must have n >= 0 for n!, got n = {0}"),
FAILED_BRACKETING("number of iterations={4}, maximum iterations={5}, initial={6}, lower bound={7}, upper bound={8}, final a value={0}, final b value={1}, f(a)={2}, f(b)={3}"),
FAILED_FRACTION_CONVERSION("Unable to convert {0} to fraction after {1} iterations"),
FIRST_COLUMNS_NOT_INITIALIZED_YET("first {0} columns are not initialized yet"),
FIRST_ELEMENT_NOT_ZERO("first element is not 0: {0}"),
FIRST_ROWS_NOT_INITIALIZED_YET("first {0} rows are not initialized yet"),
FRACTION_CONVERSION_OVERFLOW("Overflow trying to convert {0} to fraction ({1}/{2})"),
FUNCTION_NOT_DIFFERENTIABLE("function is not differentiable"),
FUNCTION_NOT_POLYNOMIAL("function is not polynomial"),
GCD_OVERFLOW_32_BITS("overflow: gcd({0}, {1}) is 2^31"),
GCD_OVERFLOW_64_BITS("overflow: gcd({0}, {1}) is 2^63"),
HOLE_BETWEEN_MODELS_TIME_RANGES("{0} wide hole between models time ranges"),
ILL_CONDITIONED_OPERATOR("condition number {1} is too high "),
INCONSISTENT_STATE_AT_2_PI_WRAPPING("inconsistent state at 2\u03c0 wrapping"),
INDEX_LARGER_THAN_MAX("the index specified: {0} is larger than the current maximal index {1}"),
INDEX_NOT_POSITIVE("index ({0}) is not positive"),
INDEX_OUT_OF_RANGE("index {0} out of allowed range [{1}, {2}]"),
INDEX("index ({0})"), /* keep */
NOT_FINITE_NUMBER("{0} is not a finite number"), /* keep */
INFINITE_BOUND("interval bounds must be finite"),
ARRAY_ELEMENT("value {0} at index {1}"), /* keep */
INFINITE_ARRAY_ELEMENT("Array contains an infinite element, {0} at index {1}"),
INFINITE_VALUE_CONVERSION("cannot convert infinite value"),
INITIAL_CAPACITY_NOT_POSITIVE("initial capacity ({0}) is not positive"),
INITIAL_COLUMN_AFTER_FINAL_COLUMN("initial column {1} after final column {0}"),
INITIAL_ROW_AFTER_FINAL_ROW("initial row {1} after final row {0}"),
@Deprecated
INPUT_DATA_FROM_UNSUPPORTED_DATASOURCE("input data comes from unsupported datasource: {0}, supported sources: {1}, {2}"),
INSTANCES_NOT_COMPARABLE_TO_EXISTING_VALUES("instance of class {0} not comparable to existing values"),
INSUFFICIENT_DATA("insufficient data"),
INSUFFICIENT_DATA_FOR_T_STATISTIC("insufficient data for t statistic, needs at least 2, got {0}"),
INSUFFICIENT_DIMENSION("insufficient dimension {0}, must be at least {1}"),
DIMENSION("dimension ({0})"), /* keep */
INSUFFICIENT_OBSERVED_POINTS_IN_SAMPLE("sample contains {0} observed points, at least {1} are required"),
INSUFFICIENT_ROWS_AND_COLUMNS("insufficient data: only {0} rows and {1} columns."),
INTEGRATION_METHOD_NEEDS_AT_LEAST_TWO_PREVIOUS_POINTS("multistep method needs at least {0} previous steps, got {1}"),
INTERNAL_ERROR("internal error, please fill a bug report at {0}"),
INVALID_BINARY_DIGIT("invalid binary digit: {0}"),
INVALID_BINARY_CHROMOSOME("binary mutation works on BinaryChromosome only"),
INVALID_BRACKETING_PARAMETERS("invalid bracketing parameters: lower bound={0}, initial={1}, upper bound={2}"),
INVALID_FIXED_LENGTH_CHROMOSOME("one-point crossover only works with fixed-length chromosomes"),
INVALID_IMPLEMENTATION("required functionality is missing in {0}"),
INVALID_INTERVAL_INITIAL_VALUE_PARAMETERS("invalid interval, initial value parameters: lower={0}, initial={1}, upper={2}"),
INVALID_ITERATIONS_LIMITS("invalid iteration limits: min={0}, max={1}"),
INVALID_MAX_ITERATIONS("bad value for maximum iterations number: {0}"),
NOT_ENOUGH_DATA_REGRESSION("the number of observations is not sufficient to conduct regression"),
INVALID_REGRESSION_ARRAY("input data array length = {0} does not match the number of observations = {1} and the number of regressors = {2}"),
INVALID_REGRESSION_OBSERVATION("length of regressor array = {0} does not match the number of variables = {1} in the model"),
INVALID_ROUNDING_METHOD("invalid rounding method {0}, valid methods: {1} ({2}), {3} ({4}), {5} ({6}), {7} ({8}), {9} ({10}), {11} ({12}), {13} ({14}), {15} ({16})"),
ITERATOR_EXHAUSTED("iterator exhausted"),
ITERATIONS("iterations"), /* keep */
LCM_OVERFLOW_32_BITS("overflow: lcm({0}, {1}) is 2^31"),
LCM_OVERFLOW_64_BITS("overflow: lcm({0}, {1}) is 2^63"),
LIST_OF_CHROMOSOMES_BIGGER_THAN_POPULATION_SIZE("list of chromosomes bigger than maxPopulationSize"),
LOESS_EXPECTS_AT_LEAST_ONE_POINT("Loess expects at least 1 point"),
LOWER_BOUND_NOT_BELOW_UPPER_BOUND("lower bound ({0}) must be strictly less than upper bound ({1})"), /* keep */
LOWER_ENDPOINT_ABOVE_UPPER_ENDPOINT("lower endpoint ({0}) must be less than or equal to upper endpoint ({1})"),
MAP_MODIFIED_WHILE_ITERATING("map has been modified while iterating"),
MULTISTEP_STARTER_STOPPED_EARLY("multistep integrator starter stopped early, maybe too large step size"),
EVALUATIONS("evaluations"), /* keep */
MAX_COUNT_EXCEEDED("maximal count ({0}) exceeded"), /* keep */
MAX_ITERATIONS_EXCEEDED("maximal number of iterations ({0}) exceeded"),
MINIMAL_STEPSIZE_REACHED_DURING_INTEGRATION("minimal step size ({1,number,0.00E00}) reached, integration needs {0,number,0.00E00}"),
MISMATCHED_LOESS_ABSCISSA_ORDINATE_ARRAYS("Loess expects the abscissa and ordinate arrays to be of the same size, but got {0} abscissae and {1} ordinatae"),
MUTATION_RATE("mutation rate ({0})"),
NAN_ELEMENT_AT_INDEX("element {0} is NaN"),
NAN_VALUE_CONVERSION("cannot convert NaN value"),
NEGATIVE_BRIGHTNESS_EXPONENT("brightness exponent should be positive or null, but got {0}"),
NEGATIVE_COMPLEX_MODULE("negative complex module {0}"),
NEGATIVE_ELEMENT_AT_2D_INDEX("element ({0}, {1}) is negative: {2}"),
NEGATIVE_ELEMENT_AT_INDEX("element {0} is negative: {1}"),
NEGATIVE_NUMBER_OF_SUCCESSES("number of successes must be non-negative ({0})"),
NUMBER_OF_SUCCESSES("number of successes ({0})"), /* keep */
NEGATIVE_NUMBER_OF_TRIALS("number of trials must be non-negative ({0})"),
NUMBER_OF_INTERPOLATION_POINTS("number of interpolation points ({0})"), /* keep */
NUMBER_OF_TRIALS("number of trials ({0})"),
NOT_CONVEX("vertices do not form a convex hull in CCW winding"),
NOT_CONVEX_HYPERPLANES("hyperplanes do not define a convex region"),
ROBUSTNESS_ITERATIONS("number of robustness iterations ({0})"),
START_POSITION("start position ({0})"), /* keep */
NON_CONVERGENT_CONTINUED_FRACTION("Continued fraction convergents failed to converge (in less than {0} iterations) for value {1}"),
NON_INVERTIBLE_TRANSFORM("non-invertible affine transform collapses some lines into single points"),
NON_POSITIVE_MICROSPHERE_ELEMENTS("number of microsphere elements must be positive, but got {0}"),
NON_POSITIVE_POLYNOMIAL_DEGREE("polynomial degree must be positive: degree={0}"),
NON_REAL_FINITE_ABSCISSA("all abscissae must be finite real numbers, but {0}-th is {1}"),
NON_REAL_FINITE_ORDINATE("all ordinatae must be finite real numbers, but {0}-th is {1}"),
NON_REAL_FINITE_WEIGHT("all weights must be finite real numbers, but {0}-th is {1}"),
NON_SQUARE_MATRIX("non square ({0}x{1}) matrix"),
NORM("Norm ({0})"), /* keep */
NORMALIZE_INFINITE("Cannot normalize to an infinite value"),
NORMALIZE_NAN("Cannot normalize to NaN"),
NOT_ADDITION_COMPATIBLE_MATRICES("{0}x{1} and {2}x{3} matrices are not addition compatible"),
NOT_DECREASING_NUMBER_OF_POINTS("points {0} and {1} are not decreasing ({2} < {3})"),
NOT_DECREASING_SEQUENCE("points {3} and {2} are not decreasing ({1} < {0})"), /* keep */
NOT_ENOUGH_DATA_FOR_NUMBER_OF_PREDICTORS("not enough data ({0} rows) for this many predictors ({1} predictors)"),
NOT_ENOUGH_POINTS_IN_SPLINE_PARTITION("spline partition must have at least {0} points, got {1}"),
NOT_INCREASING_NUMBER_OF_POINTS("points {0} and {1} are not increasing ({2} > {3})"),
NOT_INCREASING_SEQUENCE("points {3} and {2} are not increasing ({1} > {0})"), /* keep */
NOT_MULTIPLICATION_COMPATIBLE_MATRICES("{0}x{1} and {2}x{3} matrices are not multiplication compatible"),
NOT_POSITIVE_DEFINITE_MATRIX("not positive definite matrix"), /* keep */
NON_POSITIVE_DEFINITE_MATRIX("not positive definite matrix: diagonal element at ({1},{1}) is smaller than {2} ({0})"),
NON_POSITIVE_DEFINITE_OPERATOR("non positive definite linear operator"), /* keep */
NON_SELF_ADJOINT_OPERATOR("non self-adjoint linear operator"), /* keep */
NON_SQUARE_OPERATOR("non square ({0}x{1}) linear operator"), /* keep */
DEGREES_OF_FREEDOM("degrees of freedom ({0})"), /* keep */
NOT_POSITIVE_DEGREES_OF_FREEDOM("degrees of freedom must be positive ({0})"),
NOT_POSITIVE_ELEMENT_AT_INDEX("element {0} is not positive: {1}"),
NOT_POSITIVE_EXPONENT("invalid exponent {0} (must be positive)"),
NUMBER_OF_ELEMENTS_SHOULD_BE_POSITIVE("number of elements should be positive ({0})"),
BASE("base ({0})"), /* keep */
EXPONENT("exponent ({0})"), /* keep */
NOT_POSITIVE_LENGTH("length must be positive ({0})"),
LENGTH("length ({0})"), /* keep */
NOT_POSITIVE_MEAN("mean must be positive ({0})"),
MEAN("mean ({0})"), /* keep */
NOT_POSITIVE_NUMBER_OF_SAMPLES("number of sample is not positive: {0}"),
NUMBER_OF_SAMPLES("number of samples ({0})"), /* keep */
NOT_POSITIVE_PERMUTATION("permutation k ({0}) must be positive"),
PERMUTATION_SIZE("permutation size ({0}"), /* keep */
NOT_POSITIVE_POISSON_MEAN("the Poisson mean must be positive ({0})"),
NOT_POSITIVE_POPULATION_SIZE("population size must be positive ({0})"),
POPULATION_SIZE("population size ({0})"), /* keep */
NOT_POSITIVE_ROW_DIMENSION("invalid row dimension: {0} (must be positive)"),
NOT_POSITIVE_SAMPLE_SIZE("sample size must be positive ({0})"),
NOT_POSITIVE_SCALE("scale must be positive ({0})"),
SCALE("scale ({0})"), /* keep */
NOT_POSITIVE_SHAPE("shape must be positive ({0})"),
SHAPE("shape ({0})"), /* keep */
NOT_POSITIVE_STANDARD_DEVIATION("standard deviation must be positive ({0})"),
STANDARD_DEVIATION("standard deviation ({0})"), /* keep */
NOT_POSITIVE_UPPER_BOUND("upper bound must be positive ({0})"),
NOT_POSITIVE_WINDOW_SIZE("window size must be positive ({0})"),
NOT_POWER_OF_TWO("{0} is not a power of 2"),
NOT_POWER_OF_TWO_CONSIDER_PADDING("{0} is not a power of 2, consider padding for fix"),
NOT_POWER_OF_TWO_PLUS_ONE("{0} is not a power of 2 plus one"),
NOT_STRICTLY_DECREASING_NUMBER_OF_POINTS("points {0} and {1} are not strictly decreasing ({2} <= {3})"),
NOT_STRICTLY_DECREASING_SEQUENCE("points {3} and {2} are not strictly decreasing ({1} <= {0})"), /* keep */
NOT_STRICTLY_INCREASING_KNOT_VALUES("knot values must be strictly increasing"),
NOT_STRICTLY_INCREASING_NUMBER_OF_POINTS("points {0} and {1} are not strictly increasing ({2} >= {3})"),
NOT_STRICTLY_INCREASING_SEQUENCE("points {3} and {2} are not strictly increasing ({1} >= {0})"), /* keep */
NOT_SUBTRACTION_COMPATIBLE_MATRICES("{0}x{1} and {2}x{3} matrices are not subtraction compatible"),
NOT_SUPPORTED_IN_DIMENSION_N("method not supported in dimension {0}"),
NOT_SYMMETRIC_MATRIX("not symmetric matrix"),
NON_SYMMETRIC_MATRIX("non symmetric matrix: the difference between entries at ({0},{1}) and ({1},{0}) is larger than {2}"), /* keep */
NO_BIN_SELECTED("no bin selected"),
NO_CONVERGENCE_WITH_ANY_START_POINT("none of the {0} start points lead to convergence"), /* keep */
NO_DATA("no data"), /* keep */
NO_DEGREES_OF_FREEDOM("no degrees of freedom ({0} measurements, {1} parameters)"),
NO_DENSITY_FOR_THIS_DISTRIBUTION("This distribution does not have a density function implemented"),
NO_FEASIBLE_SOLUTION("no feasible solution"),
NO_OPTIMUM_COMPUTED_YET("no optimum computed yet"), /* keep */
NO_REGRESSORS("Regression model must include at least one regressor"),
NO_RESULT_AVAILABLE("no result available"),
NO_SUCH_MATRIX_ENTRY("no entry at indices ({0}, {1}) in a {2}x{3} matrix"),
NAN_NOT_ALLOWED("NaN is not allowed"),
NULL_NOT_ALLOWED("null is not allowed"), /* keep */
ARRAY_ZERO_LENGTH_OR_NULL_NOT_ALLOWED("a null or zero length array not allowed"),
COVARIANCE_MATRIX("covariance matrix"), /* keep */
DENOMINATOR("denominator"), /* keep */
DENOMINATOR_FORMAT("denominator format"), /* keep */
FRACTION("fraction"), /* keep */
FUNCTION("function"), /* keep */
IMAGINARY_FORMAT("imaginary format"), /* keep */
INPUT_ARRAY("input array"), /* keep */
NUMERATOR("numerator"), /* keep */
NUMERATOR_FORMAT("numerator format"), /* keep */
OBJECT_TRANSFORMATION("conversion exception in transformation"), /* keep */
REAL_FORMAT("real format"), /* keep */
WHOLE_FORMAT("whole format"), /* keep */
NUMBER_TOO_LARGE("{0} is larger than the maximum ({1})"), /* keep */
NUMBER_TOO_SMALL("{0} is smaller than the minimum ({1})"), /* keep */
NUMBER_TOO_LARGE_BOUND_EXCLUDED("{0} is larger than, or equal to, the maximum ({1})"), /* keep */
NUMBER_TOO_SMALL_BOUND_EXCLUDED("{0} is smaller than, or equal to, the minimum ({1})"), /* keep */
NUMBER_OF_SUCCESS_LARGER_THAN_POPULATION_SIZE("number of successes ({0}) must be less than or equal to population size ({1})"),
NUMERATOR_OVERFLOW_AFTER_MULTIPLY("overflow, numerator too large after multiply: {0}"),
N_POINTS_GAUSS_LEGENDRE_INTEGRATOR_NOT_SUPPORTED("{0} points Legendre-Gauss integrator not supported, number of points must be in the {1}-{2} range"),
OBSERVED_COUNTS_ALL_ZERO("observed counts are all 0 in observed array {0}"),
OBSERVED_COUNTS_BOTTH_ZERO_FOR_ENTRY("observed counts are both zero for entry {0}"),
BOBYQA_BOUND_DIFFERENCE_CONDITION("the difference between the upper and lower bound must be larger than twice the initial trust region radius ({0})"),
OUT_OF_BOUNDS_QUANTILE_VALUE("out of bounds quantile value: {0}, must be in (0, 100]"),
OUT_OF_BOUNDS_CONFIDENCE_LEVEL("out of bounds confidence level {0}, must be between {1} and {2}"),
OUT_OF_BOUND_SIGNIFICANCE_LEVEL("out of bounds significance level {0}, must be between {1} and {2}"),
SIGNIFICANCE_LEVEL("significance level ({0})"), /* keep */
OUT_OF_ORDER_ABSCISSA_ARRAY("the abscissae array must be sorted in a strictly increasing order, but the {0}-th element is {1} whereas {2}-th is {3}"),
OUT_OF_PLANE("point ({0}, {1}, {2}) is out of plane"),
OUT_OF_RANGE_ROOT_OF_UNITY_INDEX("out of range root of unity index {0} (must be in [{1};{2}])"),
OUT_OF_RANGE("out of range"), /* keep */
OUT_OF_RANGE_SIMPLE("{0} out of [{1}, {2}] range"), /* keep */
OUT_OF_RANGE_LEFT("{0} out of ({1}, {2}] range"),
OUT_OF_RANGE_RIGHT("{0} out of [{1}, {2}) range"),
OUTLINE_BOUNDARY_LOOP_OPEN("an outline boundary loop is open"),
OVERFLOW("overflow"), /* keep */
OVERFLOW_IN_FRACTION("overflow in fraction {0}/{1}, cannot negate"),
OVERFLOW_IN_ADDITION("overflow in addition: {0} + {1}"),
OVERFLOW_IN_SUBTRACTION("overflow in subtraction: {0} - {1}"),
OVERFLOW_IN_MULTIPLICATION("overflow in multiplication: {0} * {1}"),
PERCENTILE_IMPLEMENTATION_CANNOT_ACCESS_METHOD("cannot access {0} method in percentile implementation {1}"),
PERCENTILE_IMPLEMENTATION_UNSUPPORTED_METHOD("percentile implementation {0} does not support {1}"),
PERMUTATION_EXCEEDS_N("permutation size ({0}) exceeds permuation domain ({1})"), /* keep */
POLYNOMIAL("polynomial"), /* keep */
POLYNOMIAL_INTERPOLANTS_MISMATCH_SEGMENTS("number of polynomial interpolants must match the number of segments ({0} != {1} - 1)"),
POPULATION_LIMIT_NOT_POSITIVE("population limit has to be positive"),
POWER_NEGATIVE_PARAMETERS("cannot raise an integral value to a negative power ({0}^{1})"),
PROPAGATION_DIRECTION_MISMATCH("propagation direction mismatch"),
RANDOMKEY_MUTATION_WRONG_CLASS("RandomKeyMutation works only with RandomKeys, not {0}"),
ROOTS_OF_UNITY_NOT_COMPUTED_YET("roots of unity have not been computed yet"),
ROTATION_MATRIX_DIMENSIONS("a {0}x{1} matrix cannot be a rotation matrix"),
ROW_INDEX_OUT_OF_RANGE("row index {0} out of allowed range [{1}, {2}]"),
ROW_INDEX("row index ({0})"), /* keep */
SAME_SIGN_AT_ENDPOINTS("function values at endpoints do not have different signs, endpoints: [{0}, {1}], values: [{2}, {3}]"),
SAMPLE_SIZE_EXCEEDS_COLLECTION_SIZE("sample size ({0}) exceeds collection size ({1})"), /* keep */
SAMPLE_SIZE_LARGER_THAN_POPULATION_SIZE("sample size ({0}) must be less than or equal to population size ({1})"),
SIMPLEX_NEED_ONE_POINT("simplex must contain at least one point"),
SIMPLE_MESSAGE("{0}"),
SINGULAR_MATRIX("matrix is singular"), /* keep */
SINGULAR_OPERATOR("operator is singular"),
SUBARRAY_ENDS_AFTER_ARRAY_END("subarray ends after array end"),
TOO_LARGE_CUTOFF_SINGULAR_VALUE("cutoff singular value is {0}, should be at most {1}"),
TOO_LARGE_TOURNAMENT_ARITY("tournament arity ({0}) cannot be bigger than population size ({1})"),
TOO_MANY_ELEMENTS_TO_DISCARD_FROM_ARRAY("cannot discard {0} elements from a {1} elements array"),
TOO_MANY_REGRESSORS("too many regressors ({0}) specified, only {1} in the model"),
TOO_SMALL_COST_RELATIVE_TOLERANCE("cost relative tolerance is too small ({0}), no further reduction in the sum of squares is possible"),
TOO_SMALL_INTEGRATION_INTERVAL("too small integration interval: length = {0}"),
TOO_SMALL_ORTHOGONALITY_TOLERANCE("orthogonality tolerance is too small ({0}), solution is orthogonal to the jacobian"),
TOO_SMALL_PARAMETERS_RELATIVE_TOLERANCE("parameters relative tolerance is too small ({0}), no further improvement in the approximate solution is possible"),
TRUST_REGION_STEP_FAILED("trust region step has failed to reduce Q"),
TWO_OR_MORE_CATEGORIES_REQUIRED("two or more categories required, got {0}"),
TWO_OR_MORE_VALUES_IN_CATEGORY_REQUIRED("two or more values required in each category, one has {0}"),
UNABLE_TO_BRACKET_OPTIMUM_IN_LINE_SEARCH("unable to bracket optimum in line search"),
UNABLE_TO_COMPUTE_COVARIANCE_SINGULAR_PROBLEM("unable to compute covariances: singular problem"),
UNABLE_TO_FIRST_GUESS_HARMONIC_COEFFICIENTS("unable to first guess the harmonic coefficients"),
UNABLE_TO_ORTHOGONOLIZE_MATRIX("unable to orthogonalize matrix in {0} iterations"),
UNABLE_TO_PERFORM_QR_DECOMPOSITION_ON_JACOBIAN("unable to perform Q.R decomposition on the {0}x{1} jacobian matrix"),
UNABLE_TO_SOLVE_SINGULAR_PROBLEM("unable to solve: singular problem"),
UNBOUNDED_SOLUTION("unbounded solution"),
UNKNOWN_MODE("unknown mode {0}, known modes: {1} ({2}), {3} ({4}), {5} ({6}), {7} ({8}), {9} ({10}) and {11} ({12})"),
UNKNOWN_PARAMETER("unknown parameter {0}"),
UNMATCHED_ODE_IN_EXPANDED_SET("ode does not match the main ode set in the extended set"),
CANNOT_PARSE_AS_TYPE("string \"{0}\" unparseable (from position {1}) as an object of type {2}"), /* keep */
CANNOT_PARSE("string \"{0}\" unparseable (from position {1})"), /* keep */
UNPARSEABLE_3D_VECTOR("unparseable 3D vector: \"{0}\""),
UNPARSEABLE_COMPLEX_NUMBER("unparseable complex number: \"{0}\""),
UNPARSEABLE_REAL_VECTOR("unparseable real vector: \"{0}\""),
UNSUPPORTED_EXPANSION_MODE("unsupported expansion mode {0}, supported modes are {1} ({2}) and {3} ({4})"),
UNSUPPORTED_OPERATION("unsupported operation"), /* keep */
ARITHMETIC_EXCEPTION("arithmetic exception"), /* keep */
ILLEGAL_STATE("illegal state"), /* keep */
USER_EXCEPTION("exception generated in user code"), /* keep */
URL_CONTAINS_NO_DATA("URL {0} contains no data"),
VALUES_ADDED_BEFORE_CONFIGURING_STATISTIC("{0} values have been added before statistic is configured"),
VECTOR_LENGTH_MISMATCH("vector length mismatch: got {0} but expected {1}"),
VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT("vector must have at least one element"),
WEIGHT_AT_LEAST_ONE_NON_ZERO("weigth array must contain at least one non-zero value"),
WRONG_BLOCK_LENGTH("wrong array shape (block length = {0}, expected {1})"),
WRONG_NUMBER_OF_POINTS("{0} points are required, got only {1}"),
NUMBER_OF_POINTS("number of points ({0})"), /* keep */
ZERO_DENOMINATOR("denominator must be different from 0"), /* keep */
ZERO_DENOMINATOR_IN_FRACTION("zero denominator in fraction {0}/{1}"),
ZERO_FRACTION_TO_DIVIDE_BY("the fraction to divide by must not be zero: {0}/{1}"),
ZERO_NORM("zero norm"),
ZERO_NORM_FOR_ROTATION_AXIS("zero norm for rotation axis"),
ZERO_NORM_FOR_ROTATION_DEFINING_VECTOR("zero norm for rotation defining vector"),
ZERO_NOT_ALLOWED("zero not allowed here");
// CHECKSTYLE: resume JavadocVariable
// CHECKSTYLE: resume MultipleVariableDeclarations
/** Source English format. */
private final String sourceFormat;
/** Simple constructor.
* @param sourceFormat source English format to use when no
* localized version is available
*/
LocalizedFormats(final String sourceFormat) {
this.sourceFormat = sourceFormat;
}
/** {@inheritDoc} */
public String getSourceString() {
return sourceFormat;
}
/** {@inheritDoc} */
public String getLocalizedString(final Locale locale) {
try {
final String path = LocalizedFormats.class.getName().replaceAll("\\.", "/");
ResourceBundle bundle =
ResourceBundle.getBundle("assets/" + path, locale);
if (bundle.getLocale().getLanguage().equals(locale.getLanguage())) {
// the value of the resource is the translated format
return bundle.getString(toString());
}
} catch (MissingResourceException mre) { // NOPMD
// do nothing here
}
// either the locale is not supported or the resource is unknown
// don't translate and fall back to using the source format
return sourceFormat;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,658 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math3.util;
import java.io.PrintStream;
import org.apache.commons.math3.exception.DimensionMismatchException;
/** Class used to compute the classical functions tables.
* @since 3.0
*/
class FastMathCalc {
/**
* 0x40000000 - used to split a double into two parts, both with the low order bits cleared.
* Equivalent to 2^30.
*/
private static final long HEX_40000000 = 0x40000000L; // 1073741824L
/** Factorial table, for Taylor series expansions. 0!, 1!, 2!, ... 19! */
private static final double FACT[] = new double[]
{
+1.0d, // 0
+1.0d, // 1
+2.0d, // 2
+6.0d, // 3
+24.0d, // 4
+120.0d, // 5
+720.0d, // 6
+5040.0d, // 7
+40320.0d, // 8
+362880.0d, // 9
+3628800.0d, // 10
+39916800.0d, // 11
+479001600.0d, // 12
+6227020800.0d, // 13
+87178291200.0d, // 14
+1307674368000.0d, // 15
+20922789888000.0d, // 16
+355687428096000.0d, // 17
+6402373705728000.0d, // 18
+121645100408832000.0d, // 19
};
/** Coefficients for slowLog. */
private static final double LN_SPLIT_COEF[][] = {
{2.0, 0.0},
{0.6666666269302368, 3.9736429850260626E-8},
{0.3999999761581421, 2.3841857910019882E-8},
{0.2857142686843872, 1.7029898543501842E-8},
{0.2222222089767456, 1.3245471311735498E-8},
{0.1818181574344635, 2.4384203044354907E-8},
{0.1538461446762085, 9.140260083262505E-9},
{0.13333332538604736, 9.220590270857665E-9},
{0.11764700710773468, 1.2393345855018391E-8},
{0.10526403784751892, 8.251545029714408E-9},
{0.0952233225107193, 1.2675934823758863E-8},
{0.08713622391223907, 1.1430250008909141E-8},
{0.07842259109020233, 2.404307984052299E-9},
{0.08371849358081818, 1.176342548272881E-8},
{0.030589580535888672, 1.2958646899018938E-9},
{0.14982303977012634, 1.225743062930824E-8},
};
/** Table start declaration. */
private static final String TABLE_START_DECL = " {";
/** Table end declaration. */
private static final String TABLE_END_DECL = " };";
/**
* Private Constructor.
*/
private FastMathCalc() {
}
/** Build the sine and cosine tables.
* @param SINE_TABLE_A table of the most significant part of the sines
* @param SINE_TABLE_B table of the least significant part of the sines
* @param COSINE_TABLE_A table of the most significant part of the cosines
* @param COSINE_TABLE_B table of the most significant part of the cosines
* @param SINE_TABLE_LEN length of the tables
* @param TANGENT_TABLE_A table of the most significant part of the tangents
* @param TANGENT_TABLE_B table of the most significant part of the tangents
*/
@SuppressWarnings("unused")
private static void buildSinCosTables(double[] SINE_TABLE_A, double[] SINE_TABLE_B,
double[] COSINE_TABLE_A, double[] COSINE_TABLE_B,
int SINE_TABLE_LEN, double[] TANGENT_TABLE_A, double[] TANGENT_TABLE_B) {
final double result[] = new double[2];
/* Use taylor series for 0 <= x <= 6/8 */
for (int i = 0; i < 7; i++) {
double x = i / 8.0;
slowSin(x, result);
SINE_TABLE_A[i] = result[0];
SINE_TABLE_B[i] = result[1];
slowCos(x, result);
COSINE_TABLE_A[i] = result[0];
COSINE_TABLE_B[i] = result[1];
}
/* Use angle addition formula to complete table to 13/8, just beyond pi/2 */
for (int i = 7; i < SINE_TABLE_LEN; i++) {
double xs[] = new double[2];
double ys[] = new double[2];
double as[] = new double[2];
double bs[] = new double[2];
double temps[] = new double[2];
if ( (i & 1) == 0) {
// Even, use double angle
xs[0] = SINE_TABLE_A[i/2];
xs[1] = SINE_TABLE_B[i/2];
ys[0] = COSINE_TABLE_A[i/2];
ys[1] = COSINE_TABLE_B[i/2];
/* compute sine */
splitMult(xs, ys, result);
SINE_TABLE_A[i] = result[0] * 2.0;
SINE_TABLE_B[i] = result[1] * 2.0;
/* Compute cosine */
splitMult(ys, ys, as);
splitMult(xs, xs, temps);
temps[0] = -temps[0];
temps[1] = -temps[1];
splitAdd(as, temps, result);
COSINE_TABLE_A[i] = result[0];
COSINE_TABLE_B[i] = result[1];
} else {
xs[0] = SINE_TABLE_A[i/2];
xs[1] = SINE_TABLE_B[i/2];
ys[0] = COSINE_TABLE_A[i/2];
ys[1] = COSINE_TABLE_B[i/2];
as[0] = SINE_TABLE_A[i/2+1];
as[1] = SINE_TABLE_B[i/2+1];
bs[0] = COSINE_TABLE_A[i/2+1];
bs[1] = COSINE_TABLE_B[i/2+1];
/* compute sine */
splitMult(xs, bs, temps);
splitMult(ys, as, result);
splitAdd(result, temps, result);
SINE_TABLE_A[i] = result[0];
SINE_TABLE_B[i] = result[1];
/* Compute cosine */
splitMult(ys, bs, result);
splitMult(xs, as, temps);
temps[0] = -temps[0];
temps[1] = -temps[1];
splitAdd(result, temps, result);
COSINE_TABLE_A[i] = result[0];
COSINE_TABLE_B[i] = result[1];
}
}
/* Compute tangent = sine/cosine */
for (int i = 0; i < SINE_TABLE_LEN; i++) {
double xs[] = new double[2];
double ys[] = new double[2];
double as[] = new double[2];
as[0] = COSINE_TABLE_A[i];
as[1] = COSINE_TABLE_B[i];
splitReciprocal(as, ys);
xs[0] = SINE_TABLE_A[i];
xs[1] = SINE_TABLE_B[i];
splitMult(xs, ys, as);
TANGENT_TABLE_A[i] = as[0];
TANGENT_TABLE_B[i] = as[1];
}
}
/**
* For x between 0 and pi/4 compute cosine using Talor series
* cos(x) = 1 - x^2/2! + x^4/4! ...
* @param x number from which cosine is requested
* @param result placeholder where to put the result in extended precision
* (may be null)
* @return cos(x)
*/
static double slowCos(final double x, final double result[]) {
final double xs[] = new double[2];
final double ys[] = new double[2];
final double facts[] = new double[2];
final double as[] = new double[2];
split(x, xs);
ys[0] = ys[1] = 0.0;
for (int i = FACT.length-1; i >= 0; i--) {
splitMult(xs, ys, as);
ys[0] = as[0]; ys[1] = as[1];
if ( (i & 1) != 0) { // skip odd entries
continue;
}
split(FACT[i], as);
splitReciprocal(as, facts);
if ( (i & 2) != 0 ) { // alternate terms are negative
facts[0] = -facts[0];
facts[1] = -facts[1];
}
splitAdd(ys, facts, as);
ys[0] = as[0]; ys[1] = as[1];
}
if (result != null) {
result[0] = ys[0];
result[1] = ys[1];
}
return ys[0] + ys[1];
}
/**
* For x between 0 and pi/4 compute sine using Taylor expansion:
* sin(x) = x - x^3/3! + x^5/5! - x^7/7! ...
* @param x number from which sine is requested
* @param result placeholder where to put the result in extended precision
* (may be null)
* @return sin(x)
*/
static double slowSin(final double x, final double result[]) {
final double xs[] = new double[2];
final double ys[] = new double[2];
final double facts[] = new double[2];
final double as[] = new double[2];
split(x, xs);
ys[0] = ys[1] = 0.0;
for (int i = FACT.length-1; i >= 0; i--) {
splitMult(xs, ys, as);
ys[0] = as[0]; ys[1] = as[1];
if ( (i & 1) == 0) { // Ignore even numbers
continue;
}
split(FACT[i], as);
splitReciprocal(as, facts);
if ( (i & 2) != 0 ) { // alternate terms are negative
facts[0] = -facts[0];
facts[1] = -facts[1];
}
splitAdd(ys, facts, as);
ys[0] = as[0]; ys[1] = as[1];
}
if (result != null) {
result[0] = ys[0];
result[1] = ys[1];
}
return ys[0] + ys[1];
}
/**
* For x between 0 and 1, returns exp(x), uses extended precision
* @param x argument of exponential
* @param result placeholder where to place exp(x) split in two terms
* for extra precision (i.e. exp(x) = result[0] + result[1]
* @return exp(x)
*/
static double slowexp(final double x, final double result[]) {
final double xs[] = new double[2];
final double ys[] = new double[2];
final double facts[] = new double[2];
final double as[] = new double[2];
split(x, xs);
ys[0] = ys[1] = 0.0;
for (int i = FACT.length-1; i >= 0; i--) {
splitMult(xs, ys, as);
ys[0] = as[0];
ys[1] = as[1];
split(FACT[i], as);
splitReciprocal(as, facts);
splitAdd(ys, facts, as);
ys[0] = as[0];
ys[1] = as[1];
}
if (result != null) {
result[0] = ys[0];
result[1] = ys[1];
}
return ys[0] + ys[1];
}
/** Compute split[0], split[1] such that their sum is equal to d,
* and split[0] has its 30 least significant bits as zero.
* @param d number to split
* @param split placeholder where to place the result
*/
private static void split(final double d, final double split[]) {
if (d < 8e298 && d > -8e298) {
final double a = d * HEX_40000000;
split[0] = (d + a) - a;
split[1] = d - split[0];
} else {
final double a = d * 9.31322574615478515625E-10;
split[0] = (d + a - d) * HEX_40000000;
split[1] = d - split[0];
}
}
/** Recompute a split.
* @param a input/out array containing the split, changed
* on output
*/
private static void resplit(final double a[]) {
final double c = a[0] + a[1];
final double d = -(c - a[0] - a[1]);
if (c < 8e298 && c > -8e298) { // MAGIC NUMBER
double z = c * HEX_40000000;
a[0] = (c + z) - z;
a[1] = c - a[0] + d;
} else {
double z = c * 9.31322574615478515625E-10;
a[0] = (c + z - c) * HEX_40000000;
a[1] = c - a[0] + d;
}
}
/** Multiply two numbers in split form.
* @param a first term of multiplication
* @param b second term of multiplication
* @param ans placeholder where to put the result
*/
private static void splitMult(double a[], double b[], double ans[]) {
ans[0] = a[0] * b[0];
ans[1] = a[0] * b[1] + a[1] * b[0] + a[1] * b[1];
/* Resplit */
resplit(ans);
}
/** Add two numbers in split form.
* @param a first term of addition
* @param b second term of addition
* @param ans placeholder where to put the result
*/
private static void splitAdd(final double a[], final double b[], final double ans[]) {
ans[0] = a[0] + b[0];
ans[1] = a[1] + b[1];
resplit(ans);
}
/** Compute the reciprocal of in. Use the following algorithm.
* in = c + d.
* want to find x + y such that x+y = 1/(c+d) and x is much
* larger than y and x has several zero bits on the right.
*
* Set b = 1/(2^22), a = 1 - b. Thus (a+b) = 1.
* Use following identity to compute (a+b)/(c+d)
*
* (a+b)/(c+d) = a/c + (bc - ad) / (c^2 + cd)
* set x = a/c and y = (bc - ad) / (c^2 + cd)
* This will be close to the right answer, but there will be
* some rounding in the calculation of X. So by carefully
* computing 1 - (c+d)(x+y) we can compute an error and
* add that back in. This is done carefully so that terms
* of similar size are subtracted first.
* @param in initial number, in split form
* @param result placeholder where to put the result
*/
static void splitReciprocal(final double in[], final double result[]) {
final double b = 1.0/4194304.0;
final double a = 1.0 - b;
if (in[0] == 0.0) {
in[0] = in[1];
in[1] = 0.0;
}
result[0] = a / in[0];
result[1] = (b*in[0]-a*in[1]) / (in[0]*in[0] + in[0]*in[1]);
if (result[1] != result[1]) { // can happen if result[1] is NAN
result[1] = 0.0;
}
/* Resplit */
resplit(result);
for (int i = 0; i < 2; i++) {
/* this may be overkill, probably once is enough */
double err = 1.0 - result[0] * in[0] - result[0] * in[1] -
result[1] * in[0] - result[1] * in[1];
/*err = 1.0 - err; */
err *= result[0] + result[1];
/*printf("err = %16e\n", err); */
result[1] += err;
}
}
/** Compute (a[0] + a[1]) * (b[0] + b[1]) in extended precision.
* @param a first term of the multiplication
* @param b second term of the multiplication
* @param result placeholder where to put the result
*/
private static void quadMult(final double a[], final double b[], final double result[]) {
final double xs[] = new double[2];
final double ys[] = new double[2];
final double zs[] = new double[2];
/* a[0] * b[0] */
split(a[0], xs);
split(b[0], ys);
splitMult(xs, ys, zs);
result[0] = zs[0];
result[1] = zs[1];
/* a[0] * b[1] */
split(b[1], ys);
splitMult(xs, ys, zs);
double tmp = result[0] + zs[0];
result[1] -= tmp - result[0] - zs[0];
result[0] = tmp;
tmp = result[0] + zs[1];
result[1] -= tmp - result[0] - zs[1];
result[0] = tmp;
/* a[1] * b[0] */
split(a[1], xs);
split(b[0], ys);
splitMult(xs, ys, zs);
tmp = result[0] + zs[0];
result[1] -= tmp - result[0] - zs[0];
result[0] = tmp;
tmp = result[0] + zs[1];
result[1] -= tmp - result[0] - zs[1];
result[0] = tmp;
/* a[1] * b[0] */
split(a[1], xs);
split(b[1], ys);
splitMult(xs, ys, zs);
tmp = result[0] + zs[0];
result[1] -= tmp - result[0] - zs[0];
result[0] = tmp;
tmp = result[0] + zs[1];
result[1] -= tmp - result[0] - zs[1];
result[0] = tmp;
}
/** Compute exp(p) for a integer p in extended precision.
* @param p integer whose exponential is requested
* @param result placeholder where to put the result in extended precision
* @return exp(p) in standard precision (equal to result[0] + result[1])
*/
static double expint(int p, final double result[]) {
//double x = M_E;
final double xs[] = new double[2];
final double as[] = new double[2];
final double ys[] = new double[2];
//split(x, xs);
//xs[1] = (double)(2.7182818284590452353602874713526625L - xs[0]);
//xs[0] = 2.71827697753906250000;
//xs[1] = 4.85091998273542816811e-06;
//xs[0] = Double.longBitsToDouble(0x4005bf0800000000L);
//xs[1] = Double.longBitsToDouble(0x3ed458a2bb4a9b00L);
/* E */
xs[0] = 2.718281828459045;
xs[1] = 1.4456468917292502E-16;
split(1.0, ys);
while (p > 0) {
if ((p & 1) != 0) {
quadMult(ys, xs, as);
ys[0] = as[0]; ys[1] = as[1];
}
quadMult(xs, xs, as);
xs[0] = as[0]; xs[1] = as[1];
p >>= 1;
}
if (result != null) {
result[0] = ys[0];
result[1] = ys[1];
resplit(result);
}
return ys[0] + ys[1];
}
/** xi in the range of [1, 2].
* 3 5 7
* x+1 / x x x \
* ln ----- = 2 * | x + ---- + ---- + ---- + ... |
* 1-x \ 3 5 7 /
*
* So, compute a Remez approximation of the following function
*
* ln ((sqrt(x)+1)/(1-sqrt(x))) / x
*
* This will be an even function with only positive coefficents.
* x is in the range [0 - 1/3].
*
* Transform xi for input to the above function by setting
* x = (xi-1)/(xi+1). Input to the polynomial is x^2, then
* the result is multiplied by x.
* @param xi number from which log is requested
* @return log(xi)
*/
static double[] slowLog(double xi) {
double x[] = new double[2];
double x2[] = new double[2];
double y[] = new double[2];
double a[] = new double[2];
split(xi, x);
/* Set X = (x-1)/(x+1) */
x[0] += 1.0;
resplit(x);
splitReciprocal(x, a);
x[0] -= 2.0;
resplit(x);
splitMult(x, a, y);
x[0] = y[0];
x[1] = y[1];
/* Square X -> X2*/
splitMult(x, x, x2);
//x[0] -= 1.0;
//resplit(x);
y[0] = LN_SPLIT_COEF[LN_SPLIT_COEF.length-1][0];
y[1] = LN_SPLIT_COEF[LN_SPLIT_COEF.length-1][1];
for (int i = LN_SPLIT_COEF.length-2; i >= 0; i--) {
splitMult(y, x2, a);
y[0] = a[0];
y[1] = a[1];
splitAdd(y, LN_SPLIT_COEF[i], a);
y[0] = a[0];
y[1] = a[1];
}
splitMult(y, x, a);
y[0] = a[0];
y[1] = a[1];
return y;
}
/**
* Print an array.
* @param out text output stream where output should be printed
* @param name array name
* @param expectedLen expected length of the array
* @param array2d array data
*/
static void printarray(PrintStream out, String name, int expectedLen, double[][] array2d) {
out.println(name);
checkLen(expectedLen, array2d.length);
out.println(TABLE_START_DECL + " ");
int i = 0;
for(double[] array : array2d) { // "double array[]" causes PMD parsing error
out.print(" {");
for(double d : array) { // assume inner array has very few entries
out.printf("%-25.25s", format(d)); // multiple entries per line
}
out.println("}, // " + i++);
}
out.println(TABLE_END_DECL);
}
/**
* Print an array.
* @param out text output stream where output should be printed
* @param name array name
* @param expectedLen expected length of the array
* @param array array data
*/
static void printarray(PrintStream out, String name, int expectedLen, double[] array) {
out.println(name + "=");
checkLen(expectedLen, array.length);
out.println(TABLE_START_DECL);
for(double d : array){
out.printf(" %s%n", format(d)); // one entry per line
}
out.println(TABLE_END_DECL);
}
/** Format a double.
* @param d double number to format
* @return formatted number
*/
static String format(double d) {
if (d != d) {
return "Double.NaN,";
} else {
return ((d >= 0) ? "+" : "") + Double.toString(d) + "d,";
}
}
/**
* Check two lengths are equal.
* @param expectedLen expected length
* @param actual actual length
* @exception DimensionMismatchException if the two lengths are not equal
*/
private static void checkLen(int expectedLen, int actual)
throws DimensionMismatchException {
if (expectedLen != actual) {
throw new DimensionMismatchException(actual, expectedLen);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,608 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math3.util;
import java.math.BigDecimal;
import org.apache.commons.math3.exception.MathArithmeticException;
import org.apache.commons.math3.exception.MathIllegalArgumentException;
import org.apache.commons.math3.exception.util.LocalizedFormats;
/**
* Utilities for comparing numbers.
*
* @since 3.0
*/
public class Precision {
/**
* <p>
* Largest double-precision floating-point number such that
* {@code 1 + EPSILON} is numerically equal to 1. This value is an upper
* bound on the relative error due to rounding real numbers to double
* precision floating-point numbers.
* </p>
* <p>
* In IEEE 754 arithmetic, this is 2<sup>-53</sup>.
* </p>
*
* @see <a href="http://en.wikipedia.org/wiki/Machine_epsilon">Machine epsilon</a>
*/
public static final double EPSILON;
/**
* Safe minimum, such that {@code 1 / SAFE_MIN} does not overflow.
* <br/>
* In IEEE 754 arithmetic, this is also the smallest normalized
* number 2<sup>-1022</sup>.
*/
public static final double SAFE_MIN;
/** Exponent offset in IEEE754 representation. */
private static final long EXPONENT_OFFSET = 1023l;
/** Offset to order signed double numbers lexicographically. */
private static final long SGN_MASK = 0x8000000000000000L;
/** Offset to order signed double numbers lexicographically. */
private static final int SGN_MASK_FLOAT = 0x80000000;
/** Positive zero. */
private static final double POSITIVE_ZERO = 0d;
/** Positive zero bits. */
private static final long POSITIVE_ZERO_DOUBLE_BITS = Double.doubleToRawLongBits(+0.0);
/** Negative zero bits. */
private static final long NEGATIVE_ZERO_DOUBLE_BITS = Double.doubleToRawLongBits(-0.0);
/** Positive zero bits. */
private static final int POSITIVE_ZERO_FLOAT_BITS = Float.floatToRawIntBits(+0.0f);
/** Negative zero bits. */
private static final int NEGATIVE_ZERO_FLOAT_BITS = Float.floatToRawIntBits(-0.0f);
static {
/*
* This was previously expressed as = 0x1.0p-53;
* However, OpenJDK (Sparc Solaris) cannot handle such small
* constants: MATH-721
*/
EPSILON = Double.longBitsToDouble((EXPONENT_OFFSET - 53l) << 52);
/*
* This was previously expressed as = 0x1.0p-1022;
* However, OpenJDK (Sparc Solaris) cannot handle such small
* constants: MATH-721
*/
SAFE_MIN = Double.longBitsToDouble((EXPONENT_OFFSET - 1022l) << 52);
}
/**
* Private constructor.
*/
private Precision() {}
/**
* Compares two numbers given some amount of allowed error.
*
* @param x the first number
* @param y the second number
* @param eps the amount of error to allow when checking for equality
* @return <ul><li>0 if {@link #equals(double, double, double) equals(x, y, eps)}</li>
* <li>&lt; 0 if !{@link #equals(double, double, double) equals(x, y, eps)} &amp;&amp; x &lt; y</li>
* <li>> 0 if !{@link #equals(double, double, double) equals(x, y, eps)} &amp;&amp; x > y or
* either argument is NaN</li></ul>
*/
public static int compareTo(double x, double y, double eps) {
if (equals(x, y, eps)) {
return 0;
} else if (x < y) {
return -1;
}
return 1;
}
/**
* Compares two numbers given some amount of allowed error.
* Two float numbers are considered equal if there are {@code (maxUlps - 1)}
* (or fewer) floating point numbers between them, i.e. two adjacent floating
* point numbers are considered equal.
* Adapted from <a
* href="http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/">
* Bruce Dawson</a>. Returns {@code false} if either of the arguments is NaN.
*
* @param x first value
* @param y second value
* @param maxUlps {@code (maxUlps - 1)} is the number of floating point
* values between {@code x} and {@code y}.
* @return <ul><li>0 if {@link #equals(double, double, int) equals(x, y, maxUlps)}</li>
* <li>&lt; 0 if !{@link #equals(double, double, int) equals(x, y, maxUlps)} &amp;&amp; x &lt; y</li>
* <li>&gt; 0 if !{@link #equals(double, double, int) equals(x, y, maxUlps)} &amp;&amp; x > y
* or either argument is NaN</li></ul>
*/
public static int compareTo(final double x, final double y, final int maxUlps) {
if (equals(x, y, maxUlps)) {
return 0;
} else if (x < y) {
return -1;
}
return 1;
}
/**
* Returns true iff they are equal as defined by
* {@link #equals(float,float,int) equals(x, y, 1)}.
*
* @param x first value
* @param y second value
* @return {@code true} if the values are equal.
*/
public static boolean equals(float x, float y) {
return equals(x, y, 1);
}
/**
* Returns true if both arguments are NaN or they are
* equal as defined by {@link #equals(float,float) equals(x, y, 1)}.
*
* @param x first value
* @param y second value
* @return {@code true} if the values are equal or both are NaN.
* @since 2.2
*/
public static boolean equalsIncludingNaN(float x, float y) {
return (x != x || y != y) ? !(x != x ^ y != y) : equals(x, y, 1);
}
/**
* Returns true if the arguments are equal or within the range of allowed
* error (inclusive). Returns {@code false} if either of the arguments
* is NaN.
*
* @param x first value
* @param y second value
* @param eps the amount of absolute error to allow.
* @return {@code true} if the values are equal or within range of each other.
* @since 2.2
*/
public static boolean equals(float x, float y, float eps) {
return equals(x, y, 1) || FastMath.abs(y - x) <= eps;
}
/**
* Returns true if the arguments are both NaN, are equal, or are within the range
* of allowed error (inclusive).
*
* @param x first value
* @param y second value
* @param eps the amount of absolute error to allow.
* @return {@code true} if the values are equal or within range of each other,
* or both are NaN.
* @since 2.2
*/
public static boolean equalsIncludingNaN(float x, float y, float eps) {
return equalsIncludingNaN(x, y) || (FastMath.abs(y - x) <= eps);
}
/**
* Returns true if the arguments are equal or within the range of allowed
* error (inclusive).
* Two float numbers are considered equal if there are {@code (maxUlps - 1)}
* (or fewer) floating point numbers between them, i.e. two adjacent floating
* point numbers are considered equal.
* Adapted from <a
* href="http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/">
* Bruce Dawson</a>. Returns {@code false} if either of the arguments is NaN.
*
* @param x first value
* @param y second value
* @param maxUlps {@code (maxUlps - 1)} is the number of floating point
* values between {@code x} and {@code y}.
* @return {@code true} if there are fewer than {@code maxUlps} floating
* point values between {@code x} and {@code y}.
* @since 2.2
*/
public static boolean equals(final float x, final float y, final int maxUlps) {
final int xInt = Float.floatToRawIntBits(x);
final int yInt = Float.floatToRawIntBits(y);
final boolean isEqual;
if (((xInt ^ yInt) & SGN_MASK_FLOAT) == 0) {
// number have same sign, there is no risk of overflow
isEqual = FastMath.abs(xInt - yInt) <= maxUlps;
} else {
// number have opposite signs, take care of overflow
final int deltaPlus;
final int deltaMinus;
if (xInt < yInt) {
deltaPlus = yInt - POSITIVE_ZERO_FLOAT_BITS;
deltaMinus = xInt - NEGATIVE_ZERO_FLOAT_BITS;
} else {
deltaPlus = xInt - POSITIVE_ZERO_FLOAT_BITS;
deltaMinus = yInt - NEGATIVE_ZERO_FLOAT_BITS;
}
if (deltaPlus > maxUlps) {
isEqual = false;
} else {
isEqual = deltaMinus <= (maxUlps - deltaPlus);
}
}
return isEqual && !Float.isNaN(x) && !Float.isNaN(y);
}
/**
* Returns true if the arguments are both NaN or if they are equal as defined
* by {@link #equals(float,float,int) equals(x, y, maxUlps)}.
*
* @param x first value
* @param y second value
* @param maxUlps {@code (maxUlps - 1)} is the number of floating point
* values between {@code x} and {@code y}.
* @return {@code true} if both arguments are NaN or if there are less than
* {@code maxUlps} floating point values between {@code x} and {@code y}.
* @since 2.2
*/
public static boolean equalsIncludingNaN(float x, float y, int maxUlps) {
return (x != x || y != y) ? !(x != x ^ y != y) : equals(x, y, maxUlps);
}
/**
* Returns true iff they are equal as defined by
* {@link #equals(double,double,int) equals(x, y, 1)}.
*
* @param x first value
* @param y second value
* @return {@code true} if the values are equal.
*/
public static boolean equals(double x, double y) {
return equals(x, y, 1);
}
/**
* Returns true if the arguments are both NaN or they are
* equal as defined by {@link #equals(double,double) equals(x, y, 1)}.
*
* @param x first value
* @param y second value
* @return {@code true} if the values are equal or both are NaN.
* @since 2.2
*/
public static boolean equalsIncludingNaN(double x, double y) {
return (x != x || y != y) ? !(x != x ^ y != y) : equals(x, y, 1);
}
/**
* Returns {@code true} if there is no double value strictly between the
* arguments or the difference between them is within the range of allowed
* error (inclusive). Returns {@code false} if either of the arguments
* is NaN.
*
* @param x First value.
* @param y Second value.
* @param eps Amount of allowed absolute error.
* @return {@code true} if the values are two adjacent floating point
* numbers or they are within range of each other.
*/
public static boolean equals(double x, double y, double eps) {
return equals(x, y, 1) || FastMath.abs(y - x) <= eps;
}
/**
* Returns {@code true} if there is no double value strictly between the
* arguments or the relative difference between them is less than or equal
* to the given tolerance. Returns {@code false} if either of the arguments
* is NaN.
*
* @param x First value.
* @param y Second value.
* @param eps Amount of allowed relative error.
* @return {@code true} if the values are two adjacent floating point
* numbers or they are within range of each other.
* @since 3.1
*/
public static boolean equalsWithRelativeTolerance(double x, double y, double eps) {
if (equals(x, y, 1)) {
return true;
}
final double absoluteMax = FastMath.max(FastMath.abs(x), FastMath.abs(y));
final double relativeDifference = FastMath.abs((x - y) / absoluteMax);
return relativeDifference <= eps;
}
/**
* Returns true if the arguments are both NaN, are equal or are within the range
* of allowed error (inclusive).
*
* @param x first value
* @param y second value
* @param eps the amount of absolute error to allow.
* @return {@code true} if the values are equal or within range of each other,
* or both are NaN.
* @since 2.2
*/
public static boolean equalsIncludingNaN(double x, double y, double eps) {
return equalsIncludingNaN(x, y) || (FastMath.abs(y - x) <= eps);
}
/**
* Returns true if the arguments are equal or within the range of allowed
* error (inclusive).
* <p>
* Two float numbers are considered equal if there are {@code (maxUlps - 1)}
* (or fewer) floating point numbers between them, i.e. two adjacent
* floating point numbers are considered equal.
* </p>
* <p>
* Adapted from <a
* href="http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/">
* Bruce Dawson</a>. Returns {@code false} if either of the arguments is NaN.
* </p>
*
* @param x first value
* @param y second value
* @param maxUlps {@code (maxUlps - 1)} is the number of floating point
* values between {@code x} and {@code y}.
* @return {@code true} if there are fewer than {@code maxUlps} floating
* point values between {@code x} and {@code y}.
*/
public static boolean equals(final double x, final double y, final int maxUlps) {
final long xInt = Double.doubleToRawLongBits(x);
final long yInt = Double.doubleToRawLongBits(y);
final boolean isEqual;
if (((xInt ^ yInt) & SGN_MASK) == 0l) {
// number have same sign, there is no risk of overflow
isEqual = FastMath.abs(xInt - yInt) <= maxUlps;
} else {
// number have opposite signs, take care of overflow
final long deltaPlus;
final long deltaMinus;
if (xInt < yInt) {
deltaPlus = yInt - POSITIVE_ZERO_DOUBLE_BITS;
deltaMinus = xInt - NEGATIVE_ZERO_DOUBLE_BITS;
} else {
deltaPlus = xInt - POSITIVE_ZERO_DOUBLE_BITS;
deltaMinus = yInt - NEGATIVE_ZERO_DOUBLE_BITS;
}
if (deltaPlus > maxUlps) {
isEqual = false;
} else {
isEqual = deltaMinus <= (maxUlps - deltaPlus);
}
}
return isEqual && !Double.isNaN(x) && !Double.isNaN(y);
}
/**
* Returns true if both arguments are NaN or if they are equal as defined
* by {@link #equals(double,double,int) equals(x, y, maxUlps)}.
*
* @param x first value
* @param y second value
* @param maxUlps {@code (maxUlps - 1)} is the number of floating point
* values between {@code x} and {@code y}.
* @return {@code true} if both arguments are NaN or if there are less than
* {@code maxUlps} floating point values between {@code x} and {@code y}.
* @since 2.2
*/
public static boolean equalsIncludingNaN(double x, double y, int maxUlps) {
return (x != x || y != y) ? !(x != x ^ y != y) : equals(x, y, maxUlps);
}
/**
* Rounds the given value to the specified number of decimal places.
* The value is rounded using the {@link BigDecimal#ROUND_HALF_UP} method.
*
* @param x Value to round.
* @param scale Number of digits to the right of the decimal point.
* @return the rounded value.
* @since 1.1 (previously in {@code MathUtils}, moved as of version 3.0)
*/
public static double round(double x, int scale) {
return round(x, scale, BigDecimal.ROUND_HALF_UP);
}
/**
* Rounds the given value to the specified number of decimal places.
* The value is rounded using the given method which is any method defined
* in {@link BigDecimal}.
* If {@code x} is infinite or {@code NaN}, then the value of {@code x} is
* returned unchanged, regardless of the other parameters.
*
* @param x Value to round.
* @param scale Number of digits to the right of the decimal point.
* @param roundingMethod Rounding method as defined in {@link BigDecimal}.
* @return the rounded value.
* @throws ArithmeticException if {@code roundingMethod == ROUND_UNNECESSARY}
* and the specified scaling operation would require rounding.
* @throws IllegalArgumentException if {@code roundingMethod} does not
* represent a valid rounding mode.
* @since 1.1 (previously in {@code MathUtils}, moved as of version 3.0)
*/
public static double round(double x, int scale, int roundingMethod) {
try {
final double rounded = (new BigDecimal(Double.toString(x))
.setScale(scale, roundingMethod))
.doubleValue();
// MATH-1089: negative values rounded to zero should result in negative zero
return rounded == POSITIVE_ZERO ? POSITIVE_ZERO * x : rounded;
} catch (NumberFormatException ex) {
if (Double.isInfinite(x)) {
return x;
} else {
return Double.NaN;
}
}
}
/**
* Rounds the given value to the specified number of decimal places.
* The value is rounded using the {@link BigDecimal#ROUND_HALF_UP} method.
*
* @param x Value to round.
* @param scale Number of digits to the right of the decimal point.
* @return the rounded value.
* @since 1.1 (previously in {@code MathUtils}, moved as of version 3.0)
*/
public static float round(float x, int scale) {
return round(x, scale, BigDecimal.ROUND_HALF_UP);
}
/**
* Rounds the given value to the specified number of decimal places.
* The value is rounded using the given method which is any method defined
* in {@link BigDecimal}.
*
* @param x Value to round.
* @param scale Number of digits to the right of the decimal point.
* @param roundingMethod Rounding method as defined in {@link BigDecimal}.
* @return the rounded value.
* @since 1.1 (previously in {@code MathUtils}, moved as of version 3.0)
* @throws MathArithmeticException if an exact operation is required but result is not exact
* @throws MathIllegalArgumentException if {@code roundingMethod} is not a valid rounding method.
*/
public static float round(float x, int scale, int roundingMethod)
throws MathArithmeticException, MathIllegalArgumentException {
final float sign = FastMath.copySign(1f, x);
final float factor = (float) FastMath.pow(10.0f, scale) * sign;
return (float) roundUnscaled(x * factor, sign, roundingMethod) / factor;
}
/**
* Rounds the given non-negative value to the "nearest" integer. Nearest is
* determined by the rounding method specified. Rounding methods are defined
* in {@link BigDecimal}.
*
* @param unscaled Value to round.
* @param sign Sign of the original, scaled value.
* @param roundingMethod Rounding method, as defined in {@link BigDecimal}.
* @return the rounded value.
* @throws MathArithmeticException if an exact operation is required but result is not exact
* @throws MathIllegalArgumentException if {@code roundingMethod} is not a valid rounding method.
* @since 1.1 (previously in {@code MathUtils}, moved as of version 3.0)
*/
private static double roundUnscaled(double unscaled,
double sign,
int roundingMethod)
throws MathArithmeticException, MathIllegalArgumentException {
switch (roundingMethod) {
case BigDecimal.ROUND_CEILING :
if (sign == -1) {
unscaled = FastMath.floor(FastMath.nextAfter(unscaled, Double.NEGATIVE_INFINITY));
} else {
unscaled = FastMath.ceil(FastMath.nextAfter(unscaled, Double.POSITIVE_INFINITY));
}
break;
case BigDecimal.ROUND_DOWN :
unscaled = FastMath.floor(FastMath.nextAfter(unscaled, Double.NEGATIVE_INFINITY));
break;
case BigDecimal.ROUND_FLOOR :
if (sign == -1) {
unscaled = FastMath.ceil(FastMath.nextAfter(unscaled, Double.POSITIVE_INFINITY));
} else {
unscaled = FastMath.floor(FastMath.nextAfter(unscaled, Double.NEGATIVE_INFINITY));
}
break;
case BigDecimal.ROUND_HALF_DOWN : {
unscaled = FastMath.nextAfter(unscaled, Double.NEGATIVE_INFINITY);
double fraction = unscaled - FastMath.floor(unscaled);
if (fraction > 0.5) {
unscaled = FastMath.ceil(unscaled);
} else {
unscaled = FastMath.floor(unscaled);
}
break;
}
case BigDecimal.ROUND_HALF_EVEN : {
double fraction = unscaled - FastMath.floor(unscaled);
if (fraction > 0.5) {
unscaled = FastMath.ceil(unscaled);
} else if (fraction < 0.5) {
unscaled = FastMath.floor(unscaled);
} else {
// The following equality test is intentional and needed for rounding purposes
if (FastMath.floor(unscaled) / 2.0 == FastMath.floor(FastMath.floor(unscaled) / 2.0)) { // even
unscaled = FastMath.floor(unscaled);
} else { // odd
unscaled = FastMath.ceil(unscaled);
}
}
break;
}
case BigDecimal.ROUND_HALF_UP : {
unscaled = FastMath.nextAfter(unscaled, Double.POSITIVE_INFINITY);
double fraction = unscaled - FastMath.floor(unscaled);
if (fraction >= 0.5) {
unscaled = FastMath.ceil(unscaled);
} else {
unscaled = FastMath.floor(unscaled);
}
break;
}
case BigDecimal.ROUND_UNNECESSARY :
if (unscaled != FastMath.floor(unscaled)) {
throw new MathArithmeticException();
}
break;
case BigDecimal.ROUND_UP :
// do not round if the discarded fraction is equal to zero
if (unscaled != FastMath.floor(unscaled)) {
unscaled = FastMath.ceil(FastMath.nextAfter(unscaled, Double.POSITIVE_INFINITY));
}
break;
default :
throw new MathIllegalArgumentException(LocalizedFormats.INVALID_ROUNDING_METHOD,
roundingMethod,
"ROUND_CEILING", BigDecimal.ROUND_CEILING,
"ROUND_DOWN", BigDecimal.ROUND_DOWN,
"ROUND_FLOOR", BigDecimal.ROUND_FLOOR,
"ROUND_HALF_DOWN", BigDecimal.ROUND_HALF_DOWN,
"ROUND_HALF_EVEN", BigDecimal.ROUND_HALF_EVEN,
"ROUND_HALF_UP", BigDecimal.ROUND_HALF_UP,
"ROUND_UNNECESSARY", BigDecimal.ROUND_UNNECESSARY,
"ROUND_UP", BigDecimal.ROUND_UP);
}
return unscaled;
}
/**
* Computes a number {@code delta} close to {@code originalDelta} with
* the property that <pre><code>
* x + delta - x
* </code></pre>
* is exactly machine-representable.
* This is useful when computing numerical derivatives, in order to reduce
* roundoff errors.
*
* @param x Value.
* @param originalDelta Offset value.
* @return a number {@code delta} so that {@code x + delta} and {@code x}
* differ by a representable floating number.
*/
public static double representableDelta(double x,
double originalDelta) {
return x + originalDelta - x;
}
}

View File

@ -112,6 +112,12 @@ public class ClientPlatformSingleplayer {
} else if(s.equals("smoothWorld:false")) { } else if(s.equals("smoothWorld:false")) {
MinecraftServer.smoothWorld = false; MinecraftServer.smoothWorld = false;
return; return;
} else if(s.contains("fullbright:true")) {
MinecraftServer.isFullBright = true;
return;
} else if(s.contains("fullbright:false")) {
MinecraftServer.isFullBright = false;
return;
} else if(s.contains("ofTrees")) { } else if(s.contains("ofTrees")) {
String[] value = s.split(":"); String[] value = s.split(":");
int i = Integer.parseInt(value[1]); int i = Integer.parseInt(value[1]);

View File

@ -79,6 +79,12 @@ public class ServerPlatformSingleplayer {
} else if(s.equals("smoothWorld:false")) { } else if(s.equals("smoothWorld:false")) {
MinecraftServer.smoothWorld = false; MinecraftServer.smoothWorld = false;
return; return;
} else if(s.contains("fullbright:true")) {
MinecraftServer.isFullBright = true;
return;
} else if(s.contains("fullbright:false")) {
MinecraftServer.isFullBright = false;
return;
} else if(s.contains("ofTrees")) { } else if(s.contains("ofTrees")) {
String[] value = s.split(":"); String[] value = s.split(":");
int i = Integer.parseInt(value[1]); int i = Integer.parseInt(value[1]);

View File

@ -1261,6 +1261,7 @@ public class Minecraft extends ModData implements IThreadListener {
/**+ /**+
* Runs the current tick. * Runs the current tick.
*/ */
public boolean packetsSent = false;
public void runTick() throws IOException { public void runTick() throws IOException {
Minecraft.getMinecraft().modapi.onFrame(); Minecraft.getMinecraft().modapi.onFrame();
if (this.rightClickDelayTimer > 0) { if (this.rightClickDelayTimer > 0) {
@ -1693,20 +1694,24 @@ public class Minecraft extends ModData implements IThreadListener {
this.fixWorldTime(); this.fixWorldTime();
} }
if(Config.isWeatherEnabled()) { if(!packetsSent) {
ClientPlatformSingleplayer.sendPacket(new IPCPacketData("iFuckingHateWebworkers", "weather:true".getBytes())); if(Config.isWeatherEnabled()) {
} else { ClientPlatformSingleplayer.sendPacket(new IPCPacketData("iFuckingHateWebworkers", "weather:true".getBytes()));
ClientPlatformSingleplayer.sendPacket(new IPCPacketData("iFuckingHateWebworkers", "weather:false".getBytes())); } else {
} ClientPlatformSingleplayer.sendPacket(new IPCPacketData("iFuckingHateWebworkers", "weather:false".getBytes()));
}
if(Config.isSmoothWorld()) { if(Config.isSmoothWorld()) {
ClientPlatformSingleplayer.sendPacket(new IPCPacketData("iFuckingHateWebworkers", "smoothWorld:true".getBytes())); ClientPlatformSingleplayer.sendPacket(new IPCPacketData("iFuckingHateWebworkers", "smoothWorld:true".getBytes()));
} else { } else {
ClientPlatformSingleplayer.sendPacket(new IPCPacketData("iFuckingHateWebworkers", "smoothWorld:false".getBytes())); ClientPlatformSingleplayer.sendPacket(new IPCPacketData("iFuckingHateWebworkers", "smoothWorld:false".getBytes()));
} }
ClientPlatformSingleplayer.sendPacket(new IPCPacketData("iFuckingHateWebworkers", new String("ofTrees:" + gameSettings.ofTrees).getBytes())); ClientPlatformSingleplayer.sendPacket(new IPCPacketData("iFuckingHateWebworkers", new String("ofTrees:" + gameSettings.ofTrees).getBytes()));
ClientPlatformSingleplayer.sendPacket(new IPCPacketData("iFuckingHateWebworkers", new String("graphics:" + gameSettings.fancyGraphics).getBytes())); ClientPlatformSingleplayer.sendPacket(new IPCPacketData("iFuckingHateWebworkers", new String("graphics:" + gameSettings.fancyGraphics).getBytes()));
ClientPlatformSingleplayer.sendPacket(new IPCPacketData("iFuckingHateWebworkers", new String("fullbright:" + gameSettings.fullBright).getBytes()));
packetsSent = true;
}
if (Config.waterOpacityChanged) { if (Config.waterOpacityChanged) {
Config.waterOpacityChanged = false; Config.waterOpacityChanged = false;
@ -1842,6 +1847,7 @@ public class Minecraft extends ModData implements IThreadListener {
this.guiAchievement.clearAchievements(); this.guiAchievement.clearAchievements();
this.entityRenderer.getMapItemRenderer().clearLoadedMaps(); this.entityRenderer.getMapItemRenderer().clearLoadedMaps();
packetsSent = false;
} }
this.renderViewEntity = null; this.renderViewEntity = null;

View File

@ -496,6 +496,8 @@ public class GameSettings extends ModData {
* value), this will set the float value. * value), this will set the float value.
*/ */
public void setOptionFloatValue(GameSettings.Options parOptions, float parFloat1) { public void setOptionFloatValue(GameSettings.Options parOptions, float parFloat1) {
Minecraft.getMinecraft().packetsSent = false;
if (parOptions == GameSettings.Options.SENSITIVITY) { if (parOptions == GameSettings.Options.SENSITIVITY) {
this.mouseSensitivity = parFloat1; this.mouseSensitivity = parFloat1;
} }
@ -615,6 +617,8 @@ public class GameSettings extends ModData {
* through the list i.e. render distances. * through the list i.e. render distances.
*/ */
public void setOptionValue(GameSettings.Options parOptions, int parInt1) { public void setOptionValue(GameSettings.Options parOptions, int parInt1) {
Minecraft.getMinecraft().packetsSent = false;
if (parOptions == GameSettings.Options.INVERT_MOUSE) { if (parOptions == GameSettings.Options.INVERT_MOUSE) {
this.invertMouse = !this.invertMouse; this.invertMouse = !this.invertMouse;
} }