All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.javanut.pronghorn.util.math.PMath Maven / Gradle / Ivy

Go to download

Ring buffer based queuing utility for applications that require high performance and/or a small footprint. Well suited for embedded and stream based processing.

There is a newer version: 1.1.27
Show newest version
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