Here you can find the source of norm(final double[] x)
Parameter | Description |
---|---|
x | a parameter |
public static final double norm(final double[] x)
//package com.java2s; /*//from www.ja v a2 s . c o m * ==================================================== * Copyright (C) 2013 by Idylwood Technologies, LLC. All rights reserved. * * Developed at Idylwood Technologies, LLC. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * The License should have been distributed to you with the source tree. * If not, it can be found 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. * * Author: Charles Cooper * Date: 2013 * ==================================================== */ public class Main { /** * Returns sqrt(x*x), the Euclidean norm. * @param x * @return */ public static final double norm(final double[] x) { return Math.sqrt(normSquared(x)); } /** * Returns x*x, or x_1^2 + x_2^2 .., the Euclidean norm squared. * @param x * @return */ public static final double normSquared(final double[] x) { return linearCombination(x, x); } /** * Numerically precise dot product. Keeps a running error along with the * accumulator. Equivalent to MathUtils.sum(MathUtils.multiply(x,y)) * but much faster and with O(1) memory overhead. * O(n) with O(1) space. * Even faster than the naive implementation ;). * @param x Reference to first array * @param y Reference to second array * @param startOne Offset from beginning of first array * @param startTwo Offset from beginning of second array * @param len Number of terms to combine * @throws ArrayIndexOutOfBoundsException if the input indices don't make sense * (in particular, if startOne + len > x.length || startTwo + len > y.length) * @return ddot(x,y) * Side Effects: none */ public static final double linearCombination(final double[] x, final double[] y, final int startOne, final int startTwo, final int len) { //if (true) return MathUtils.sum(MathUtils.multiply(x,y)); if (startOne + len > x.length || startTwo + len > y.length) throw new ArrayIndexOutOfBoundsException("Vector indices don't make sense!"); final int unroll = 4; // don't blindly change this without changing the loop! // unroll was tuned to my machine. the optimal value is // probably architecture specific. one day java is give access to SIMD // instructions and then this can be optimized more. final int len_down = len - len % unroll; double sum = 0; double err = 0; int i = 0; int xPtr = startOne; int yPtr = startTwo; // hopefully the cpu will pipeline all of these things for (; i < len_down; i += unroll, xPtr += unroll, yPtr += unroll) { // this line depends on unroll variable. final double prod = x[xPtr] * y[yPtr] + x[xPtr + 1] * y[yPtr + 1] + x[xPtr + 2] * y[yPtr + 2] + x[xPtr + 3] * y[yPtr + 3]; final double partial = prod - err; final double hi = sum + prod; err = (hi - sum) - partial; sum = hi; } for (; i < len; i++, xPtr++, yPtr++) { final double prod = x[xPtr] * y[yPtr]; final double partial = prod - err; final double hi = sum + prod; err = (hi - sum) - partial; sum = hi; } return sum; } /** * Calls {@link MathUtils#linearCombination(x,y,0,0,x.length)} * @param x * @param y * @throws ArrayIndexOutOfBoundsException if x and y have unequal length * @return */ public static final double linearCombination(final double[] x, final double[] y) { if (x.length != y.length) throw new ArrayIndexOutOfBoundsException("Unequal length vectors!"); return linearCombination(x, y, 0, 0, x.length); } }