```/*
*
*/
package jrc.it.geolocation.common;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.math3.util.FastMath;

import jrc.it.geolocation.exception.MathException;

public class MathUtil {

public static double[] powArray(double a[],double pow){
double[]  apow=new double[a.length];
for(int i=0;i<a.length;i++){
apow[i]=FastMath.pow(a[i], pow);
}
return apow;
}

/**
*
* @param val
* @param pows
* @return
*/
public static double[] powValue2Coeffs(double val,int pows[]){
double[]  apow=new double[pows.length];
for(int i=0;i<pows.length;i++){
apow[i]=FastMath.pow(val, pows[i]);
}
return apow;
}

/**
* divide each element of vector for val
*
* @param vector
* @param val
* @return
*/
public static double[] divVectByVal(double[] vector,double val){
double[]  r=new double[vector.length];
for(int i=0;i<vector.length;i++){
r[i]=vector[i]/val;
}
return r;
}

/**
*  return the Euclidean norm of this Vector
* @return
*/
public static double norm(double[] v) {
return FastMath.sqrt(dot(v,v));
}

/**
* return the scalar product
* @param v1,v2 should have the same length
* @return
*/
public static double dot(double[] v1,double[] v2) {
double sum = 0.0;
for (int i = 0; i < v1.length; i++)
sum = sum + (v1[i] * v2[i]);
return sum;
}

/**
* cross product    (a2b3-a3b2)^i+(a3b1-a1b3)^j+(a1b2-a2b1)^k
* @param v1,v2 should have the same length
* @return
*/
public static double[] crossProd3x3(double[] a,double[] b) {
double p[] = new double[a.length];
//for (int i = 0; i < v1.length; i++)
//    p[i] = v1[i] * v2[i];
p[0]=a[1]*b[2]-a[2]*b[1];
p[1]=a[2]*b[0]-a[0]*b[2];
p[2]=a[0]*b[1]-a[1]*b[0];

return p;
}

public static double[][] transpose(double[][] m) {
// returns the transpose of this matrix object
double[][] t = new double[m[0].length][m.length];
int i, j;
for (i = 0; i<m.length; i++) {
for (j = 0; j<m[0].length; j++) {
t[j][i] = m[i][j];
}
}
return t;
}

/**
*
* @param a
* @param b
* @return
* @throws MathException
*/
public static double[][] multiplyMatrix(double[][] m1,double[][] m2) throws MathException{
int m1ColLength = m1[0].length; // m1 columns length
int m2RowLength = m2.length;    // m2 rows length
if(m1ColLength != m2RowLength)
throw new MathException("Wrong matrix dimension "); // matrix multiplication is not possible
int mRRowLength = m1.length;    // m result rows length
int mRColLength = m2[0].length; // m result columns length
double[][] mResult = new double[mRRowLength][mRColLength];
for(int i = 0; i < mRRowLength; i++) {         // rows from m1
for(int j = 0; j < mRColLength; j++) {     // columns from m2
for(int k = 0; k < m1ColLength; k++) { // columns from m1
mResult[i][j] += m1[i][k] * m2[k][j];
}
}
}
return mResult;

}

/**
* Convolution U(m)=Sum( H(m)X(n-m) )    0<=m=<(size(H)-1) n=size(H)
*
* This function reproduce the matlab conv function with shape='valid'
*
* @param a
* @param b
* @return
*/
public static double[] linearConvolutionMatlabValid(double a[],double b[]){
//size of the array result without zero padd values
int sizeResult=a.length+b.length-1;
int matlabSizeResult=a.length-b.length+1;

double[] u=new double[sizeResult];
int idU=0;
for(int n=0;n<sizeResult;n++){
double val=0;

for(int m=0;m<=n;m++){
int idx1=m;
int idx2=n-m;

if(idx2>=0&&idx1>=0&&idx2<b.length-1&&idx1<a.length){
val=val+a[idx1]*b[idx2];
}
}
u[idU]=val;
idU++;
}
int diff=(sizeResult-matlabSizeResult);
int idxStart=diff/2+diff%2;
int idxEnd=u.length-diff/2;
u=ArrayUtils.subarray(u, idxStart, idxEnd);

return u;
}

}
```