com.javanut.pronghorn.util.math.PMath Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pronghorn-pipes Show documentation
Show all versions of pronghorn-pipes Show documentation
Ring buffer based queuing utility for applications that require high performance and/or a small
footprint. Well suited for embedded and stream based processing.
package com.javanut.pronghorn.util.math;
/*
* @Author Nathan Tippy
*/
public class PMath {
//WARNING: asking for large primes or factors may cause this array to grow out of control
private static int[] primes = new int[] {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97,
101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193};
//can deal with prime factors up to the "length" prime number
public static void factors(long value, byte[] target, int offset, int length, int mask) {
int pIndex = 0;
do {
int exponent = 0;
if (1 != value) { //no work to do if the value is 1
int p = primeAtIdx(pIndex++);
boolean continueCheck = false;
do {
long d = value/p;
long r = value%p;
if (r==0) {
value = d;
exponent++;
continueCheck = (d!=1);
} else {
continueCheck = false;
}
} while (continueCheck);
}
target[mask&offset++] = (byte)exponent;
//increment even it was not divisible so we can record that fact as blank spot
} while (--length>0);
}
public static void greatestCommonFactor( byte[] backingA, int offsetA, int lengthA, int maskA,
byte[] backingB, int offsetB, int lengthB, int maskB,
byte[] target, int offset, int length, int mask) {
if (length=0) {
int a = length>=lengthA ? 0 : (backingA[(offsetA+length)&maskA]);
int b = length>=lengthB ? 0 : (backingB[(offsetB+length)&maskB]);
target[(offset+length)&mask] = (byte)Math.min(a, b);
}
}
public static void greatestCommonFactor( byte[][] backingA, int[] offsetA, int[] lengthA, int[] maskA,
byte[] target, int offset, int length, int mask) {
assert(isNotLessThanAny(length, lengthA));
while (--length>=0) {
int min = Integer.MAX_VALUE;
int i = backingA.length;
while (--i>=0) {
assert( (backingA[i][(offsetA[i]+length)&maskA[i]]) >= 0) : "only works on integers not rationals";
min = Math.min((int) (length>=lengthA[i] ? 0 : (backingA[i][(offsetA[i]+length)&maskA[i]])), min);
}
target[(offset+length)&mask] = (min==Integer.MAX_VALUE?0:(byte)min);
}
}
private static boolean isNotLessThanAny(int x, int[] y) {
int i = y.length;
while (--i>=0) {
if (x=0) {
int a = length>=lengthA ? 0 : (backingA[(offsetA+length)&maskA]);
int b = length>=lengthB ? 0 : (backingB[(offsetB+length)&maskB]);
target[(offset+length)&mask] = (byte)(a-b);
}
}
/*
* A contains the factors of B and we want them removed. The result is in target
* Any factors not found in A are not removed. Eg. this is a modulus divide leaving the remainder.
*/
public static void removeExistingFactors( byte[] backingA, int offsetA, int lengthA, int maskA,
byte[] backingB, int offsetB, int lengthB, int maskB,
byte[] target, int offset, int length, int mask) {
if (length=0) {
int a = length>=lengthA ? 0 : (backingA[(offsetA+length)&maskA]);
int b = length>=lengthB ? 0 : (backingB[(offsetB+length)&maskB]);
target[(offset+length)&mask] = (byte)Math.max(a-b,0); //never goes negative
}
}
/*
*
*
* This operation is the same as integer multiply. the result is A*B
*/
public static void addFactors( byte[] backingA, int offsetA, int lengthA, int maskA,
byte[] backingB, int offsetB, int lengthB, int maskB,
byte[] target, int offset, int length, int mask) {
if (length=0) {
int a = length>=lengthA ? 0 : (backingA[(offsetA+length)&maskA]);
int b = length>=lengthB ? 0 : (backingB[(offsetB+length)&maskB]);
target[(offset+length)&mask] = (byte)(a+b);
}
}
public static int factorsToInt(byte[] target, int offset, int length, int mask) {
int value = 1;
while (--length>=0) {
int j = target[(offset+length)&mask];
if (j<0) {
throw new UnsupportedOperationException("This rational number can not be expressed as an integer");
}
while (--j>=0) {
value = value * primeAtIdx(length);
}
}
return value;
}
public static long factorsToLong(byte[] target, int offset, int length, int mask) {
long value = 1;
while (--length>=0) {
int j = target[(offset+length)&mask];
if (j<0) {
throw new UnsupportedOperationException("This rational number can not be expressed as an integer");
}
while (--j>=0) {
value = value * primeAtIdx(length);
}
}
return value;
}
/**
* Grows the internal array as needed. Then returns the prime at that index.
* NOTE: 0 index will return 2 and 1 index will return 3 (they are zero based)
* @param i
* @return
*/
private static int primeAtIdx(int i) {
int[] localPrimes = primes;
while (i>=localPrimes.length) {
//Must build out primes to the required index
int v = localPrimes[localPrimes.length-1];
while (!isPrime(++v)) {}
int[] newPrimes = new int[primes.length+1];
System.arraycopy(primes, 0, newPrimes, 0, primes.length);
newPrimes[primes.length]=v;
localPrimes = primes = newPrimes;
}
//return the value
return primes[i];
}
/**
* Next prime above the given value which need not be prime.
* @param startValue
* @return first prime discovered at or above start value
*/
public static int nextPrime(int startValue) {
int i = 0;
int p = 1;
while ((p=primeAtIdx(i++))=0) {
if (i%primes[j] == 0) {
return false;
}
}
return true;
}
public static ScriptedSchedule buildScriptedSchedule(long[] schedulePeriods) {
return buildScriptedSchedule(schedulePeriods, false);
}
/**
*
* @param schedulePeriods array of periods that the item at each index is epxpected to run
* @param reverseOrder the reversed order schedule may be desirable under heavy load conditions with directed graphs.
* @return new scripted schedule object to be used at runtime.
*/
public static ScriptedSchedule buildScriptedSchedule(long[] schedulePeriods, final boolean reverseOrder) {
assert(schedulePeriods.length=0) {
if (0==((bases[i] + r) % steps[i])) {
if (++runCount >= maxRun) {
maxRun = runCount;
}
script[s++]=i;
}
}
} else {
//NOTE: this run covers all the items to run at the "same" time
for(int i=0;i= maxRun) {
maxRun = runCount;
}
script[s++]=i;
}
}
}
//finished with run.
script[s++] = -1;
}
//System.out.println(Arrays.toString(script));
return new ScriptedSchedule(commonClock, script, maxRun);
}
private static int largestPrimeFactorIdx(byte[] target, int offset, int length, int mask) {
while (--length>=0) {
int j = target[(offset+length)&mask];
if (j!=0) {
return length;
}
}
return -1;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy