001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.commons.rng.core.source64; 019 020import org.apache.commons.rng.JumpableUniformRandomProvider; 021import org.apache.commons.rng.UniformRandomProvider; 022 023/** 024 * A fast all-purpose 64-bit generator. 025 * 026 * <p>This is a member of the Xor-Shift-Rotate family of generators. Memory footprint is 128 bits 027 * and the period is 2<sup>128</sup>-1. Speed is expected to be similar to 028 * {@link XoShiRo256StarStar}.</p> 029 * 030 * @see <a href="http://xoshiro.di.unimi.it/xoroshiro128plusplus.c">Original source code</a> 031 * @see <a href="http://xoshiro.di.unimi.it/">xorshiro / xoroshiro generators</a> 032 * @since 1.3 033 */ 034public class XoRoShiRo128PlusPlus extends AbstractXoRoShiRo128 { 035 /** The coefficients for the jump function. */ 036 private static final long[] JUMP_COEFFICIENTS = { 037 0x2bd7a6a6e99c2ddcL, 0x0992ccaf6a6fca05L 038 }; 039 /** The coefficients for the long jump function. */ 040 private static final long[] LONG_JUMP_COEFFICIENTS = { 041 0x360fd5f2cf8d5d99L, 0x9c6e6877736c46e3L 042 }; 043 044 /** 045 * Creates a new instance. 046 * 047 * @param seed Initial seed. 048 * If the length is larger than 2, only the first 2 elements will 049 * be used; if smaller, the remaining elements will be automatically 050 * set. A seed containing all zeros will create a non-functional generator. 051 */ 052 public XoRoShiRo128PlusPlus(long[] seed) { 053 super(seed); 054 } 055 056 /** 057 * Creates a new instance using a 2 element seed. 058 * A seed containing all zeros will create a non-functional generator. 059 * 060 * @param seed0 Initial seed element 0. 061 * @param seed1 Initial seed element 1. 062 */ 063 public XoRoShiRo128PlusPlus(long seed0, long seed1) { 064 super(seed0, seed1); 065 } 066 067 /** 068 * Creates a copy instance. 069 * 070 * @param source Source to copy. 071 */ 072 protected XoRoShiRo128PlusPlus(XoRoShiRo128PlusPlus source) { 073 super(source); 074 } 075 076 /** {@inheritDoc} */ 077 @Override 078 public long next() { 079 // Override the abstract class to use a different state update step. 080 // Note: This requires different jump coefficients. 081 082 final long s0 = state0; 083 long s1 = state1; 084 final long result = Long.rotateLeft(s0 + s1, 17) + s0; 085 086 s1 ^= s0; 087 state0 = Long.rotateLeft(s0, 49) ^ s1 ^ (s1 << 21); // a, b 088 state1 = Long.rotateLeft(s1, 28); // c 089 090 return result; 091 } 092 093 /** {@inheritDoc} */ 094 @Override 095 protected long nextOutput() { 096 throw new UnsupportedOperationException("The PlusPlus algorithm redefines the next() method"); 097 } 098 099 /** {@inheritDoc} */ 100 @Override 101 public UniformRandomProvider jump() { 102 // Duplicated from the abstract class to change the jump coefficients 103 final UniformRandomProvider copy = copy(); 104 performJump(JUMP_COEFFICIENTS); 105 return copy; 106 } 107 108 /** {@inheritDoc} */ 109 @Override 110 public JumpableUniformRandomProvider longJump() { 111 // Duplicated from the abstract class to change the jump coefficients 112 final JumpableUniformRandomProvider copy = copy(); 113 performJump(LONG_JUMP_COEFFICIENTS); 114 return copy; 115 } 116 117 /** {@inheritDoc} */ 118 @Override 119 protected XoRoShiRo128PlusPlus copy() { 120 // This exists to ensure the jump function performed in the super class returns 121 // the correct class type. It should not be public. 122 return new XoRoShiRo128PlusPlus(this); 123 } 124}