Householder and QR decomposition for matrices (f64,f32,f16).

(not yet optimized)
pull/34/head
Christophe Favergeon 4 years ago
parent ae88662740
commit 91f599c052

1
.gitignore vendored

@ -26,3 +26,4 @@ build
Documentation/html/*
Doxygen/history.txt
Doxygen/dsp.dxy
__pycache__/

@ -1703,7 +1703,7 @@ FORMULA_MACROFILE =
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
USE_MATHJAX = NO
USE_MATHJAX = YES
# With MATHJAX_VERSION it is possible to specify the MathJax version to be used.
# Note that the different versions of MathJax have different requirements with
@ -1745,7 +1745,7 @@ MATHJAX_FORMAT = HTML-CSS
# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_RELPATH =
MATHJAX_RELPATH = https://cdn.jsdelivr.net/npm/mathjax@2
# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
# extension names that should be enabled during MathJax rendering. For example
@ -1757,7 +1757,7 @@ MATHJAX_RELPATH =
# MATHJAX_EXTENSIONS = ams
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_EXTENSIONS =
MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
# of code that will be used on startup of the MathJax code. See the MathJax site

@ -0,0 +1,146 @@
/******************************************************************************
* @file basic_math_functions.h
* @brief Public header file for CMSIS DSP Library
* @version V1.10.0
* @date 08 July 2021
* Target Processor: Cortex-M and Cortex-A cores
******************************************************************************/
/*
* Copyright (c) 2010-2020 Arm Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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.
*/
#ifndef _DEBUG_FUNCTIONS_H_
#define _DEBUG_FUNCTIONS_H_
#include "arm_math_types.h"
#include "arm_math_memory.h"
#include "dsp/none.h"
#include "dsp/utils.h"
#include "dsp/matrix_functions.h"
#include "dsp/matrix_functions_f16.h"
#include <stdio.h>
#ifdef __cplusplus
extern "C"
{
#endif
#if defined(ARM_FLOAT16_SUPPORTED)
#define PROW_f16(S,NB) \
{ \
printf("{%f",(double)(S)[0]); \
for(unsigned int i=1;i<(NB) ;i++) \
{ \
printf(",%f",(double)(S)[i]);\
} \
printf("}"); \
};
#define PV_f16(S,V,NB)\
{ \
printf("%s=",(S)); \
PROW_f16((V),(NB)); \
printf(";\n"); \
};
#define PM_f16(S,M) \
{ \
printf("%s={",(S)); \
for(unsigned int row=0;row<(M)->numRows;row++) \
{ \
if (row != 0) \
{ \
printf("\n,"); \
} \
PROW_f16((M)->pData + row * (M)->numCols, (M)->numCols);\
} \
printf("};\n"); \
}
#endif
#define PROW_f32(S,NB) \
{ \
printf("{%f",(double)(S)[0]); \
for(unsigned int i=1;i<(NB) ;i++) \
{ \
printf(",%f",(double)(S)[i]);\
} \
printf("}"); \
};
#define PV_f32(S,V,NB)\
{ \
printf("%s=",(S)); \
PROW_f32((V),(NB)); \
printf(";\n"); \
};
#define PM_f32(S,M) \
{ \
printf("%s={",(S)); \
for(unsigned int row=0;row<(M)->numRows;row++) \
{ \
if (row != 0) \
{ \
printf("\n,"); \
} \
PROW_f32((M)->pData + row * (M)->numCols, (M)->numCols);\
} \
printf("};\n"); \
}
#define PROW_f64(S,NB) \
{ \
printf("{%.20g",(double)(S)[0]); \
for(unsigned int i=1;i<(NB) ;i++) \
{ \
printf(",%.20g",(double)(S)[i]);\
} \
printf("}"); \
};
#define PV_f64(S,V,NB) \
{ \
printf("%s=",(S)); \
PROW_f64((V),(NB));\
printf(";\n"); \
};
#define PM_f64(S,M) \
{ \
printf("%s={",(S)); \
for(unsigned int row=0;row<(M)->numRows;row++) \
{ \
if (row != 0) \
{ \
printf("\n,"); \
} \
PROW_f64((M)->pData + row * (M)->numCols, (M)->numCols);\
} \
printf("};\n"); \
}
#ifdef __cplusplus
}
#endif
#endif /* ifndef _DEBUG_FUNCTIONS_H_ */

@ -109,6 +109,9 @@ extern "C"
* return <code>ARM_MATH_SUCCESS</code>.
*/
#define DEFAULT_HOUSEHOLDER_THRESHOLD_F64 (1.0e-16)
#define DEFAULT_HOUSEHOLDER_THRESHOLD_F32 (1.0e-12f)
/**
* @brief Instance structure for the floating-point matrix structure.
*/
@ -750,6 +753,88 @@ void arm_mat_init_f32(
arm_matrix_instance_f64 * d,
uint16_t * pp);
/**
@brief QR decomposition of a m x n floating point matrix with m >= n.
@param[in] pSrc points to input matrix structure. The source matrix is modified by the function.
@param[in] threshold norm2 threshold.
@param[out] pOutR points to output R matrix structure of dimension m x n
@param[out] pOutQ points to output Q matrix structure of dimension m x m
@param[out] pOutTau points to Householder scaling factors of dimension n
@param[inout] pTmpA points to a temporary vector of dimension m.
@param[inout] pTmpB points to a temporary vector of dimension n.
@return execution status
- \ref ARM_MATH_SUCCESS : Operation successful
- \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed
- \ref ARM_MATH_SINGULAR : Input matrix is found to be singular (non-invertible)
*/
arm_status arm_mat_qr_f32(
const arm_matrix_instance_f32 * pSrc,
const float32_t threshold,
arm_matrix_instance_f32 * pOutR,
arm_matrix_instance_f32 * pOutQ,
float32_t * pOutTau,
float32_t *pTmpA,
float32_t *pTmpB
);
/**
@brief QR decomposition of a m x n floating point matrix with m >= n.
@param[in] pSrc points to input matrix structure. The source matrix is modified by the function.
@param[in] threshold norm2 threshold.
@param[out] pOutR points to output R matrix structure of dimension m x n
@param[out] pOutQ points to output Q matrix structure of dimension m x m
@param[out] pOutTau points to Householder scaling factors of dimension n
@param[inout] pTmpA points to a temporary vector of dimension m.
@param[inout] pTmpB points to a temporary vector of dimension n.
@return execution status
- \ref ARM_MATH_SUCCESS : Operation successful
- \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed
- \ref ARM_MATH_SINGULAR : Input matrix is found to be singular (non-invertible)
*/
arm_status arm_mat_qr_f64(
const arm_matrix_instance_f64 * pSrc,
const float64_t threshold,
arm_matrix_instance_f64 * pOutR,
arm_matrix_instance_f64 * pOutQ,
float64_t * pOutTau,
float64_t *pTmpA,
float64_t *pTmpB
);
/**
@brief Householder transform of a floating point vector.
@param[in] pSrc points to the input vector.
@param[in] threshold norm2 threshold.
@param[in] blockSize dimension of the vector space.
@param[outQ] pOut points to the output vector.
@return beta return the scaling factor beta
*/
float32_t arm_householder_f32(
const float32_t * pSrc,
const float32_t threshold,
uint32_t blockSize,
float32_t * pOut
);
/**
@brief Householder transform of a double floating point vector.
@param[in] pSrc points to the input vector.
@param[in] threshold norm2 threshold.
@param[in] blockSize dimension of the vector space.
@param[outQ] pOut points to the output vector.
@return beta return the scaling factor beta
*/
float64_t arm_householder_f64(
const float64_t * pSrc,
const float64_t threshold,
uint32_t blockSize,
float64_t * pOut
);
#ifdef __cplusplus
}
#endif

@ -41,6 +41,8 @@ extern "C"
#if defined(ARM_FLOAT16_SUPPORTED)
#define DEFAULT_HOUSEHOLDER_THRESHOLD_F16 (1.0e-3f)
/**
* @brief Instance structure for the floating-point matrix structure.
*/
@ -212,6 +214,46 @@ void arm_mat_init_f16(
arm_matrix_instance_f16 * dst);
/**
@brief QR decomposition of a m x n floating point matrix with m >= n.
@param[in] pSrc points to input matrix structure. The source matrix is modified by the function.
@param[in] threshold norm2 threshold.
@param[out] pOutR points to output R matrix structure of dimension m x n
@param[out] pOutQ points to output Q matrix structure of dimension m x m
@param[out] pOutTau points to Householder scaling factors of dimension n
@param[inout] pTmpA points to a temporary vector of dimension m.
@param[inout] pTmpB points to a temporary vector of dimension n.
@return execution status
- \ref ARM_MATH_SUCCESS : Operation successful
- \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed
- \ref ARM_MATH_SINGULAR : Input matrix is found to be singular (non-invertible)
*/
arm_status arm_mat_qr_f16(
const arm_matrix_instance_f16 * pSrc,
const float16_t threshold,
arm_matrix_instance_f16 * pOutR,
arm_matrix_instance_f16 * pOutQ,
float16_t * pOutTau,
float16_t *pTmpA,
float16_t *pTmpB
);
/**
@brief Householder transform of a half floating point vector.
@param[in] pSrc points to the input vector.
@param[in] threshold norm2 threshold.
@param[in] blockSize dimension of the vector space.
@param[outQ] pOut points to the output vector.
@return beta return the scaling factor beta
*/
float16_t arm_householder_f16(
const float16_t * pSrc,
const float16_t threshold,
uint32_t blockSize,
float16_t * pOut
);
#endif /*defined(ARM_FLOAT16_SUPPORTED)*/
#ifdef __cplusplus

@ -56,6 +56,18 @@ extern "C"
} \
}
#define COPY_COL_T(T,A,ROW,COL,DST) \
{ \
uint32_t row; \
T *pb=DST; \
T *pa = (A)->pData + ROW * (A)->numCols + COL;\
for(row = ROW; row < (A)->numRows; row ++) \
{ \
*pb++ = *pa; \
pa += (A)->numCols; \
} \
}
#if defined(ARM_FLOAT16_SUPPORTED)
#if defined(ARM_MATH_MVE_FLOAT16) && !defined(ARM_MATH_AUTOVECTORIZE)
@ -145,6 +157,7 @@ extern "C"
#else
#define SWAP_ROWS_F16(A,COL,i,j) \
{ \
int32_t w; \
@ -217,6 +230,9 @@ extern "C"
#endif /*defined(ARM_MATH_MVE_FLOAT16) && !defined(ARM_MATH_AUTOVECTORIZE)*/
/* Functions with only a scalar version */
#define COPY_COL_F16(A,ROW,COL,DST) \
COPY_COL_T(float16_t,A,ROW,COL,DST)
#define SCALE_COL_F16(A,ROW,v,i) \
SCALE_COL_T(float16_t,(_Float16),A,ROW,v,i)
@ -505,6 +521,15 @@ extern "C"
#endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
/* Functions with only a scalar version */
#define COPY_COL_F32(A,ROW,COL,DST) \
COPY_COL_T(float32_t,A,ROW,COL,DST)
#define COPY_COL_F64(A,ROW,COL,DST) \
COPY_COL_T(float64_t,A,ROW,COL,DST)
#define SWAP_COLS_F32(A,COL,i,j) \
{ \
int32_t w; \

File diff suppressed because it is too large Load Diff

@ -179,83 +179,77 @@ Method_##NAME##_##FIELD(dsp_##NAME##Object *self, PyObject *ignored)\
void capsule_cleanup(PyObject *capsule) {
void *memory = PyCapsule_GetPointer(capsule, "cmsisdsp capsule");
// I'm going to assume your memory needs to be freed with free().
// If it needs different cleanup, perform whatever that cleanup is
// instead of calling free().
PyMem_Free(memory);
}
#define FLOATARRAY2(OBJ,NB1,NB2,DATA) \
npy_intp dims[2]; \
dims[0]=NB1; \
dims[1]=NB2; \
const int ND=2; \
PyArrayObject *OBJ=(PyArrayObject*)PyArray_SimpleNewFromData(ND, dims, NPY_FLOAT, DATA);\
PyObject *capsule = PyCapsule_New(DATA, "cmsisdsp capsule",capsule_cleanup); \
PyArray_SetBaseObject(OBJ, capsule);
npy_intp dims##OBJ[2]; \
dims##OBJ[0]=NB1; \
dims##OBJ[1]=NB2; \
const int ND##OBJ=2; \
PyArrayObject *OBJ=(PyArrayObject*)PyArray_SimpleNewFromData(ND##OBJ, dims##OBJ, NPY_FLOAT, DATA);\
PyObject *capsule##OBJ = PyCapsule_New(DATA, "cmsisdsp capsule",capsule_cleanup); \
PyArray_SetBaseObject(OBJ, capsule##OBJ);
#define FLOATARRAY1(OBJ,NB1,DATA) \
npy_intp dims##OBJ[1]; \
dims##OBJ[0]=NB1; \
const int ND##OBJ=1; \
PyArrayObject *OBJ=(PyArrayObject*)PyArray_SimpleNewFromData(ND##OBJ, dims##OBJ, NPY_FLOAT, DATA);\
PyObject *capsule = PyCapsule_New(DATA, "cmsisdsp capsule",capsule_cleanup); \
PyArray_SetBaseObject(OBJ, capsule);
PyObject *capsule##OBJ = PyCapsule_New(DATA, "cmsisdsp capsule",capsule_cleanup); \
PyArray_SetBaseObject(OBJ, capsule##OBJ);
#define FLOAT64ARRAY1(OBJ,NB1,DATA) \
npy_intp dims[1]; \
dims[0]=NB1; \
const int ND=1; \
PyArrayObject *OBJ=(PyArrayObject*)PyArray_SimpleNewFromData(ND, dims, NPY_DOUBLE, DATA);\
PyObject *capsule = PyCapsule_New(DATA, "cmsisdsp capsule",capsule_cleanup); \
PyArray_SetBaseObject(OBJ, capsule);
npy_intp dims##OBJ[1]; \
dims##OBJ[0]=NB1; \
const int ND##OBJ=1; \
PyArrayObject *OBJ=(PyArrayObject*)PyArray_SimpleNewFromData(ND##OBJ, dims##OBJ, NPY_DOUBLE, DATA);\
PyObject *capsule##OBJ = PyCapsule_New(DATA, "cmsisdsp capsule",capsule_cleanup); \
PyArray_SetBaseObject(OBJ, capsule##OBJ);
#define UINT32ARRAY1(OBJ,NB1,DATA) \
npy_intp dims[1]; \
dims[0]=NB1; \
const int ND=1; \
PyArrayObject *OBJ=(PyArrayObject*)PyArray_SimpleNewFromData(ND, dims, NPY_UINT32, DATA);\
PyObject *capsule = PyCapsule_New(DATA, "cmsisdsp capsule",capsule_cleanup); \
PyArray_SetBaseObject(OBJ, capsule);
npy_intp dims##OBJ[1]; \
dims##OBJ[0]=NB1; \
const int ND##OBJ=1; \
PyArrayObject *OBJ=(PyArrayObject*)PyArray_SimpleNewFromData(ND##OBJ, dims##OBJ, NPY_UINT32, DATA);\
PyObject *capsule##OBJ = PyCapsule_New(DATA, "cmsisdsp capsule",capsule_cleanup); \
PyArray_SetBaseObject(OBJ, capsule##OBJ);
#define INT32ARRAY1(OBJ,NB1,DATA) \
npy_intp dims[1]; \
dims[0]=NB1; \
const int ND=1; \
PyArrayObject *OBJ=(PyArrayObject*)PyArray_SimpleNewFromData(ND, dims, NPY_INT32, DATA);\
PyObject *capsule = PyCapsule_New(DATA, "cmsisdsp capsule",capsule_cleanup); \
PyArray_SetBaseObject(OBJ, capsule);
npy_intp dims##OBJ[1]; \
dims##OBJ[0]=NB1; \
const int ND##OBJ=1; \
PyArrayObject *OBJ=(PyArrayObject*)PyArray_SimpleNewFromData(ND##OBJ, dims##OBJ, NPY_INT32, DATA);\
PyObject *capsule##OBJ = PyCapsule_New(DATA, "cmsisdsp capsule",capsule_cleanup); \
PyArray_SetBaseObject(OBJ, capsule##OBJ);
#define INT16ARRAY1(OBJ,NB1,DATA) \
npy_intp dims[1]; \
dims[0]=NB1; \
const int ND=1; \
PyArrayObject *OBJ=(PyArrayObject*)PyArray_SimpleNewFromData(ND, dims, NPY_INT16, DATA);\
PyObject *capsule = PyCapsule_New(DATA, "cmsisdsp capsule",capsule_cleanup); \
PyArray_SetBaseObject(OBJ, capsule);
npy_intp dims##OBJ[1]; \
dims##OBJ[0]=NB1; \
const int ND##OBJ=1; \
PyArrayObject *OBJ=(PyArrayObject*)PyArray_SimpleNewFromData(ND##OBJ, dims##OBJ, NPY_INT16, DATA);\
PyObject *capsule##OBJ = PyCapsule_New(DATA, "cmsisdsp capsule",capsule_cleanup); \
PyArray_SetBaseObject(OBJ, capsule##OBJ);
#define INT8ARRAY1(OBJ,NB1,DATA) \
npy_intp dims[1]; \
dims[0]=NB1; \
const int ND=1; \
PyArrayObject *OBJ=(PyArrayObject*)PyArray_SimpleNewFromData(ND, dims, NPY_BYTE, DATA);\
PyObject *capsule = PyCapsule_New(DATA, "cmsisdsp capsule",capsule_cleanup); \
PyArray_SetBaseObject(OBJ, capsule);
npy_intp dims##OBJ[1]; \
dims##OBJ[0]=NB1; \
const int ND##OBJ=1; \
PyArrayObject *OBJ=(PyArrayObject*)PyArray_SimpleNewFromData(ND##OBJ, dims##OBJ, NPY_BYTE, DATA);\
PyObject *capsule##OBJ = PyCapsule_New(DATA, "cmsisdsp capsule",capsule_cleanup); \
PyArray_SetBaseObject(OBJ, capsule##OBJ);
#define TYP_ARRAY1(OBJ,NB1,DATA,NPYTYPE) \
npy_intp dims[1]; \
dims[0]=NB1; \
const int ND=1; \
PyArrayObject *OBJ=(PyArrayObject*)PyArray_SimpleNewFromData(ND, dims, NPYTYPE, DATA);\
PyObject *capsule = PyCapsule_New(DATA, "cmsisdsp capsule",capsule_cleanup); \
PyArray_SetBaseObject(OBJ, capsule);
npy_intp dims##OBJ[1]; \
dims##OBJ[0]=NB1; \
const int ND##OBJ=1; \
PyArrayObject *OBJ=(PyArrayObject*)PyArray_SimpleNewFromData(ND##OBJ, dims##OBJ, NPYTYPE, DATA);\
PyObject *capsule##OBJ = PyCapsule_New(DATA, "cmsisdsp capsule",capsule_cleanup); \
PyArray_SetBaseObject(OBJ, capsule##OBJ);
#define MATRIXFROMNUMPY(EXT,TYP,SRCTYPE,NUMPYTYPE) \
arm_matrix_instance_##EXT *EXT##MatrixFromNumpy(PyObject *o) \
void EXT##MatrixFromNumpy(arm_matrix_instance_##EXT *s,PyObject *o) \
{ \
arm_matrix_instance_##EXT *s; \
\
s=PyMem_Malloc(sizeof(arm_matrix_instance_##EXT)); \
s->pData=NULL; \
s->numRows=0; \
s->numCols=0; \
@ -277,25 +271,21 @@ arm_matrix_instance_##EXT *EXT##MatrixFromNumpy(PyObject *o) \
} \
\
\
return(s); \
\
}
#define CREATEMATRIX(EXT,TYP) \
arm_matrix_instance_##EXT *create##EXT##Matrix(uint32_t r,uint32_t c)\
void create##EXT##Matrix(arm_matrix_instance_##EXT *s,uint32_t r,uint32_t c)\
{ \
arm_matrix_instance_##EXT *s; \
\
s=PyMem_Malloc(sizeof(arm_matrix_instance_##EXT)); \
s->pData=PyMem_Malloc(sizeof(TYP)*r*c); \
s->numRows=r; \
s->numCols=c; \
return(s); \
}
#define FREEMATRIX(s) PyMem_Free((s)->pData)
#define NUMPYVECTORFROMBUFFER(EXT,CTYPE,NUMPYTYPE_FROMC) \
PyObject *NumpyVectorFrom##EXT##Buffer(CTYPE *ptr,int nb) \

@ -934,7 +934,7 @@ cmsis_arm_weighted_sum_f32(PyObject *obj, PyObject *args)
}
static PyObject *
cmsis_arm_div_q63_to_q31(PyObject *obj, PyObject *args)
cmsis_arm_div_int64_to_int32(PyObject *obj, PyObject *args)
{
PyObject *pSrc=NULL; // input
@ -946,7 +946,7 @@ cmsis_arm_div_q63_to_q31(PyObject *obj, PyObject *args)
{
result=arm_div_q63_to_q31(num,den);
result=arm_div_int64_to_int32(num,den);
PyObject* resultOBJ=Py_BuildValue("l",result);
@ -962,7 +962,7 @@ cmsis_arm_div_q63_to_q31(PyObject *obj, PyObject *args)
static PyMethodDef CMSISDSPMethods[] = {
{"arm_div_q63_to_q31", cmsis_arm_div_q63_to_q31, METH_VARARGS,""},
{"arm_div_int64_to_int32", cmsis_arm_div_int64_to_int32, METH_VARARGS,""},
{"arm_copy_f64", cmsis_arm_copy_f64, METH_VARARGS,""},
{"arm_copy_f32", cmsis_arm_copy_f32, METH_VARARGS,""},
{"arm_copy_q7", cmsis_arm_copy_q7, METH_VARARGS,""},

@ -31,7 +31,7 @@ y = np.sin(angles)
vals=list(zip(y,x))
printSubTitle("Atan2 Referebce")
printSubTitle("Atan2 Reference")
ref=np.array([np.arctan2(yv,xv) for (yv,xv) in vals])/math.pi*180
print(ref)

@ -0,0 +1,158 @@
# New functions for version 1.5 of the Python wrapper
import cmsisdsp as dsp
import cmsisdsp.fixedpoint as f
import numpy as np
import math
import colorama
from colorama import init,Fore, Back, Style
from numpy.linalg import qr
def householder(x,eps=1e-16):
#print(x)
v=np.hstack([[1],x[1:]])
alpha = x[0]
xnorm2=x[1:].dot(x[1:])
epsilon=eps
#print(sigma)
if xnorm2<=epsilon:
tau = 0.0
v = np.zeros(len(x))
else:
if np.sign(alpha) <= 0:
beta = math.sqrt(alpha*alpha + xnorm2)
else:
beta = -math.sqrt(alpha*alpha + xnorm2)
r = (alpha - beta)
v = x / r
tau = (beta - alpha) / beta
v[0] = 1
return(v,tau)
init()
def printTitle(s):
print("\n" + Fore.GREEN + Style.BRIGHT + s + Style.RESET_ALL)
def printSubTitle(s):
print("\n" + Style.BRIGHT + s + Style.RESET_ALL)
printTitle("Householder")
VECDIM = 10
a=np.random.randn(VECDIM)
a = a / np.max(np.abs(a))
# Reference
vRef,betaRef = householder(a)
printSubTitle("Householder F32")
betaF32,vF32 = dsp.arm_householder_f32(a,dsp.DEFAULT_HOUSEHOLDER_THRESHOLD_F32)
print(np.isclose(betaRef,betaF32,1e-6,1e-6))
print(np.isclose(vRef,vF32,1e-6,1e-6))
printSubTitle("Householder F64")
betaF64,vF64 = dsp.arm_householder_f64(a,dsp.DEFAULT_HOUSEHOLDER_THRESHOLD_F64)
print(np.isclose(betaRef,betaF64,1e-6,1e-6))
print(np.isclose(vRef,vF64,1e-6,1e-6))
printSubTitle("Householder Proportional F32")
a=np.random.randn(5)
# With the threshold defined with DEFAULT_HOUSEHOLDER_THRESHOLD_F32
# this vector is considered as proportional to (1,0,...)
# and thus the function will return (0,[0,...,0])
a = a / np.max(np.abs(a)) * 1.0e-7
resF32 = dsp.arm_householder_f32(a,dsp.DEFAULT_HOUSEHOLDER_THRESHOLD_F32)
print(resF32)
# With a smaller threshold, a computation is taking place
resF32 = dsp.arm_householder_f32(a,0.001*dsp.DEFAULT_HOUSEHOLDER_THRESHOLD_F32)
print(resF32)
printTitle("QR decomposition")
def checkOrtho(A,err=1e-10):
product = A.T.dot(A)
#print(A)
np.fill_diagonal(product,0)
#print(product)
print(np.max(np.abs(product)))
return (np.all(np.abs(product)<=err))
m=np.array([[-0.35564874, -0.07809871, -0.10350569, -0.50633135, -0.65073484],
[-0.71887395, 0.45257918, 0.29606363, 0.1497621 , 0.07002738],
[-0.50586141, -0.50613839, -0.01650463, -0.29693649, 0.47667742],
[ 0.06802137, 0.07689169, -0.02726221, -0.09996672, 0.15521956],
[ 0.21220523, -0.22273009, 0.78247386, -0.2760002 , -0.24438688],
[ 0.09683658, 0.62026597, 0.26771763, -0.26935342, 0.18443573],
[-0.01014268, 0.27578087, -0.44635721, -0.21827312, -0.26463186],
[-0.20420646, -0.12880459, 0.13207738, 0.65319578, -0.3956695 ]])
rows,columns = m.shape
# The CMSIS-DSP C functions is requiring two temporary arrays
# To follow the C function as closely as possible, we create
# two arrays. Their size will be used internally by the Python
# wrapper to allocate two temporary buffers.
# Like that you can check you have dimensionned the arrays in the
# right way.
# The content of the temporary buffers is not accesible from the
# Python API. tmpa and tmpb are not modified.
tmpa=np.zeros(rows)
tmpb=np.zeros(rows)
printSubTitle("QR F32")
status,r,q,tau = dsp.arm_mat_qr_f32(m,dsp.DEFAULT_HOUSEHOLDER_THRESHOLD_F32,tmpa,tmpb)
# Status different from 0 if matrix dimensions are not right
# (rows must be >= columns)
#print(status)
#print(q)
#print(r)
#print(tau)
# Check that the matrix Q is orthogonal
assert(checkOrtho(q,err=1.0e-6))
# Remove householder vectors from R matrix
i=1
for c in r.T:
c[i:] = 0
i = i+1
# Check that M = Q R
newm = np.dot(q,r)
assert_allclose(newm,m,2e-6,1e-7)
printSubTitle("QR F64")
status,r,q,tau = dsp.arm_mat_qr_f64(m,dsp.DEFAULT_HOUSEHOLDER_THRESHOLD_F64,tmpa,tmpb)
# Status different from 0 if matrix dimensions are not right
# (rows must be >= columns)
#print(status)
#print(q)
#print(r)
#print(tau)
# Check that the matrix Q is orthogonal
assert(checkOrtho(q,err=1e-14))
# Remove householder vectors from R matrix
i=1
for c in r.T:
c[i:] = 0
i = i+1
# Check that M = Q R
newm = np.dot(q,r)
assert_allclose(newm,m)

@ -431,12 +431,12 @@ ref = sa
res = dsp.arm_copy_f64(sa)
assert_allclose(ref,res,1e-10,1e-10)
print("arm_div_q63_to_q31")
print("arm_div_int64_to_int32")
den=0x7FFF00000000
num=0x10000
ref=den//num
res=dsp.arm_div_q63_to_q31(den,num)
res=dsp.arm_div_int64_to_int32(den,num)
print(ref)
print(res)

@ -1,17 +1,17 @@
# README
This is a Python wrapper for the Arm open source [CMSIS-DSP](https://arm-software.github.io/CMSIS_5/DSP/html/index.html) and it is compatible with `NumPy`.
This is a Python wrapper for the Arm open source [CMSIS-DSP](https://github.com/ARM-software/CMSIS-DSP) and it is compatible with `NumPy`.
The CMSIS-DSP is available on our [GitHub](https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DSP) or as a CMSIS Pack.
The CMSIS-DSP is available on our [GitHub](https://github.com/ARM-software/CMSIS-DSP) or as a [CMSIS Pack](https://github.com/ARM-software/CMSIS-DSP/releases).
The idea is to follow as closely as possible the C [CMSIS-DSP](https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DSP) API to ease the migration to the final implementation on a board.
The idea is to follow as closely as possible the C [CMSIS-DSP](https://github.com/ARM-software/CMSIS-DSP) API to ease the migration to the final implementation on a board.
The signal processing chain can thus be tested and developed in a Python environment and then easily converted to a C implementation running on a Cortex-M or Cortex-A board.
A tutorial is also available but with less details than this README:
https://developer.arm.com/documentation/102463/latest/
This wrapper is also containing the scripts for the new CMSIS-DSP [Synchronous Data Flow](https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DSP/SDFTools) (SDF) framework.
This wrapper is also containing the scripts for the new CMSIS-DSP [Synchronous Data Flow](https://github.com/ARM-software/CMSIS-DSP/blob/main/SDFTools/README.md) (SDF) framework.
SDF is also including some nodes to communicate with Modelica using the VHT Modelica blocks developed as part of our [VHT-SystemModeling](https://github.com/ARM-software/VHT-SystemModeling) demos.
@ -41,13 +41,13 @@ It is advised to do it in a Python virtual environment. Then, in the virtual env
You must have a recent `pip` (to automatically install the dependencies like `NumPy`) and you should have a compiler which can be found by Python when building the package.
DSP examples are available in the [CMSIS-DSP PythonWrapper examples](https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DSP/PythonWrapper/examples) folder.
DSP examples are available in the [CMSIS-DSP PythonWrapper examples](https://github.com/ARM-software/CMSIS-DSP/tree/main/PythonWrapper/examples) folder.
Synchronous Data Flow examples are available in the [SDF](https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DSP/SDFTools) folder of [CMSIS-DSP](https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DSP) .
Synchronous Data Flow examples are available in the [SDF](https://github.com/ARM-software/CMSIS-DSP/tree/main/SDFTools) folder of [CMSIS-DSP](https://github.com/ARM-software/CMSIS-DSP) .
You can also install and run it from [Google colab](https://colab.research.google.com/):
This [link](https://colab.research.google.com/github/ARM-software/CMSIS_5/blob/develop/CMSIS/DSP/PythonWrapper/examples/cmsisdsp_tests.ipynb) will open a Jupyter notebook in [Google colab](https://colab.research.google.com/) for testing. This notebook is from the [examples](https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DSP/PythonWrapper/examples) in the CMSIS-DSP GitHub repository.
This [link](https://colab.research.google.com/github/ARM-software/CMSIS-DSP/blob/main/PythonWrapper/examples/cmsisdsp_tests.ipynb) will open a Jupyter notebook in [Google colab](https://colab.research.google.com/) for testing. This notebook is from the [examples](https://github.com/ARM-software/CMSIS-DSP/tree/main/PythonWrapper/examples) in the CMSIS-DSP GitHub repository.
### Building
@ -56,11 +56,11 @@ It it is not working (because it is not possible for us to test all configuratio
It is advised to do this it into a virtualenv
Since the [CMSIS-DSP](https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DSP) wrapper is using `NumPy`, you must first install it in the virtual environment.
Since the [CMSIS-DSP](https://github.com/ARM-software/CMSIS-DSP) wrapper is using `NumPy`, you must first install it in the virtual environment.
> pip install numpy
Once `NumPy` is installed, you can build the [CMSIS-DSP](https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DSP) python wrapper. Go to folder `CMSIS/DSP`.
Once `NumPy` is installed, you can build the [CMSIS-DSP](https://github.com/ARM-software/CMSIS-DSP) python wrapper. Go to folder `CMSIS/DSP`.
(In a previous version you had to go to the `PythonWrapper` folder. Now the `setup.py` is inside the DSP folder).
Now, you can install the cmsisdsp package in editable mode:
@ -79,7 +79,7 @@ Install some packages to be able to run the examples
Depending on the example, you may have to install more packages.
The examples are in the [CMSIS-DSP PythonWrapper examples](https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DSP/PythonWrapper/examples) folder.
The examples are in the [CMSIS-DSP PythonWrapper examples](https://github.com/ARM-software/CMSIS-DSP/tree/main/PythonWrapper/examples) folder.
You can test the scripts `testdsp.py` and `example.py` and try to run them from this virtual environment. `example.py` is requiring a data file to be downloaded from the web. See below in this document for the link.
@ -87,7 +87,7 @@ Note that due to the great number of possible configurations (OS, Compiler, Pyth
# Usage
The idea is to follow as closely as possible the [CMSIS-DSP](https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DSP) API to ease the migration to the final implementation on a board.
The idea is to follow as closely as possible the [CMSIS-DSP](https://github.com/ARM-software/CMSIS-DSP) API to ease the migration to the final implementation on a board.
First you need to import the module
@ -103,7 +103,7 @@ If you use scipy signal processing functions:
## Functions with no instance arguments
You can use a [CMSIS-DSP](https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DSP) function with numpy arrays:
You can use a [CMSIS-DSP](https://github.com/ARM-software/CMSIS-DSP) function with numpy arrays:
> r = dsp.arm_add_f32(np.array([1.,2,3]),np.array([4.,5,7]))
@ -111,11 +111,11 @@ The function can also be called more simply with
> r = dsp.arm_add_f32([1.,2,3],[4.,5,7])
The result of a [CMSIS-DSP](https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DSP) function will always be a numpy array whatever the arguments were (numpy array or list).
The result of a [CMSIS-DSP](https://github.com/ARM-software/CMSIS-DSP) function will always be a numpy array whatever the arguments were (numpy array or list).
## Functions with instance arguments
When the [CMSIS-DSP](https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DSP) function is requiring an instance data structure, it is just a bit more complex to use it:
When the [CMSIS-DSP](https://github.com/ARM-software/CMSIS-DSP) function is requiring an instance data structure, it is just a bit more complex to use it:
First you need to create this instance:
@ -125,7 +125,7 @@ Then, you need to call an init function:
> dsp.arm_fir_init_f32(firf32,3,[1.,2,3],[0,0,0,0,0,0,0])
The third argument in this function is the state. Since all arguments (except the instance ones) are read-only in this Python API, this state will never be changed ! It is just used to communicate the length of the state array which must be allocated by the init function. This argument is required because it is present in the [CMSIS-DSP](https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DSP) API and in the final C implementation you'll need to allocate a state array with the right dimension.
The third argument in this function is the state. Since all arguments (except the instance ones) are read-only in this Python API, this state will never be changed ! It is just used to communicate the length of the state array which must be allocated by the init function. This argument is required because it is present in the [CMSIS-DSP](https://github.com/ARM-software/CMSIS-DSP) API and in the final C implementation you'll need to allocate a state array with the right dimension.
Since the goal is to be as close as possible to the C API, the API is forcing the use of this argument.
@ -139,9 +139,9 @@ Then, you can filter with CMSIS-DSP:
> print(dsp.arm_fir_f32(firf32,[1,2,3,4,5]))
The size of this signal should be `blockSize`. `blockSize` was inferred from the size of the state array : `numTaps + blockSize - 1` according to [CMSIS-DSP.](https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DSP) So here the signal must have 5 samples.
The size of this signal should be `blockSize`. `blockSize` was inferred from the size of the state array : `numTaps + blockSize - 1` according to [CMSIS-DSP.](https://github.com/ARM-software/CMSIS-DSP) So here the signal must have 5 samples.
If you want to filter more than 5 samples, then you can just call the function again. The state variable inside firf32 will ensure that it works like in the [CMSIS-DSP](https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DSP) C code.
If you want to filter more than 5 samples, then you can just call the function again. The state variable inside firf32 will ensure that it works like in the [CMSIS-DSP](https://github.com/ARM-software/CMSIS-DSP) C code.
> print(dsp.arm_fir_f32(firf32,[6,7,8,9,10]))
@ -161,7 +161,7 @@ Let's define a signal you will use for the FFT.
> nb = 16
> signal = np.cos(2 * np.pi * np.arange(nb) / nb)
The [CMSIS-DSP](https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DSP) cfft is requiring complex signals with a specific layout in memory.
The [CMSIS-DSP](https://github.com/ARM-software/CMSIS-DSP) cfft is requiring complex signals with a specific layout in memory.
To remain as close as possible to the C API, we are not using complex numbers in the wrapper. So a complex signal must be converted into a real one. The function imToReal1D is defined in testdsp.py
@ -187,9 +187,9 @@ You convert back to a complex format to compare with scipy:
## Matrix
For matrix, the instance variables are masked by the Python API. We decided that for matrix only there was no use for having the [CMSIS-DSP](https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DSP) instance visibles since they contain the same information as the numpy array (samples and dimension).
For matrix, the instance variables are masked by the Python API. We decided that for matrix only there was no use for having the [CMSIS-DSP](https://github.com/ARM-software/CMSIS-DSP) instance visibles since they contain the same information as the numpy array (samples and dimension).
So to use a [CMSIS-DSP](https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DSP) matrix function, it is very simple:
So to use a [CMSIS-DSP](https://github.com/ARM-software/CMSIS-DSP) matrix function, it is very simple:
> a=np.array([[1.,2,3,4],[5,6,7,8],[9,10,11,12]])
> b=np.array([[1.,2,3],[5.1,6,7],[9.1,10,11],[5,8,4]])
@ -198,7 +198,7 @@ So to use a [CMSIS-DSP](https://github.com/ARM-software/CMSIS_5/tree/develop/CMS
> print(np.dot(a , b))
[CMSIS-DSP](https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DSP) result:
[CMSIS-DSP](https://github.com/ARM-software/CMSIS-DSP) result:
> v=dsp.arm_mat_mult_f32(a,b)
> print(v)
@ -224,10 +224,10 @@ Goldberger AL, Amaral LAN, Glass L, Hausdorff JM, Ivanov PCh, Mark RG, Mietus JE
The Python wrapper is containing three submodules : `fixedpoint` , `mfcc` and `datatype`
`fixedpoint` is proving some tools to help generating the fixedpoint values expected
by [CMSIS-DSP](https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DSP).
by [CMSIS-DSP](https://github.com/ARM-software/CMSIS-DSP).
`mfcc` is generating some tools to generate the MEL filters, DCT and window coefficients
expected by the [CMSIS-DSP](https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DSP) MFCC implementation.
expected by the [CMSIS-DSP](https://github.com/ARM-software/CMSIS-DSP) MFCC implementation.
MEL filters are represented as 3 arrays to encode a sparse array.

@ -5,7 +5,6 @@ project(CMSISDSP)
# DSP Sources
SET(DSP ${CMAKE_CURRENT_SOURCE_DIR}/..)
option(NEON "Neon acceleration" OFF)
option(NEONEXPERIMENTAL "Neon experimental acceleration" OFF)
option(HELIUMEXPERIMENTAL "Helium experimental acceleration" OFF)

@ -11,6 +11,8 @@ MatrixFunctions/arm_mat_solve_lower_triangular_f64.c
MatrixFunctions/arm_mat_solve_upper_triangular_f64.c
MatrixFunctions/arm_mat_sub_f64.c
MatrixFunctions/arm_mat_trans_f64.c
MatrixFunctions/arm_mat_qr_f64.c
MatrixFunctions/arm_householder_f64.c
)
set(SRCF32 MatrixFunctions/arm_mat_add_f32.c
@ -27,6 +29,8 @@ MatrixFunctions/arm_mat_solve_upper_triangular_f32.c
MatrixFunctions/arm_mat_sub_f32.c
MatrixFunctions/arm_mat_trans_f32.c
MatrixFunctions/arm_mat_vec_mult_f32.c
MatrixFunctions/arm_mat_qr_f32.c
MatrixFunctions/arm_householder_f32.c
)
set(SRCQ31 MatrixFunctions/arm_mat_add_q31.c
@ -82,6 +86,8 @@ MatrixFunctions/arm_mat_solve_upper_triangular_f16.c
MatrixFunctions/arm_mat_sub_f16.c
MatrixFunctions/arm_mat_trans_f16.c
MatrixFunctions/arm_mat_vec_mult_f16.c
MatrixFunctions/arm_mat_qr_f16.c
MatrixFunctions/arm_householder_f16.c
)
endif()

@ -72,3 +72,7 @@
#include "arm_mat_solve_lower_triangular_f64.c"
#include "arm_mat_ldlt_f32.c"
#include "arm_mat_ldlt_f64.c"
#include "arm_mat_qr_f32.c"
#include "arm_mat_qr_f64.c"
#include "arm_householder_f64.c"
#include "arm_householder_f32.c"

@ -39,3 +39,5 @@
#include "arm_mat_cholesky_f16.c"
#include "arm_mat_solve_upper_triangular_f16.c"
#include "arm_mat_solve_lower_triangular_f16.c"
#include "arm_mat_qr_f16.c"
#include "arm_householder_f32.c"

@ -0,0 +1,116 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_householder_f16.c
* Description: Half floating-point Householder transform
*
* $Date: 15 June 2022
* $Revision: V1.11.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2022 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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.
*/
#include "dsp/matrix_functions_f16.h"
#include "dsp/basic_math_functions_f16.h"
#include "dsp/fast_math_functions_f16.h"
#include "dsp/matrix_utils.h"
#include <math.h>
/**
@ingroup groupMatrix
*/
/**
@addtogroup MatrixHouseholder
@{
*/
/**
@brief Householder transform of a half floating point vector.
@param[in] pSrc points to the input vector.
@param[in] threshold norm2 threshold.
@param[in] blockSize dimension of the vector space.
@param[out] pOut points to the output vector.
@return beta return the scaling factor beta
*/
#if defined(ARM_FLOAT16_SUPPORTED)
float16_t arm_householder_f16(
const float16_t * pSrc,
const float16_t threshold,
uint32_t blockSize,
float16_t * pOut
)
{
uint32_t i;
float16_t epsilon;
float16_t x1norm2,alpha;
float16_t beta,tau,r;
epsilon = threshold;
alpha = pSrc[0];
for(i=1; i < blockSize; i++)
{
pOut[i] = pSrc[i];
}
pOut[0] = 1.0f16;
arm_dot_prod_f16(pSrc+1,pSrc+1,blockSize-1,&x1norm2);
if ((_Float16)x1norm2<=(_Float16)epsilon)
{
tau = 0.0f16;
memset(pOut,0,blockSize * sizeof(float16_t));
}
else
{
beta = (_Float16)alpha * (_Float16)alpha + (_Float16)x1norm2;
(void)arm_sqrt_f16(beta,&beta);
if ((_Float16)alpha > 0.0f16)
{
beta = -(_Float16)beta;
}
r = 1.0f16 / ((_Float16)alpha -(_Float16)beta);
arm_scale_f16(pOut,r,pOut,blockSize);
pOut[0] = 1.0f16;
tau = ((_Float16)beta - (_Float16)alpha) / (_Float16)beta;
}
return(tau);
}
#endif /* #if defined(ARM_FLOAT16_SUPPORTED) */
/**
@} end of MatrixHouseholder group
*/

@ -0,0 +1,188 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_householder_f32.c
* Description: Floating-point Householder transform
*
* $Date: 15 June 2022
* $Revision: V1.11.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2022 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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.
*/
#include "dsp/matrix_functions.h"
#include "dsp/basic_math_functions.h"
#include "dsp/fast_math_functions.h"
#include "dsp/matrix_utils.h"
#include <math.h>
/**
@ingroup groupMatrix
*/
/**
@defgroup MatrixHouseholder Householder transform of a vector
Computes the Householder transform of a vector x.
The Householder transform of x is a vector v with
\f[
v_0 = 1
\f]
and a scalar \f$\beta\f$ such that:
\f[
P = I - \beta v v^T
\f]
is an orthogonal matrix and
\f[
P x = ||x||_2 e_1
\f]
So P is an hyperplane reflection such that the image of x
is proportional to \f$e_1\f$.
\f$e_1\f$ is the vector of coordinates:
\f[
\begin{pmatrix}
1 \\
0 \\
\vdots \\
\end{pmatrix}
\f]
If x is already proportional to \f$e_1\f$ then
the matrix P should be the identity.
Thus, \f$\beta\f$ should be 0 and in this case the vector v
can also be null.
But how do we detect that x is already proportional to
\f$e_1\f$.
If x
\f[
x =
\begin{pmatrix}
x_0 \\
xr \\
\end{pmatrix}
\f]
where \f$xr\f$ is a vector.
The algorithm is computing the norm squared of this vector:
\f[
||xr||^2
\f]
and this value is compared to a `threshold`. If the value
is smaller than the `threshold`, the algorithm is
returning 0 for \f$\beta\f$ and the householder vector.
This `threshold` is an argument of the function.
Default values are provided in the header
`dsp/matrix_functions.h` like for instance
`DEFAULT_HOUSEHOLDER_THRESHOLD_F32`
*/
/**
@addtogroup MatrixHouseholder
@{
*/
/**
@brief Householder transform of a floating point vector.
@param[in] pSrc points to the input vector.
@param[in] threshold norm2 threshold.
@param[in] blockSize dimension of the vector space.
@param[out] pOut points to the output vector.
@return beta return the scaling factor beta
*/
float32_t arm_householder_f32(
const float32_t * pSrc,
const float32_t threshold,
uint32_t blockSize,
float32_t * pOut
)
{
uint32_t i;
float32_t epsilon;
float32_t x1norm2,alpha;
float32_t beta,tau,r;
epsilon = threshold;
alpha = pSrc[0];
for(i=1; i < blockSize; i++)
{
pOut[i] = pSrc[i];
}
pOut[0] = 1.0f;
arm_dot_prod_f32(pSrc+1,pSrc+1,blockSize-1,&x1norm2);
if (x1norm2<=epsilon)
{
tau = 0.0f;
memset(pOut,0,blockSize * sizeof(float32_t));
}
else
{
beta = alpha * alpha + x1norm2;
(void)arm_sqrt_f32(beta,&beta);
if (alpha > 0.0f)
{
beta = -beta;
}
r = 1.0f / (alpha -beta);
arm_scale_f32(pOut,r,pOut,blockSize);
pOut[0] = 1.0f;
tau = (beta - alpha) / beta;
}
return(tau);
}
/**
@} end of MatrixHouseholder group
*/

@ -0,0 +1,113 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_householder_f64.c
* Description: Double floating-point Householder transform
*
* $Date: 15 June 2022
* $Revision: V1.11.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2022 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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.
*/
#include "dsp/matrix_functions.h"
#include "dsp/basic_math_functions.h"
#include "dsp/fast_math_functions.h"
#include "dsp/matrix_utils.h"
#include <math.h>
/**
@ingroup groupMatrix
*/
/**
@addtogroup MatrixHouseholder
@{
*/
/**
@brief Householder transform of a double floating point vector.
@param[in] pSrc points to the input vector.
@param[in] threshold norm2 threshold.
@param[in] blockSize dimension of the vector space.
@param[out] pOut points to the output vector.
@return beta return the scaling factor beta
*/
float64_t arm_householder_f64(
const float64_t * pSrc,
const float64_t threshold,
uint32_t blockSize,
float64_t * pOut
)
{
uint32_t i;
float64_t epsilon;
float64_t x1norm2,alpha;
float64_t beta,tau,r;
epsilon = threshold;
alpha = pSrc[0];
for(i=1; i < blockSize; i++)
{
pOut[i] = pSrc[i];
}
pOut[0] = 1.0;
arm_dot_prod_f64(pSrc+1,pSrc+1,blockSize-1,&x1norm2);
if (x1norm2<=epsilon)
{
tau = 0.0;
memset(pOut,0,blockSize * sizeof(float64_t));
}
else
{
beta = alpha * alpha + x1norm2;
beta=sqrt(beta);
if (alpha > 0.0)
{
beta = -beta;
}
r = 1.0 / (alpha -beta);
arm_scale_f64(pOut,r,pOut,blockSize);
pOut[0] = 1.0;
tau = (beta - alpha) / beta;
}
return(tau);
}
/**
@} end of MatrixHouseholder group
*/

@ -0,0 +1,220 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_mat_qr_f16.c
* Description: Half floating-point matrix QR decomposition.
*
* $Date: 15 June 2022
* $Revision: V1.11.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2022 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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.
*/
#include "dsp/matrix_functions_f16.h"
#include "dsp/matrix_utils.h"
/**
@ingroup groupMatrix
*/
/**
@addtogroup MatrixQR
@{
*/
/**
@brief QR decomposition of a m x n half floating point matrix with m >= n.
@param[in] pSrc points to input matrix structure. The source matrix is modified by the function.
@param[in] threshold norm2 threshold.
@param[out] pOutR points to output R matrix structure of dimension m x n
@param[out] pOutQ points to output Q matrix structure of dimension m x m (can be NULL)
@param[out] pOutTau points to Householder scaling factors of dimension n
@param[inout] pTmpA points to a temporary vector of dimension m.
@param[inout] pTmpB points to a temporary vector of dimension m.
@return execution status
- \ref ARM_MATH_SUCCESS : Operation successful
- \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed
@par pOutQ is optional:
pOutQ can be a NULL pointer.
In this case, the argument will be ignored
and the output Q matrix won't be computed.
@par f16 implementation
The f16 implementation is not very accurate.
@par Norm2 threshold
For the meaning of this argument please
refer to the \ref MatrixHouseholder documentation
*/
#if defined(ARM_FLOAT16_SUPPORTED)
arm_status arm_mat_qr_f16(
const arm_matrix_instance_f16 * pSrc,
const float16_t threshold,
arm_matrix_instance_f16 * pOutR,
arm_matrix_instance_f16 * pOutQ,
float16_t * pOutTau,
float16_t *pTmpA,
float16_t *pTmpB
)
{
uint32_t col=0;
int32_t nb,pos;
float16_t *pa,*pc;
float16_t beta;
float16_t *pv;
float16_t *pdst;
float16_t *p;
float16_t sum;
if (pSrc->numRows < pSrc->numCols)
{
return(ARM_MATH_SIZE_MISMATCH);
}
memcpy(pOutR->pData,pSrc->pData,pSrc->numCols * pSrc->numRows*sizeof(float16_t));
pOutR->numCols = pSrc->numCols;
pOutR->numRows = pSrc->numRows;
p = pOutR->pData;
pc = pOutTau;
for(col=0 ; col < pSrc->numCols; col++)
{
uint32_t i,j,k;
COPY_COL_F16(pOutR,col,col,pTmpA);
beta = arm_householder_f16(pTmpA,threshold,pSrc->numRows - col,pTmpA);
*pc++ = beta;
pdst = pTmpB;
/* v.T A(col:,col:) -> tmpb */
for(j=0;j<pSrc->numCols-col; j++)
{
pa = p+j;
pv = pTmpA;
sum = 0.0f16;
for(k=0;k<pSrc->numRows-col; k++)
{
sum += (_Float16)*pv++ * (_Float16)*pa;
pa += pOutR->numCols;
}
*pdst++ = sum;
}
/* A(col:,col:) - beta v tmpb */
pa = p;
for(j=0;j<pSrc->numRows-col; j++)
{
for(i=0;i<pSrc->numCols-col; i++)
{
*pa = (_Float16)*pa - (_Float16)beta * (_Float16)pTmpA[j] * (_Float16)pTmpB[i] ;
pa++;
}
pa += col;
}
/* Copy Householder reflectors into R matrix */
pa = p + pOutR->numCols;
for(k=0;k<pSrc->numRows-col-1; k++)
{
*pa = pTmpA[k+1];
pa += pOutR->numCols;
}
p += 1 + pOutR->numCols;
}
/* Generate Q if requested by user matrix */
if (pOutQ != NULL)
{
/* Initialize Q matrix to identity */
memset(pOutQ->pData,0,sizeof(float16_t)*pOutQ->numRows*pOutQ->numRows);
pa = pOutQ->pData;
for(col=0 ; col < pOutQ->numCols; col++)
{
*pa = 1.0f16;
pa += pOutQ->numCols+1;
}
nb = pOutQ->numRows - pOutQ->numCols + 1;
pc = pOutTau + pOutQ->numCols - 1;
for(col=0 ; col < pOutQ->numCols; col++)
{
int32_t i,j,k;
pos = pSrc->numRows - nb;
p = pOutQ->pData + pos + pOutQ->numCols*pos ;
COPY_COL_F16(pOutR,pos,pos,pTmpA);
pTmpA[0] = 1.0f16;
pdst = pTmpB;
/* v.T A(col:,col:) -> tmpb */
for(j=0;j<pOutQ->numRows-pos; j++)
{
pa = p+j;
pv = pTmpA;
sum = 0.0f16;
for(k=0;k<pOutQ->numRows-pos; k++)
{
sum += (_Float16)*pv++ * (_Float16)*pa;
pa += pOutQ->numCols;
}
*pdst++ = sum;
}
pa = p;
beta = *pc--;
for(j=0;j<pOutQ->numRows-pos; j++)
{
for(i=0;i<pOutQ->numCols-pos; i++)
{
*pa = (_Float16)*pa - (_Float16)beta * (_Float16)pTmpA[j] * (_Float16)pTmpB[i] ;
pa++;
}
pa += pos;
}
nb++;
}
}
arm_status status = ARM_MATH_SUCCESS;
/* Return to application */
return (status);
}
#endif /* #if defined(ARM_FLOAT16_SUPPORTED) */
/**
@} end of MatrixQR group
*/

@ -0,0 +1,291 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_mat_qr_f32.c
* Description: Floating-point matrix QR decomposition.
*
* $Date: 15 June 2022
* $Revision: V1.11.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2022 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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.
*/
#include "dsp/matrix_functions.h"
#include "dsp/matrix_utils.h"
/**
@ingroup groupMatrix
*/
/**
@defgroup MatrixQR QR decomposition of a Matrix
Computes the QR decomposition of a matrix M using Householder algorithm.
\f[
M = Q R
\f]
where Q is an orthogonal matrix and R is upper triangular.
No pivoting strategy is used.
The returned value for R is using a format a bit similar
to LAPACK : it is not just containing the matrix R but
also the Householder reflectors.
The function is also returning a vector \f$\tau\f$
that is containing the scaling factor for the reflectors.
Returned value R has the structure:
\f[
\begin{pmatrix}
r_{11} & r_{12} & \dots & r_{1n} \\
v_{12} & r_{22} & \dots & r_{2n} \\
v_{13} & v_{22} & \dots & r_{3n} \\
\vdots & \vdots & \ddots & \vdots \\
v_{1m} & v_{2(m-1)} & \dots & r_{mn} \\
\end{pmatrix}
\f]
where
\f[
v_1 =
\begin{pmatrix}
1 \\
v_{12} \\
\vdots \\
v_{1m} \\
\end{pmatrix}
\f]
is the first householder reflector.
The Householder Matrix is given by \f$H_1\f$
\f[
H_1 = I - \tau_1 v_1 v_1^T
\f]
The Matrix Q is the product of the Householder matrices:
\f[
Q = H_1 H_2 \dots H_n
\f]
The computation of the matrix Q by this function is
optional.
And the matrix R, would be the returned value R without the
householder reflectors:
\f[
\begin{pmatrix}
r_{11} & r_{12} & \dots & r_{1n} \\
0 & r_{22} & \dots & r_{2n} \\
0 & 0 & \dots & r_{3n} \\
\vdots & \vdots & \ddots & \vdots \\
0 & 0 & \dots & r_{mn} \\
\end{pmatrix}
\f]
*/
/**
@addtogroup MatrixQR
@{
*/
/**
@brief QR decomposition of a m x n floating point matrix with m >= n.
@param[in] pSrc points to input matrix structure. The source matrix is modified by the function.
@param[in] threshold norm2 threshold.
@param[out] pOutR points to output R matrix structure of dimension m x n
@param[out] pOutQ points to output Q matrix structure of dimension m x m (can be NULL)
@param[out] pOutTau points to Householder scaling factors of dimension n
@param[inout] pTmpA points to a temporary vector of dimension m.
@param[inout] pTmpB points to a temporary vector of dimension m.
@return execution status
- \ref ARM_MATH_SUCCESS : Operation successful
- \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed
@par pOutQ is optional:
pOutQ can be a NULL pointer.
In this case, the argument will be ignored
and the output Q matrix won't be computed.
@par Norm2 threshold
For the meaning of this argument please
refer to the \ref MatrixHouseholder documentation
*/
arm_status arm_mat_qr_f32(
const arm_matrix_instance_f32 * pSrc,
const float32_t threshold,
arm_matrix_instance_f32 * pOutR,
arm_matrix_instance_f32 * pOutQ,
float32_t * pOutTau,
float32_t *pTmpA,
float32_t *pTmpB
)
{
uint32_t col=0;
int32_t nb,pos;
float32_t *pa,*pc;
float32_t beta;
float32_t *pv;
float32_t *pdst;
float32_t *p;
float32_t sum;
if (pSrc->numRows < pSrc->numCols)
{
return(ARM_MATH_SIZE_MISMATCH);
}
memcpy(pOutR->pData,pSrc->pData,pSrc->numCols * pSrc->numRows*sizeof(float32_t));
pOutR->numCols = pSrc->numCols;
pOutR->numRows = pSrc->numRows;
p = pOutR->pData;
pc = pOutTau;
for(col=0 ; col < pSrc->numCols; col++)
{
uint32_t i,j,k;
COPY_COL_F32(pOutR,col,col,pTmpA);
beta = arm_householder_f32(pTmpA,threshold,pSrc->numRows - col,pTmpA);
*pc++ = beta;
pdst = pTmpB;
/* v.T A(col:,col:) -> tmpb */
for(j=0;j<pSrc->numCols-col; j++)
{
pa = p+j;
pv = pTmpA;
sum = 0.0f;
for(k=0;k<pSrc->numRows-col; k++)
{
sum += *pv++ * *pa;
pa += pOutR->numCols;
}
*pdst++ = sum;
}
/* A(col:,col:) - beta v tmpb */
pa = p;
for(j=0;j<pSrc->numRows-col; j++)
{
for(i=0;i<pSrc->numCols-col; i++)
{
*pa = *pa - beta * pTmpA[j] * pTmpB[i] ;
pa++;
}
pa += col;
}
/* Copy Householder reflectors into R matrix */
pa = p + pOutR->numCols;
for(k=0;k<pSrc->numRows-col-1; k++)
{
*pa = pTmpA[k+1];
pa += pOutR->numCols;
}
p += 1 + pOutR->numCols;
}
/* Generate Q if requested by user matrix */
if (pOutQ != NULL)
{
/* Initialize Q matrix to identity */
memset(pOutQ->pData,0,sizeof(float32_t)*pOutQ->numRows*pOutQ->numRows);
pa = pOutQ->pData;
for(col=0 ; col < pOutQ->numCols; col++)
{
*pa = 1.0f;
pa += pOutQ->numCols+1;
}
nb = pOutQ->numRows - pOutQ->numCols + 1;
pc = pOutTau + pOutQ->numCols - 1;
for(col=0 ; col < pOutQ->numCols; col++)
{
int32_t i,j,k;
pos = pSrc->numRows - nb;
p = pOutQ->pData + pos + pOutQ->numCols*pos ;
COPY_COL_F32(pOutR,pos,pos,pTmpA);
pTmpA[0] = 1.0f;
pdst = pTmpB;
/* v.T A(col:,col:) -> tmpb */
for(j=0;j<pOutQ->numRows-pos; j++)
{
pa = p+j;
pv = pTmpA;
sum = 0.0f;
for(k=0;k<pOutQ->numRows-pos; k++)
{
sum += *pv++ * *pa;
pa += pOutQ->numCols;
}
*pdst++ = sum;
}
pa = p;
beta = *pc--;
for(j=0;j<pOutQ->numRows-pos; j++)
{
for(i=0;i<pOutQ->numCols-pos; i++)
{
*pa = *pa - beta * pTmpA[j] * pTmpB[i] ;
pa++;
}
pa += pos;
}
nb++;
}
}
arm_status status = ARM_MATH_SUCCESS;
/* Return to application */
return (status);
}
/**
@} end of MatrixQR group
*/

@ -0,0 +1,216 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_mat_qr_f64.c
* Description: Double floating-point matrix QR decomposition.
*
* $Date: 15 June 2022
* $Revision: V1.11.0
*
* Target Processor: Cortex-M and Cortex-A cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2022 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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.
*/
#include "dsp/matrix_functions.h"
#include "dsp/matrix_utils.h"
/**
@ingroup groupMatrix
*/
/**
@addtogroup MatrixQR
@{
*/
/**
@brief QR decomposition of a m x n double floating point matrix with m >= n.
@param[in] pSrc points to input matrix structure. The source matrix is modified by the function.
@param[in] threshold norm2 threshold.
@param[out] pOutR points to output R matrix structure of dimension m x n
@param[out] pOutQ points to output Q matrix structure of dimension m x m (can be NULL)
@param[out] pOutTau points to Householder scaling factors of dimension n
@param[inout] pTmpA points to a temporary vector of dimension m.
@param[inout] pTmpB points to a temporary vector of dimension m.
@return execution status
- \ref ARM_MATH_SUCCESS : Operation successful
- \ref ARM_MATH_SIZE_MISMATCH : Matrix size check failed
@par pOutQ is optional:
pOutQ can be a NULL pointer.
In this case, the argument will be ignored
and the output Q matrix won't be computed.
@par Norm2 threshold
For the meaning of this argument please
refer to the \ref MatrixHouseholder documentation
*/
arm_status arm_mat_qr_f64(
const arm_matrix_instance_f64 * pSrc,
const float64_t threshold,
arm_matrix_instance_f64 * pOutR,
arm_matrix_instance_f64 * pOutQ,
float64_t * pOutTau,
float64_t *pTmpA,
float64_t *pTmpB
)
{
uint32_t col=0;
int32_t nb,pos;
float64_t *pa,*pc;
float64_t beta;
float64_t *pv;
float64_t *pdst;
float64_t *p;
float64_t sum;
if (pSrc->numRows < pSrc->numCols)
{
return(ARM_MATH_SIZE_MISMATCH);
}
memcpy(pOutR->pData,pSrc->pData,pSrc->numCols * pSrc->numRows*sizeof(float64_t));
pOutR->numCols = pSrc->numCols;
pOutR->numRows = pSrc->numRows;
p = pOutR->pData;
pc = pOutTau;
for(col=0 ; col < pSrc->numCols; col++)
{
uint32_t i,j,k;
COPY_COL_F64(pOutR,col,col,pTmpA);
beta = arm_householder_f64(pTmpA,threshold,pSrc->numRows - col,pTmpA);
*pc++ = beta;
pdst = pTmpB;
/* v.T A(col:,col:) -> tmpb */
for(j=0;j<pSrc->numCols-col; j++)
{
pa = p+j;
pv = pTmpA;
sum = 0.0;
for(k=0;k<pSrc->numRows-col; k++)
{
sum += *pv++ * *pa;
pa += pOutR->numCols;
}
*pdst++ = sum;
}
/* A(col:,col:) - beta v tmpb */
pa = p;
for(j=0;j<pSrc->numRows-col; j++)
{
for(i=0;i<pSrc->numCols-col; i++)
{
*pa = *pa - beta * pTmpA[j] * pTmpB[i] ;
pa++;
}
pa += col;
}
/* Copy Householder reflectors into R matrix */
pa = p + pOutR->numCols;
for(k=0;k<pSrc->numRows-col-1; k++)
{
*pa = pTmpA[k+1];
pa += pOutR->numCols;
}
p += 1 + pOutR->numCols;
}
/* Generate Q if requested by user matrix */
if (pOutQ != NULL)
{
/* Initialize Q matrix to identity */
memset(pOutQ->pData,0,sizeof(float64_t)*pOutQ->numRows*pOutQ->numRows);
pa = pOutQ->pData;
for(col=0 ; col < pOutQ->numCols; col++)
{
*pa = 1.0;
pa += pOutQ->numCols+1;
}
nb = pOutQ->numRows - pOutQ->numCols + 1;
pc = pOutTau + pOutQ->numCols - 1;
for(col=0 ; col < pOutQ->numCols; col++)
{
int32_t i,j,k;
pos = pSrc->numRows - nb;
p = pOutQ->pData + pos + pOutQ->numCols*pos ;
COPY_COL_F64(pOutR,pos,pos,pTmpA);
pTmpA[0] = 1.0;
pdst = pTmpB;
/* v.T A(col:,col:) -> tmpb */
for(j=0;j<pOutQ->numRows-pos; j++)
{
pa = p+j;
pv = pTmpA;
sum = 0.0;
for(k=0;k<pOutQ->numRows-pos; k++)
{
sum += *pv++ * *pa;
pa += pOutQ->numCols;
}
*pdst++ = sum;
}
pa = p;
beta = *pc--;
for(j=0;j<pOutQ->numRows-pos; j++)
{
for(i=0;i<pOutQ->numCols-pos; i++)
{
*pa = *pa - beta * pTmpA[j] * pTmpB[i] ;
pa++;
}
pa += pos;
}
nb++;
}
}
arm_status status = ARM_MATH_SUCCESS;
/* Return to application */
return (status);
}
/**
@} end of MatrixQR group
*/

@ -14,14 +14,26 @@ class UnaryTestsF16:public Client::Suite
Client::Pattern<float16_t> input1;
Client::Pattern<float16_t> input2;
Client::Pattern<float16_t> ref;
Client::Pattern<float16_t> refBeta;
Client::Pattern<float16_t> refTau;
Client::Pattern<float16_t> refR;
Client::Pattern<float16_t> refQ;
Client::Pattern<int16_t> dims;
Client::LocalPattern<float16_t> output;
Client::LocalPattern<float16_t> outputBeta;
Client::LocalPattern<float16_t> outputTau;
Client::LocalPattern<float16_t> outputR;
Client::LocalPattern<float16_t> outputQ;
/* Local copies of inputs since matrix instance in CMSIS-DSP are not using
pointers to const.
*/
Client::LocalPattern<float16_t> a;
Client::LocalPattern<float16_t> b;
Client::LocalPattern<float16_t> c;
Client::LocalPattern<float16_t> d;
int nbr;
int nbc;
@ -29,4 +41,6 @@ class UnaryTestsF16:public Client::Suite
arm_matrix_instance_f16 in1;
arm_matrix_instance_f16 in2;
arm_matrix_instance_f16 out;
arm_matrix_instance_f16 outQ;
arm_matrix_instance_f16 outR;
};

@ -17,13 +17,23 @@ class UnaryTestsF32:public Client::Suite
Client::Pattern<float32_t> input1;
Client::Pattern<float32_t> input2;
Client::Pattern<float32_t> ref;
Client::Pattern<float32_t> refBeta;
Client::Pattern<float32_t> refll;
Client::Pattern<float32_t> refd;
Client::Pattern<int16_t> refp;
Client::Pattern<float32_t> refTau;
Client::Pattern<float32_t> refR;
Client::Pattern<float32_t> refQ;
Client::Pattern<int16_t> dims;
Client::LocalPattern<float32_t> output;
Client::LocalPattern<float32_t> outputBeta;
Client::LocalPattern<float32_t> outputTau;
Client::LocalPattern<float32_t> outputR;
Client::LocalPattern<float32_t> outputQ;
Client::LocalPattern<float32_t> outputll;
Client::LocalPattern<float32_t> outputd;
@ -50,6 +60,8 @@ class UnaryTestsF32:public Client::Suite
arm_matrix_instance_f32 in2;
arm_matrix_instance_f32 out;
arm_matrix_instance_f32 outQ;
arm_matrix_instance_f32 outR;
arm_matrix_instance_f32 outll;
arm_matrix_instance_f32 outd;

@ -17,18 +17,28 @@ class UnaryTestsF64:public Client::Suite
Client::Pattern<float64_t> input1;
Client::Pattern<float64_t> input2;
Client::Pattern<float64_t> ref;
Client::Pattern<float64_t> refBeta;
Client::Pattern<float64_t> refll;
Client::Pattern<float64_t> refd;
Client::Pattern<int16_t> refp;
Client::Pattern<float64_t> refTau;
Client::Pattern<float64_t> refR;
Client::Pattern<float64_t> refQ;
Client::Pattern<int16_t> dims;
Client::LocalPattern<float64_t> output;
Client::LocalPattern<float64_t> outputBeta;
Client::LocalPattern<float64_t> outputll;
Client::LocalPattern<float64_t> outputd;
Client::LocalPattern<int16_t> outputp;
Client::LocalPattern<float64_t> outputTau;
Client::LocalPattern<float64_t> outputR;
Client::LocalPattern<float64_t> outputQ;
/* Local copies of inputs since matrix instance in CMSIS-DSP are not using
pointers to const.
*/
@ -52,6 +62,8 @@ class UnaryTestsF64:public Client::Suite
arm_matrix_instance_f64 outll;
arm_matrix_instance_f64 outd;
arm_matrix_instance_f64 outQ;
arm_matrix_instance_f64 outR;
float64_t *outa;
float64_t *outb;

@ -5,6 +5,7 @@ import Tools
import numpy.linalg
import math
import scipy.linalg
import QR
def cartesian(*somelists):
r=[]
@ -685,7 +686,6 @@ def notnull(x):
return(x)
def writeUnaryTests(config,format):
config.setOverwrite(False)
# For benchmarks
NBSAMPLES=NBA*NBB
NBVECSAMPLES = NBB
@ -790,8 +790,7 @@ def writeUnaryTests(config,format):
dims=[1,2,3,4,7,8,9,15,16,17,32,33]
#
if format == Tools.F32 or format == Tools.F16 or format == Tools.F64:
config.setOverwrite(True)
vals = []
inp=[]
@ -812,7 +811,6 @@ def writeUnaryTests(config,format):
config.writeInput(1, inp,"InputInvert")
config.writeReference(1, vals,"RefInvert")
config.setOverwrite(False)
# One kind of matrix shape
# Cholesky and LDLT definite positive (DPO)
@ -916,7 +914,6 @@ def writeUnaryTests(config,format):
config.writeReferenceS16(1, permvals,"RefLDLT_PERM_SDPO")
# Lower and upper triangular
config.setOverwrite(True)
thedims=[]
theltmatrix=[]
theutmatrix=[]
@ -962,10 +959,202 @@ def writeUnaryTests(config,format):
config.writeReference(1, theltinvs,"RefLTSolve")
config.writeReference(1, theutinvs,"RefUTSolve")
config.writeInputS16(1, thedims,"DimsLTSolve")
config.setOverwrite(False)
def okQRConfig(args):
rows,cols,rank=args
maxDim=max(rows,cols)
return((rank<=maxDim) and (rows >= cols))
def testHouseholder(config,format):
sizes=[Tools.loopnb(format,Tools.TAILONLY),
Tools.loopnb(format,Tools.BODYONLY),
Tools.loopnb(format,Tools.BODYANDTAIL)
]
thedims=[]
theInput=[]
theOutputVector=[]
theOutputValue=[]
for s in sizes:
x = np.random.randn(s)
x = Tools.normalize(x)
v,beta=QR.householder(x)
thedims.append(s)
theInput += list(np.array(x).reshape(s))
theOutputVector += list(np.array(v).reshape(s))
theOutputValue.append(beta)
s = 4
x = np.array([1,0,0,0])
v,beta=QR.householder(x)
thedims.append(s)
theInput += list(np.array(x).reshape(s))
theOutputVector += list(np.array(v).reshape(s))
theOutputValue.append(beta)
x = np.array([-1,0,0,0])
v,beta=QR.householder(x)
thedims.append(s)
theInput += list(np.array(x).reshape(s))
theOutputVector += list(np.array(v).reshape(s))
theOutputValue.append(beta)
config.writeInputS16(1, thedims,"DimsHouseholder")
config.writeInput(1, theInput,"InputVectorHouseHolder")
config.writeReference(1, theOutputVector,"RefVectorHouseholder")
config.writeReference(1, theOutputValue,"RefValueHouseholder")
# Check that the matrix is an orthogonal one
def checkOrtho(A):
product = A.T.dot(A)
#print(A)
np.fill_diagonal(product,0)
#print(product)
return (np.all(np.abs(product)<1e-10))
# Check the result of the QR algorithm implemented
# in python.
# We must have M = Q R and Q orthogonal
# In f16, on some mqtrix the accuracy is
# very bad so the test is relaxed a lot
def checkMyQR(m,q,r,format):
# Check that M = QR
# Q is Orthogonal
nm = np.dot(q,r)
rtol = 1e-14
atol = 1e-13
if format == Tools.F16:
rtol = 3e-2
atol = 3e-2
if not (np.allclose(nm,m,rtol=rtol,atol=atol)):
print(np.max(np.abs(nm-m)))
print(np.max(atol + rtol * np.abs(m)))
assert (np.allclose(nm,m,rtol=rtol,atol=atol))
assert (checkOrtho(q))
# Generate patterns for QR decomposition
def testQR(config,format):
eps=1e-16
if format==Tools.F32:
eps=1e-12
if format==Tools.F16:
eps=1.0e-3
thedims=[]
theMatrix=[]
theRefR=[]
theRefQ=[]
theRefTau=[]
sizes=[Tools.loopnb(format,Tools.TAILONLY),
Tools.loopnb(format,Tools.BODYONLY),
Tools.loopnb(format,Tools.BODYANDTAIL)
]
ranks=[1,Tools.loopnb(format,Tools.TAILONLY),
Tools.loopnb(format,Tools.BODYONLY),
Tools.loopnb(format,Tools.BODYANDTAIL)]
allConfigs=cartesian(sizes,sizes,ranks)
allConfigs=list(filter(okQRConfig,allConfigs))
for c in allConfigs:
rows,cols,rank = c
thedims += [rows,cols,rank]
m = QR.randomIsometry(rows,cols,rank)
theMatrix += list(np.array(m).reshape(rows*cols))
#q,r = numpy.linalg.qr(m,mode='complete')
#h,tau = numpy.linalg.qr(m,mode='raw')
q,r,tau,h = QR.QR(m,eps=eps)
# Used to check that the reference Python
# implementation for QR is correct:
checkMyQR(m,q,r,format)
#print(r)
for i in range(cols):
try:
r[i+1:,i] = h[i][1:]
except:
print(h)
print(r)
print(i)
print(r[1:,i])
print(h[i][1:])
raise
#print(m)
#print(h)
#print("")
#print(r)
#print("--------\n\n")
theRefTau += list(np.array(tau).reshape(cols))
theRefR += list(np.array(r).reshape(rows*cols))
theRefQ += list(np.array(q).reshape(rows*rows))
for d in sizes:
m = QR.kahan_matrix(d)
thedims += [d,d,d]
theMatrix += list(np.array(m).reshape(d*d))
#q,r = numpy.linalg.qr(m,mode='complete')
#h,tau = numpy.linalg.qr(m,mode='raw')
q,r,tau,h = QR.QR(m,eps=eps)
# Used to check that the reference Python
# implementation for QR is correct:
checkMyQR(m,q,r,format)
for i in range(d):
try:
r[i+1:,i] = h[i][1:]
except:
print(h)
print(r)
print(i)
raise
theRefTau += list(np.array(tau).reshape(d))
theRefR += list(np.array(r).reshape(d*d))
theRefQ += list(np.array(q).reshape(d*d))
config.writeInputS16(1, thedims,"DimsQR")
config.writeInput(1, theMatrix,"InputMatrixQR")
config.writeReference(1, theRefTau,"RefTau")
config.writeReference(1, theRefR,"RefR")
config.writeReference(1, theRefQ,"RefQ")
def checkHouseholder(h):
v,beta=h
n = len(v)
#print(v)
#print(beta)
v=v[np.newaxis]
p=np.identity(n)-beta * v.T .dot(v)
#print("P")
#print(p)
print(checkOrtho(p))
def generatePatterns():
PATTERNBINDIR = os.path.join("Patterns","DSP","Matrix","Binary","Binary")
PARAMBINDIR = os.path.join("Parameters","DSP","Matrix","Binary","Binary")
@ -984,12 +1173,12 @@ def generatePatterns():
configBinaryq7.setOverwrite(False)
writeBinaryTests(configBinaryf64,Tools.F32)
writeBinaryTests(configBinaryf32,Tools.F32)
writeBinaryTests(configBinaryf16,Tools.F16)
writeBinaryTests(configBinaryq31,Tools.Q31)
writeBinaryTests(configBinaryq15,Tools.Q15)
writeBinaryTests(configBinaryq7,Tools.Q7)
#writeBinaryTests(configBinaryf64,Tools.F32)
#writeBinaryTests(configBinaryf32,Tools.F32)
#writeBinaryTests(configBinaryf16,Tools.F16)
#writeBinaryTests(configBinaryq31,Tools.Q31)
#writeBinaryTests(configBinaryq15,Tools.Q15)
#writeBinaryTests(configBinaryq7,Tools.Q7)
PATTERNUNDIR = os.path.join("Patterns","DSP","Matrix","Unary","Unary")
PARAMUNDIR = os.path.join("Parameters","DSP","Matrix","Unary","Unary")
@ -1008,13 +1197,29 @@ def generatePatterns():
configUnaryq15.setOverwrite(False)
configUnaryq7.setOverwrite(False)
writeUnaryTests(configUnaryf64,Tools.F64)
writeUnaryTests(configUnaryf32,Tools.F32)
writeUnaryTests(configUnaryf16,Tools.F16)
writeUnaryTests(configUnaryq31,Tools.Q31)
writeUnaryTests(configUnaryq31,Tools.Q31)
writeUnaryTests(configUnaryq15,Tools.Q15)
writeUnaryTests(configUnaryq7,Tools.Q7)
#writeUnaryTests(configUnaryf64,Tools.F64)
#writeUnaryTests(configUnaryf32,Tools.F32)
#writeUnaryTests(configUnaryf16,Tools.F16)
#writeUnaryTests(configUnaryq31,Tools.Q31)
#writeUnaryTests(configUnaryq31,Tools.Q31)
#writeUnaryTests(configUnaryq15,Tools.Q15)
#writeUnaryTests(configUnaryq7,Tools.Q7)
#configUnaryf64.setOverwrite(True)
#configUnaryf32.setOverwrite(True)
#configUnaryf16.setOverwrite(True)
testQR(configUnaryf64,Tools.F64)
testQR(configUnaryf32,Tools.F32)
testQR(configUnaryf16,Tools.F16)
#testHouseholder(configUnaryf64,Tools.F32)
#testHouseholder(configUnaryf32,Tools.F32)
#testHouseholder(configUnaryf16,Tools.F32)
if __name__ == '__main__':
generatePatterns()
generatePatterns()

@ -0,0 +1,96 @@
import numpy as np
import Tools
from numpy.linalg import qr
import math
def randomIsometry(rows,cols,rank):
if rank==1:
r=np.random.randn(rows)
r = Tools.normalize(r)[np.newaxis]
c=np.random.randn(cols)
c = Tools.normalize(c)[np.newaxis]
result=r.T.dot(c)
else:
a = np.random.randn(rows,rows)
b = np.random.randn(cols,cols)
diagDim = min(rows,cols)
d = np.zeros((rows,cols))
diag = np.ones(diagDim)
diag[rank:] = 0
np.fill_diagonal(d,diag)
qa,_ = qr(a)
qb,_ = qr(b)
result = qa .dot(d.dot(qb))
return(result)
def kahan_matrix(rows):
cols = rows
eps = np.finfo(np.float32).eps
s = math.pow(eps,1.0/rows)
c = math.sqrt(1-s*s)
m = np.zeros((rows,cols))
sc = 1.0
for i in range(rows-1):
m[i,i] = sc
m[i,i+1:] = - sc * c * np.ones(rows-i-1)
sc = sc * s
m = m + m.T
return(m)
def householder(x,eps=1e-16):
#print(x)
v=np.hstack([[1],x[1:]])
alpha = x[0]
xnorm2=x[1:].dot(x[1:])
epsilon=eps
#print(sigma)
if xnorm2<=epsilon:
tau = 0.0
v = np.zeros(len(x))
else:
if np.sign(alpha) <= 0:
beta = math.sqrt(alpha*alpha + xnorm2)
else:
beta = -math.sqrt(alpha*alpha + xnorm2)
r = (alpha - beta)
v = x / r
tau = (beta - alpha) / beta
v[0] = 1
return(v,tau)
def QR(oldm,eps=1e-16):
m=np.copy(oldm)
(rows,cols) = m.shape
hvects=[]
tau=[]
h=[]
for c in range(cols):
currentSize = rows - c
v,beta=householder(m[c:,c],eps=eps)
tau.append(beta)
h.append(v)
hvects.append((v,beta))
t = np.identity(currentSize) - beta * np.outer(v,v)
m[c:,c:] = np.dot(t,m[c:,c:])
hvects.reverse()
q=np.identity(rows)
c=cols - 1
for (v,beta) in hvects:
t = np.identity(len(v)) - beta * np.outer(v,v)
q[c:,c:] = np.dot(t,q[c:,c:])
c = c - 1
return(q,m,tau,h)

@ -21,7 +21,7 @@ Q7 = 7
def loopnb(format,loopkind):
nb = 0
if loopkind == TAILONLY:
if format == 64 or format == Tools.Q63:
if format == 64 or format == Q63:
nb = 2
if format == 0 or format == 31:
nb = 3
@ -30,7 +30,7 @@ def loopnb(format,loopkind):
if format == 7:
nb = 15
if loopkind == BODYONLY:
if format == 64 or format == Tools.Q63:
if format == 64 or format == Q63:
nb = 4
if format == 0 or format == 31:
nb = 8
@ -39,7 +39,7 @@ def loopnb(format,loopkind):
if format == 7:
nb = 32
if loopkind == BODYANDTAIL:
if format == 64 or format == Tools.Q63:
if format == 64 or format == Q63:
nb = 5
if format == 0 or format == 31:
nb = 11 # 9

@ -0,0 +1,12 @@
H
5
// 3
0x0003
// 8
0x0008
// 11
0x000B
// 4
0x0004
// 4
0x0004

@ -0,0 +1,140 @@
H
69
// 7
0x0007
// 7
0x0007
// 1
0x0001
// 7
0x0007
// 7
0x0007
// 7
0x0007
// 16
0x0010
// 7
0x0007
// 1
0x0001
// 16
0x0010
// 7
0x0007
// 7
0x0007
// 16
0x0010
// 7
0x0007
// 16
0x0010
// 16
0x0010
// 16
0x0010
// 1
0x0001
// 16
0x0010
// 16
0x0010
// 7
0x0007
// 16
0x0010
// 16
0x0010
// 16
0x0010
// 23
0x0017
// 7
0x0007
// 1
0x0001
// 23
0x0017
// 7
0x0007
// 7
0x0007
// 23
0x0017
// 7
0x0007
// 16
0x0010
// 23
0x0017
// 7
0x0007
// 23
0x0017
// 23
0x0017
// 16
0x0010
// 1
0x0001
// 23
0x0017
// 16
0x0010
// 7
0x0007
// 23
0x0017
// 16
0x0010
// 16
0x0010
// 23
0x0017
// 16
0x0010
// 23
0x0017
// 23
0x0017
// 23
0x0017
// 1
0x0001
// 23
0x0017
// 23
0x0017
// 7
0x0007
// 23
0x0017
// 23
0x0017
// 16
0x0010
// 23
0x0017
// 23
0x0017
// 23
0x0017
// 7
0x0007
// 7
0x0007
// 7
0x0007
// 16
0x0010
// 16
0x0010
// 16
0x0010
// 23
0x0017
// 23
0x0017
// 23
0x0017

@ -0,0 +1,62 @@
H
30
// -0.594486
0xb8c2
// 1.000000
0x3c00
// -0.064163
0xac1b
// 0.130639
0x302e
// -0.919507
0xbb5b
// -0.090970
0xadd2
// -0.076884
0xacec
// -0.660239
0xb948
// -1.000000
0xbc00
// -0.256503
0xb41b
// 0.424322
0x36ca
// 1.000000
0x3c00
// -0.126780
0xb00f
// -0.333932
0xb558
// 0.835508
0x3aaf
// 0.208306
0x32aa
// 0.552445
0x386b
// -0.390784
0xb641
// 0.284931
0x348f
// -0.647822
0xb92f
// 0.003365
0x1ae4
// -0.144245
0xb09e
// 1.000000
0x3c00
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// -1.000000
0xbc00
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,628 @@
H
313
// 1.249327
0x3cff
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 1.112908
0x3c74
// 1.553155
0x3e36
// 1.119200
0x3c7a
// 1.334665
0x3d57
// 1.290990
0x3d2a
// 1.946836
0x3fca
// 0.000000
0x0
// 0.000000
0x0
// 1.225877
0x3ce7
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 1.025235
0x3c1a
// 1.072847
0x3c4b
// 1.213933
0x3cdb
// 1.345698
0x3d62
// 1.134086
0x3c89
// 1.183278
0x3cbc
// 1.256702
0x3d07
// 1.330338
0x3d52
// 1.209347
0x3cd6
// 1.130198
0x3c85
// 1.052117
0x3c35
// 1.083331
0x3c55
// 1.195678
0x3cc8
// 1.467501
0x3ddf
// 1.046943
0x3c30
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 1.034435
0x3c23
// 1.183531
0x3cbc
// 1.011484
0x3c0c
// 1.593110
0x3e5f
// 1.221814
0x3ce3
// 1.144500
0x3c94
// 1.203457
0x3cd0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 1.251296
0x3d01
// 1.055783
0x3c39
// 1.112250
0x3c73
// 1.283453
0x3d22
// 1.498130
0x3dfe
// 1.222296
0x3ce4
// 1.020981
0x3c15
// 1.037633
0x3c27
// 1.111454
0x3c72
// 1.744296
0x3efa
// 1.297549
0x3d31
// 1.645750
0x3e95
// 1.548950
0x3e32
// 1.509758
0x3e0a
// 1.243592
0x3cf9
// 0.000000
0x0
// 1.118610
0x3c79
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 1.025233
0x3c1a
// 1.150244
0x3c9a
// 1.158549
0x3ca2
// 1.019778
0x3c14
// 1.105581
0x3c6c
// 1.431515
0x3dba
// 1.141336
0x3c91
// 1.090137
0x3c5c
// 1.176208
0x3cb4
// 1.206416
0x3cd3
// 1.096703
0x3c63
// 1.251746
0x3d02
// 1.345664
0x3d62
// 1.296734
0x3d30
// 1.131105
0x3c86
// 1.026879
0x3c1c
// 1.017602
0x3c12
// 1.021917
0x3c16
// 1.317120
0x3d45
// 1.206884
0x3cd4
// 1.122974
0x3c7e
// 1.249058
0x3cff
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 1.177249
0x3cb6
// 1.064934
0x3c42
// 1.011010
0x3c0b
// 1.069788
0x3c47
// 1.245278
0x3cfb
// 1.253867
0x3d04
// 1.163562
0x3ca7
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 1.162741
0x3ca7
// 1.349632
0x3d66
// 1.261137
0x3d0b
// 1.036746
0x3c26
// 1.420652
0x3daf
// 1.096017
0x3c62
// 1.649897
0x3e99
// 1.172529
0x3cb1
// 1.098015
0x3c64
// 1.237672
0x3cf3
// 1.417870
0x3dac
// 1.127663
0x3c83
// 1.248526
0x3cfe
// 1.465338
0x3ddd
// 1.178838
0x3cb7
// 1.266745
0x3d11
// 1.000708
0x3c01
// 1.499542
0x3e00
// 1.126939
0x3c82
// 1.124582
0x3c80
// 1.193708
0x3cc6
// 1.334483
0x3d57
// 1.158908
0x3ca3
// 1.037520
0x3c26
// 1.063167
0x3c41
// 1.072902
0x3c4b
// 1.303294
0x3d37
// 1.083780
0x3c56
// 1.128771
0x3c84
// 1.275276
0x3d1a
// 1.141808
0x3c91
// 1.468730
0x3de0
// 1.242352
0x3cf8
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 1.205709
0x3cd3
// 1.211553
0x3cd9
// 1.264903
0x3d0f
// 1.117981
0x3c79
// 1.374149
0x3d7f
// 1.238362
0x3cf4
// 0.000000
0x0
// 1.167780
0x3cac
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 1.290960
0x3d2a
// 1.264613
0x3d0f
// 1.042760
0x3c2c
// 1.477949
0x3de9
// 1.066859
0x3c44
// 1.344601
0x3d61
// 1.180526
0x3cb9
// 1.578600
0x3e50
// 1.159727
0x3ca4
// 1.107806
0x3c6e
// 1.252143
0x3d02
// 1.129687
0x3c85
// 1.350558
0x3d67
// 1.145381
0x3c95
// 1.403709
0x3d9d
// 1.084667
0x3c57
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 1.218456
0x3ce0
// 1.054420
0x3c38
// 1.070527
0x3c48
// 1.422463
0x3db1
// 1.327318
0x3d4f
// 1.029304
0x3c1e
// 1.357337
0x3d6e
// 1.136523
0x3c8c
// 1.372240
0x3d7d
// 1.331326
0x3d53
// 1.202783
0x3cd0
// 1.172641
0x3cb1
// 1.025277
0x3c1a
// 1.222731
0x3ce4
// 1.181491
0x3cba
// 1.349769
0x3d66
// 1.208709
0x3cd6
// 1.276445
0x3d1b
// 1.551820
0x3e35
// 1.559367
0x3e3d
// 1.947451
0x3fca
// 1.742805
0x3ef9
// 0.000000
0x0
// 1.634460
0x3e8a
// 1.101045
0x3c67
// 1.520331
0x3e15
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 1.485710
0x3df1
// 1.396417
0x3d96
// 1.166070
0x3caa
// 1.043973
0x3c2d
// 1.004642
0x3c05
// 1.014632
0x3c0f
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 1.441726
0x3dc4
// 1.499710
0x3e00
// 1.391816
0x3d91
// 1.272080
0x3d17
// 1.207494
0x3cd4
// 1.180141
0x3cb8
// 1.166498
0x3caa
// 1.156696
0x3ca0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0

@ -0,0 +1,12 @@
H
5
// 1.510231
0x3e0a
// 1.081673
0x3c54
// 1.592491
0x3e5f
// 0.000000
0x0
// 0.000000
0x0

@ -0,0 +1,62 @@
H
30
// 1.000000
0x3c00
// -0.568305
0xb88c
// 0.036464
0x28ab
// 1.000000
0x3c00
// -0.531454
0xb840
// -0.052578
0xaabb
// -0.044437
0xa9b0
// -0.381603
0xb61b
// -0.577977
0xb8a0
// -0.148253
0xb0be
// 0.245248
0x33d9
// 1.000000
0x3c00
// -0.047169
0xaa0a
// -0.124241
0xaff4
// 0.310853
0x34f9
// 0.077501
0x2cf6
// 0.205539
0x3294
// -0.145392
0xb0a7
// 0.106009
0x2ec9
// -0.241024
0xb3b6
// 0.001252
0x1521
// -0.053667
0xaadf
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0

@ -0,0 +1,12 @@
H
5
// 3
0x0003
// 8
0x0008
// 11
0x000B
// 4
0x0004
// 4
0x0004

@ -0,0 +1,140 @@
H
69
// 3
0x0003
// 3
0x0003
// 1
0x0001
// 3
0x0003
// 3
0x0003
// 3
0x0003
// 8
0x0008
// 3
0x0003
// 1
0x0001
// 8
0x0008
// 3
0x0003
// 3
0x0003
// 8
0x0008
// 3
0x0003
// 8
0x0008
// 8
0x0008
// 8
0x0008
// 1
0x0001
// 8
0x0008
// 8
0x0008
// 3
0x0003
// 8
0x0008
// 8
0x0008
// 8
0x0008
// 11
0x000B
// 3
0x0003
// 1
0x0001
// 11
0x000B
// 3
0x0003
// 3
0x0003
// 11
0x000B
// 3
0x0003
// 8
0x0008
// 11
0x000B
// 3
0x0003
// 11
0x000B
// 11
0x000B
// 8
0x0008
// 1
0x0001
// 11
0x000B
// 8
0x0008
// 3
0x0003
// 11
0x000B
// 8
0x0008
// 8
0x0008
// 11
0x000B
// 8
0x0008
// 11
0x000B
// 11
0x000B
// 11
0x000B
// 1
0x0001
// 11
0x000B
// 11
0x000B
// 3
0x0003
// 11
0x000B
// 11
0x000B
// 8
0x0008
// 11
0x000B
// 11
0x000B
// 11
0x000B
// 3
0x0003
// 3
0x0003
// 3
0x0003
// 8
0x0008
// 8
0x0008
// 8
0x0008
// 11
0x000B
// 11
0x000B
// 11
0x000B

@ -0,0 +1,62 @@
W
30
// 0.169095
0x3e2d272e
// 1.000000
0x3f800000
// -0.245425
0xbe7b50cf
// 0.878361
0x3f60dc3d
// -0.226072
0xbe677f61
// -0.235404
0xbe710db4
// 0.657524
0x3f28537b
// -0.165269
0xbe293c3e
// -0.160314
0xbe242966
// -0.654146
0xbf277624
// 1.000000
0x3f800000
// -0.029512
0xbcf1c2bf
// -0.552271
0xbf0d61a7
// -0.765585
0xbf43fd65
// 0.458211
0x3eea9a9b
// -0.159167
0xbe22fc92
// 0.319820
0x3ea3bf7d
// 0.363710
0x3eba3836
// -1.000000
0xbf800000
// -0.016260
0xbc853483
// -0.101712
0xbdd04e56
// 0.392709
0x3ec9111c
// 1.000000
0x3f800000
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// -1.000000
0xbf800000
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,300 @@
W
149
// 1.944958
0x3ff8f45f
// 0.000000
0x0
// 0.000000
0x0
// 1.861959
0x3fee54aa
// 1.689097
0x3fd83455
// 0.000000
0x0
// 1.524469
0x3fc321cb
// 0.000000
0x0
// 0.000000
0x0
// 1.495681
0x3fbf7279
// 1.017388
0x3f8239c6
// 1.446700
0x3fb92d77
// 1.353075
0x3fad318d
// 1.179097
0x3f96eca7
// 1.484692
0x3fbe0a66
// 1.110829
0x3f8e2fa6
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 1.234617
0x3f9e07ea
// 1.440628
0x3fb8667e
// 1.282016
0x3fa41917
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 1.687249
0x3fd7f7c8
// 1.539779
0x3fc51779
// 1.056767
0x3f874424
// 1.171077
0x3f95e5d8
// 1.714564
0x3fdb76d7
// 1.854760
0x3fed68c6
// 1.798975
0x3fe644d1
// 0.000000
0x0
// 1.233551
0x3f9de4fd
// 0.000000
0x0
// 0.000000
0x0
// 1.456008
0x3fba5e78
// 1.079499
0x3f8a2d02
// 1.268513
0x3fa25ea3
// 1.048598
0x3f863873
// 1.306935
0x3fa749a7
// 1.114489
0x3f8ea797
// 1.263413
0x3fa1b788
// 1.416146
0x3fb54442
// 1.037746
0x3f84d4de
// 1.243646
0x3f9f2fcc
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 1.453098
0x3fb9ff1c
// 1.107877
0x3f8dceec
// 1.239619
0x3f9eabd7
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 1.161391
0x3f94a879
// 1.082779
0x3f8a987c
// 1.775636
0x3fe3480c
// 1.086696
0x3f8b18dc
// 1.003480
0x3f807209
// 1.543225
0x3fc58862
// 1.193077
0x3f98b6c0
// 1.405155
0x3fb3dc1d
// 1.268312
0x3fa2580d
// 1.066854
0x3f888ea9
// 1.060062
0x3f87b01c
// 1.212024
0x3f9b2398
// 1.139816
0x3f91e57a
// 1.162189
0x3f94c29d
// 1.113435
0x3f8e850c
// 1.968770
0x3ffc00a8
// 1.396972
0x3fb2cffa
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 1.483895
0x3fbdf043
// 1.302077
0x3fa6aa71
// 1.177689
0x3f96be86
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 1.170629
0x3f95d72d
// 1.195120
0x3f98f9af
// 1.171645
0x3f95f875
// 1.442618
0x3fb8a7b2
// 1.274664
0x3fa3282f
// 1.328844
0x3faa178d
// 1.604068
0x3fcd521a
// 1.891565
0x3ff21ecb
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 1.402246
0x3fb37ccd
// 1.216918
0x3f9bc3f6
// 1.389103
0x3fb1ce24
// 1.207991
0x3f9a9f75
// 1.052820
0x3f86c2cb
// 1.364205
0x3fae9e46
// 1.503842
0x3fc07de4
// 1.210725
0x3f9af90b
// 1.303660
0x3fa6de55
// 1.321830
0x3fa931bd
// 0.000000
0x0
// 1.816500
0x3fe88311
// 1.694142
0x3fd8d9a6
// 0.000000
0x0
// 1.606620
0x3fcda5b8
// 1.005239
0x3f80abae
// 1.297398
0x3fa61120
// 1.535747
0x3fc4935a
// 1.583723
0x3fcab76d
// 1.653492
0x3fd3a59d
// 1.766550
0x3fe21e54
// 0.000000
0x0
// 1.545362
0x3fc5ce6c
// 1.222879
0x3f9c8748
// 1.098866
0x3f8ca7a8
// 1.519790
0x3fc28879
// 1.536751
0x3fc4b446
// 1.562998
0x3fc81053
// 1.596865
0x3fcc660f
// 1.641822
0x3fd2273c
// 1.705480
0x3fda4d2a
// 1.805779
0x3fe723c4
// 0.000000
0x0

@ -0,0 +1,12 @@
W
5
// 1.162051
0x3f94be13
// 1.525738
0x3fc34b64
// 1.018566
0x3f826060
// 0.000000
0x0
// 0.000000
0x0

@ -0,0 +1,62 @@
W
30
// 1.000000
0x3f800000
// 0.824699
0x3f531f7c
// -0.202402
0xbe4f4284
// 1.000000
0x3f800000
// -0.088688
0xbdb5a1df
// -0.092349
0xbdbd2141
// 0.257946
0x3e841173
// -0.064835
0xbd84c813
// -0.062891
0xbd80cd01
// -0.256621
0xbe8363ca
// 0.392299
0x3ec8db5b
// 1.000000
0x3f800000
// 0.341105
0x3eaea544
// 0.472856
0x3ef21a27
// -0.283009
0xbe90e693
// 0.098308
0x3dc9557e
// -0.197534
0xbe4a4645
// -0.224642
0xbe66087d
// 0.617640
0x3f1e1da1
// 0.010043
0x3c248ba7
// 0.062821
0x3d80a875
// -0.242552
0xbe785fa8
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0

@ -0,0 +1,12 @@
H
5
// 3
0x0003
// 8
0x0008
// 11
0x000B
// 4
0x0004
// 4
0x0004

@ -0,0 +1,140 @@
H
69
// 2
0x0002
// 2
0x0002
// 1
0x0001
// 2
0x0002
// 2
0x0002
// 2
0x0002
// 4
0x0004
// 2
0x0002
// 1
0x0001
// 4
0x0004
// 2
0x0002
// 2
0x0002
// 4
0x0004
// 2
0x0002
// 4
0x0004
// 4
0x0004
// 4
0x0004
// 1
0x0001
// 4
0x0004
// 4
0x0004
// 2
0x0002
// 4
0x0004
// 4
0x0004
// 4
0x0004
// 5
0x0005
// 2
0x0002
// 1
0x0001
// 5
0x0005
// 2
0x0002
// 2
0x0002
// 5
0x0005
// 2
0x0002
// 4
0x0004
// 5
0x0005
// 2
0x0002
// 5
0x0005
// 5
0x0005
// 4
0x0004
// 1
0x0001
// 5
0x0005
// 4
0x0004
// 2
0x0002
// 5
0x0005
// 4
0x0004
// 4
0x0004
// 5
0x0005
// 4
0x0004
// 5
0x0005
// 5
0x0005
// 5
0x0005
// 1
0x0001
// 5
0x0005
// 5
0x0005
// 2
0x0002
// 5
0x0005
// 5
0x0005
// 4
0x0004
// 5
0x0005
// 5
0x0005
// 5
0x0005
// 2
0x0002
// 2
0x0002
// 2
0x0002
// 4
0x0004
// 4
0x0004
// 4
0x0004
// 5
0x0005
// 5
0x0005
// 5
0x0005

@ -0,0 +1,692 @@
D
345
// 0.250016
0x3fd00044d5b0ba2f
// 0.212702
0x3fcb39cddf21d4dd
// 1.000000
0x3ff0000000000000
// 0.850750
0x3feb3958bfd08492
// -0.214389
0xbfcb71185888e174
// -0.976748
0xbfef4185d362888c
// 0.976748
0x3fef4185d362888b
// -0.214389
0xbfcb71185888e174
// -0.426688
0xbfdb4edb61b66054
// 0.232817
0x3fcdccf47761087c
// -0.111167
0xbfbc756b8433f2c0
// 0.060657
0x3faf0e678f44c3a5
// 0.430923
0x3fdb943d9dc2b849
// -0.235128
0xbfce18abf7cb7c7c
// -1.000000
0xbff0000000000000
// 0.545638
0x3fe175dde6eaecaf
// 0.268599
0x3fd130b91db8f687
// -0.701589
0xbfe6736ac57e1063
// -0.250150
0xbfd002753bd0db23
// 0.264655
0x3fd0f01a0cc00ef4
// 0.906956
0x3fed05c8ea5e7843
// 0.400732
0x3fd9a599c3028b22
// -0.206664
0xbfca73fa94fef6c6
// 0.526445
0x3fe0d8a3167e7df2
// 0.425830
0x3fdb40cdae5c77b2
// -0.308670
0xbfd3c13db9b175ec
// -0.746396
0xbfe7e278e8d17da2
// 0.108771
0x3fbbd868f69793b8
// 0.287220
0x3fd261d1f50dd9e1
// -0.468616
0xbfddfdcf8a0cc5d8
// -0.423163
0xbfdb1518f2e6ab4f
// -0.820543
0xbfea41e3462efe2d
// -0.018204
0xbf92a41787596f0b
// 0.079725
0x3fb468d9c219870d
// -0.080603
0xbfb4a2605c6ba7a5
// -0.221562
0xbfcc5c2180236bd6
// 0.082163
0x3fb5089c4a2f2651
// -0.359832
0xbfd7077b958e7ee1
// 0.363793
0x3fd7486468fa3c35
// 1.000000
0x3ff0000000000000
// -0.030922
0xbf9fa9e49095231f
// 0.135421
0x3fc15579a7e23d01
// -0.136912
0xbfc18654fc914a4b
// -0.376345
0xbfd8160adee6af13
// 0.004511
0x3f727a07a71f08b5
// -0.019756
0xbf943acc43f41c4d
// 0.019973
0x3f9473d110c60f37
// 0.054902
0x3fac1c238c0678cd
// 0.149389
0x3fc31f29e844e67e
// -0.413379
0xbfda74cc98fdd29a
// 0.438122
0x3fdc0a31a8a1719c
// -0.587539
0xbfe2cd1dfd40af8d
// 0.147304
0x3fc2dadc1d9e77b4
// -0.162536
0xbfc4cdf8558f22e4
// 0.362029
0x3fd72b7d98d740a1
// -0.014669
0xbf8e0ada1d260510
// 0.144501
0x3fc27f01a5b42a51
// -0.195592
0xbfc90924e45b4368
// 0.365462
0x3fd763bb9f95048d
// -0.097680
0xbfb90188411c6f24
// -0.257564
0xbfd07bef59c58fa7
// -0.042469
0xbfa5be7d3a2290ac
// -0.539739
0xbfe1458b2848c300
// -0.727014
0xbfe743b2e5fdf50a
// 0.182166
0x3fc751343aee5809
// -0.740023
0xbfe7ae43e17e032b
// -0.155547
0xbfc3e8f87f616ced
// -0.628480
0xbfe41c826449b90a
// 0.920555
0x3fed7530b4acda8c
// 0.159151
0x3fc45f1309fb510a
// -0.319563
0xbfd473b985f3d27e
// 0.158517
0x3fc44a4d0e899642
// 0.327117
0x3fd4ef7cc64722bb
// 0.178152
0x3fc6cdacfcc9772d
// 0.867513
0x3febc2ab2d0c2692
// -0.329662
0xbfd5192edef06f11
// 0.111300
0x3fbc7e29646d93e4
// -0.628728
0xbfe41e8ae72c032d
// 0.348002
0x3fd645a888873059
// 0.686446
0x3fe5f75d32017dcf
// -0.557757
0xbfe1d92537ddfc31
// -0.272380
0xbfd16eae83ec6708
// 0.697303
0x3fe6504ea0ba6bc2
// 0.340528
0x3fd5cb3507063041
// 1.000000
0x3ff0000000000000
// 0.488350
0x3fdf411f2abf8272
// 0.148513
0x3fc3027af9dc8d63
// 0.072526
0x3fb29116afa558b9
// -0.493267
0xbfdf91af126f68a3
// -0.240887
0xbfced56044c71d8c
// 0.222148
0x3fcc6f5492d4083c
// 0.263245
0x3fd0d90306bd8c22
// 0.121930
0x3fbf36cac67ac643
// -0.250848
0xbfd00de3f234f190
// -0.655434
0xbfe4f95192ff0676
// -0.391136
0xbfd90860f2297360
// 0.646114
0x3fe4acf802feab31
// -0.050890
0xbfaa0e45d70fe288
// 0.297868
0x3fd310468fdc9175
// -0.843919
0xbfeb01630a4b4e21
// -0.601424
0xbfe33eddf1e874d6
// 0.679449
0x3fe5be0bb2383a63
// 0.156037
0x3fc3f904f5393377
// -0.210120
0xbfcae533315c638f
// 0.484968
0x3fdf09b763e0057e
// 0.027975
0x3f9ca58d26546870
// -0.087510
0xbfb6670e1265d0cf
// 0.000539
0x3f41acdc78345dc0
// -0.609171
0xbfe37e545ad683ca
// -0.702436
0xbfe67a5a879f8e32
// 0.327677
0x3fd4f8a8f6ca6af5
// 0.713038
0x3fe6d134c3042a5e
// 0.283161
0x3fd21f4da5b10b93
// 0.059462
0x3fae71d2d8a03c84
// 0.869545
0x3febd3502f540181
// -0.359248
0xbfd6fdeb5e626de8
// -0.237163
0xbfce5b5d091c6a90
// -0.282465
0xbfd213e76f3bc2e4
// 0.009636
0x3f83bbd9bd000f60
// -0.528390
0xbfe0e891a93a4e8f
// 0.078299
0x3fb40b6bab58522c
// -1.000000
0xbff0000000000000
// 0.368155
0x3fd78fd9328e3fcc
// -0.898222
0xbfecbe3c8cfb52eb
// -0.041885
0xbfa571ff4584551d
// 0.534939
0x3fe11e390a4b7084
// -0.196940
0xbfc935587c94b256
// 0.480494
0x3fdec06b7f898149
// 0.075356
0x3fb34a807e7b6b04
// -0.962404
0xbfeecc0463059712
// 0.354314
0x3fd6ad13e2ebf2a2
// -0.864453
0xbfeba99976e7824c
// 0.036874
0x3fa2e12e6cc3ae6b
// -0.470940
0xbfde23e11673daa0
// 0.173379
0x3fc63146b0ec061e
// -0.423009
0xbfdb1293042a6990
// 0.046339
0x3fa7b9c565d01896
// -0.591822
0xbfe2f033da65fab4
// 0.217882
0x3fcbe38e6ef8cb34
// -0.531587
0xbfe102c368cad262
// 0.183731
0x3fc7847bc7fa1079
// -0.000070
0xbf1266ec18334e00
// -0.039796
0xbfa46033262f49ae
// 0.122956
0x3fbf7a0ee3945c14
// -0.228769
0xbfcd484ed14982ec
// 0.139539
0x3fc1dc6d84863ff9
// 0.293633
0x3fd2cae3ebe6054c
// 0.345958
0x3fd6242e832b31b8
// -0.136106
0xbfc16be7f9205bac
// -0.026821
0xbf9b76d9feb5fc54
// -0.017554
0xbf91f9b05e6ce5fa
// -0.187253
0xbfc7f7e918f8f863
// -0.249664
0xbfcff4fc6f97ce92
// 0.224359
0x3fccb7c8409bb2ee
// 0.446603
0x3fdc9526d00c2155
// 0.635488
0x3fe455eade77cd35
// 0.794040
0x3fe968c682ae1abf
// -0.014196
0xbf8d130a59bd9ae0
// -0.196308
0xbfc9209cc24a945c
// 0.481669
0x3fded3a83835b4e4
// 0.003134
0x3f69abf2b8ee5a90
// 0.834454
0x3feab3d8b0ea882e
// 0.237527
0x3fce674afc6f7bb8
// 0.192392
0x3fc8a04de8a16987
// 0.434313
0x3fdbcbc9d7e922c3
// -0.364001
0xbfd74bc9b8795e96
// -0.274604
0xbfd1931de7c428ac
// 0.066012
0x3fb0e62839e552c0
// -0.245202
0xbfcf62c524c0d759
// -0.255966
0xbfd061bfc22a7d54
// 0.163259
0x3fc4e5abe25b14a4
// 0.920702
0x3fed76645f3933c7
// -0.853573
0xbfeb5078ae25e667
// -0.052039
0xbfaaa4cecc3588c4
// -0.336240
0xbfd584f576379263
// -0.180879
0xbfc72707240c70c9
// -0.150503
0xbfc343ae085c1416
// -0.320879
0xbfd48948e41942e2
// 0.853500
0x3feb4fdf5514d11e
// -0.279675
0xbfd1e632a94ff059
// 0.484502
0x3fdf02150530a206
// -0.743822
0xbfe7cd63d15e44fa
// -0.015745
0xbf901f68c434e95c
// -0.332158
0xbfd5421253c528e9
// -0.181448
0xbfc739aef86fffb8
// -0.182770
0xbfc764fe612e7c38
// 0.445519
0x3fdc836239d310e7
// 0.654523
0x3fe4f1d981dc0b6e
// 0.248116
0x3fcfc2437982dca1
// -0.135676
0xbfc15dd4c432862e
// 0.738235
0x3fe79f9f09ff8761
// 0.045222
0x3fa7274a94989636
// 0.706551
0x3fe69c1151af48ff
// 0.606729
0x3fe36a53209d7bbc
// 0.149498
0x3fc322be65a8f27b
// -0.017157
0xbf9191a4c789e71c
// 0.414196
0x3fda822f85333bee
// -0.163695
0xbfc4f3f20251f068
// -0.483657
0xbfdef43db14f308f
// 0.677445
0x3fe5ada18b09b18a
// -0.748598
0xbfe7f484c8b04d37
// 0.626885
0x3fe40f722dfd6a61
// -1.000000
0xbff0000000000000
// -0.017943
0xbf925f8795be6148
// 0.272157
0x3fd16b07489ba5b4
// 0.148030
0x3fc2f2a3fd95f831
// -0.123962
0xbfbfbbf8a67452d0
// 0.197743
0x3fc94fa1190cefc0
// 0.003548
0x3f6d10b48575459c
// -0.053817
0xbfab8deb35a84eb0
// -0.576875
0xbfe275c2132e1481
// 0.483082
0x3fdeead0a7a83c94
// -0.770606
0xbfe8a8cebcf6fcc9
// -0.013827
0xbf8c5123d731a108
// 0.209726
0x3fcad84fc9181803
// -0.021537
0xbf960dc6835a325f
// 0.018035
0x3f9277d75e045ee6
// -0.028770
0xbf9d75cb41379be1
// -0.000516
0xbf40ea34dae61f46
// 0.007830
0x3f80091c8ee46775
// -0.328680
0xbfd50919c04fd41c
// 0.275241
0x3fd19d8c89ac736e
// -0.439061
0xbfdc1993a7eebcc9
// -0.007878
0xbf8022460c360838
// 0.119494
0x3fbe9724b895c1db
// -0.030320
0xbf9f0c55100f50f4
// -0.018907
0xbf935c684066e396
// -0.287561
0xbfd26764977a3bda
// -0.359597
0xbfd703a14fa21427
// 0.237996
0x3fce76a833649644
// 0.097007
0x3fb8d56fda1c2815
// -0.158978
0xbfc4596305ba3562
// -0.269891
0xbfd145e431b3a069
// -0.373878
0xbfd7ed9f1a9f8966
// 0.205847
0x3fca5930bb23d55b
// 0.396396
0x3fd95e8bd938d218
// -0.405368
0xbfd9f18b66c0b21d
// 0.221461
0x3fcc58d85fe73640
// 0.168776
0x3fc59a73e9aa7d0c
// -0.235397
0xbfce2180eb0a66ab
// -0.510394
0xbfe05525f8a2a4c4
// 0.586704
0x3fe2c648369f893a
// 0.065951
0x3fb0e222bec017f9
// 0.232475
0x3fcdc1bbc8e9f1a1
// 0.017681
0x3f921af46d253636
// 0.075713
0x3fb361eba4484db6
// -0.027114
0xbf9bc3ac931afbb6
// 0.315084
0x3fd42a56b0b0a180
// 0.381695
0x3fd86db100d16adf
// -0.266711
0xbfd111ca1f93ea7f
// 0.278020
0x3fd1cb1658e92303
// -0.047845
0xbfa87f31fdc9e220
// 0.202172
0x3fc9e0c4e043a96c
// 0.157952
0x3fc437c3873a888f
// -0.618639
0xbfe3cbe34b2e94fe
// 0.069693
0x3fb1d75f6f33a88a
// 0.176804
0x3fc6a182b51bb9ba
// -0.110985
0xbfbc6986895c1884
// -0.631154
0xbfe4326929520728
// 0.464905
0x3fddc0ffc770136a
// -0.695187
0xbfe63ef7f4195a2b
// -0.186976
0xbfc7eed4180cd9d2
// 0.174651
0x3fc65af2b25c2f92
// 0.439160
0x3fdc1b334974a91a
// 0.314596
0x3fd422574960aefe
// 0.245793
0x3fcf76282806c368
// 0.332566
0x3fd548c3ada31bf7
// -0.699646
0xbfe6637f22651590
// 0.528825
0x3fe0ec21fe6aeff9
// 0.177720
0x3fc6bf87515029d8
// -0.082860
0xbfb5364d4552748c
// 0.876913
0x3fec0fab88418044
// 0.457229
0x3fdd433ec4210dea
// 0.107987
0x3fbba502b602e784
// 0.007337
0x3f7e0daa3c6faf40
// 0.331222
0x3fd532bdc899a6de
// -0.757324
0xbfe83bfed1cd63e8
// -0.136602
0xbfc17c2cda68620c
// 0.274833
0x3fd196df0433a740
// -0.471762
0xbfde3158fcfc40ae
// -0.369781
0xbfd7aa7d1912dd9f
// 0.246506
0x3fcf8d7f1ce92234
// -0.400848
0xbfd9a77cc57785b5
// -0.328543
0xbfd506d8a7d81892
// -0.730669
0xbfe761a4fb83b023
// 0.558074
0x3fe1dbbd6ac978f7
// 0.034487
0x3fa1a84626ef2a48
// 0.415475
0x3fda97251cdb48f6
// -0.692573
0xbfe6298f1d91b786
// -0.187316
0xbfc7f9f75c8457e1
// -0.646154
0xbfe4ad4b471e5b99
// -0.556382
0xbfe1cde1df70631c
// 0.341263
0x3fd5d74065bc5c2e
// -0.376476
0xbfd8182d67377a61
// 0.121365
0x3fbf11cde191d140
// -0.156821
0xbfc412b519f37514
// 0.234404
0x3fce00f6f823714a
// 0.729096
0x3fe754c14c88a4e4
// 0.441741
0x3fdc457a170c5530
// -0.440166
0xbfdc2bad5c89c699
// 2.000000
0x4000000000000000
// -1.000000
0xbfefffffdffffff0
// -1.000000
0xbfefffffdffffff0
// 0.000000
0x0
// 2.000000
0x4000000000000000
// -0.999827
0xbfeffe95ee193d85
// -0.999827
0xbfeffe95ee193d85
// -0.999827
0xbfeffe95ee193d85
// -0.999827
0xbfeffe95ee193d85
// 0.037163
0x3fa306fe0a31b715
// -0.018578
0xbf930626c072f6e8
// -0.018578
0xbf930626c072f6e8
// -0.999827
0xbfeffe95ee193d85
// -0.018578
0xbf930626c072f6e8
// 0.000691
0x3f46a09e667f3bcc
// -0.000345
0xbf369f9e60d6d42f
// -0.999827
0xbfeffe95ee193d85
// -0.018578
0xbf930626c072f6e8
// -0.000345
0xbf369f9e60d6d42f
// 0.000000
0x0
// 2.000000
0x4000000000000000
// -0.999149
0xbfeff9085a9c0401
// -0.999149
0xbfeff9085a9c0401
// -0.999149
0xbfeff9085a9c0401
// -0.999149
0xbfeff9085a9c0401
// -0.999149
0xbfeff9085a9c0401
// 0.082469
0x3fb51cb453b9536b
// -0.041200
0xbfa5181b8f3bc18e
// -0.041200
0xbfa5181b8f3bc18e
// -0.041200
0xbfa5181b8f3bc18e
// -0.999149
0xbfeff9085a9c0401
// -0.041200
0xbfa5181b8f3bc18e
// 0.003401
0x3f6bdb8cdadbe11d
// -0.001699
0xbf5bd57c19d085ad
// -0.001699
0xbf5bd57c19d085ad
// -0.999149
0xbfeff9085a9c0401
// -0.041200
0xbfa5181b8f3bc18e
// -0.001699
0xbf5bd57c19d085ad
// 0.000140
0x3f22611186bae671
// -0.000070
0xbf125d1117346c0a
// -0.999149
0xbfeff9085a9c0401
// -0.041200
0xbfa5181b8f3bc18e
// -0.001699
0xbf5bd57c19d085ad
// -0.000070
0xbf125d1117346c0a
// 0.000000
0x0

@ -0,0 +1,62 @@
D
30
// 0.093817
0x3fb804660a9cfb12
// -1.000000
0xbff0000000000000
// -0.154496
0xbfc3c68a6dae4cfb
// 0.239123
0x3fce9b9334f51744
// 0.336311
0x3fd5861e28238833
// 0.020124
0x3f949b5378206fa2
// 0.277812
0x3fd1c7acf3bdda77
// -0.669498
0xbfe56c87ae5d1138
// 0.729965
0x3fe75bdefe0928a6
// 1.000000
0x3ff0000000000000
// -0.495025
0xbfdfae7d66ac0dac
// -0.051969
0xbfaa9bab4ebe8c25
// 0.016906
0x3f914fe512037b93
// -0.207615
0xbfca93242b18cf34
// -0.839682
0xbfeadeadc6650466
// -0.227335
0xbfcd194c4b06eafe
// 0.954023
0x3fee875acf83280b
// 1.000000
0x3ff0000000000000
// -0.257931
0xbfd081f023dc0ef9
// 0.272904
0x3fd17742615ac209
// 0.585691
0x3fe2bdfbde05c94b
// 0.220540
0x3fcc3aab276063cf
// 1.000000
0x3ff0000000000000
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// -1.000000
0xbff0000000000000
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0

@ -0,0 +1,900 @@
D
449
// -0.242551
0xbfcf0be5fc7f2c88
// -0.970139
0xbfef0b606d8700f4
// -0.970139
0xbfef0b606d8700f4
// 0.242551
0x3fcf0be5fc7f2c8c
// -0.214389
0xbfcb71185888e178
// 0.976748
0x3fef4185d362888d
// 0.976748
0x3fef4185d362888d
// 0.214389
0x3fcb71185888e170
// -0.363206
0xbfd73ec39e565f04
// -0.094627
0xbfb839809ae74977
// 0.366811
0x3fd779d3348cdfc7
// -0.851221
0xbfeb3d33c992ca3c
// -0.094627
0xbfb839809ae74977
// 0.993431
0x3fefca30a802f0ba
// 0.025462
0x3f9a12c946e8ded6
// -0.059088
0xbfae40c1ce2f6df1
// 0.366811
0x3fd779d3348cdfc7
// 0.025462
0x3f9a12c946e8ded6
// 0.901299
0x3fecd7709f700c4e
// 0.229046
0x3fcd51616658cb85
// -0.851221
0xbfeb3d33c992ca3c
// -0.059088
0xbfae40c1ce2f6df1
// 0.229046
0x3fcd51616658cb85
// 0.468476
0x3fddfb810f7064f6
// -0.268599
0xbfd130b91db8f688
// 0.701589
0x3fe6736ac57e1066
// -0.545296
0xbfe173116f7dde0a
// 0.371859
0x3fd7cc8b36d64670
// 0.250150
0x3fd002753bd0db23
// -0.264655
0xbfd0f01a0cc00ef5
// -0.794793
0xbfe96ef16df1ff9c
// -0.485476
0xbfdf120b049c3722
// -0.906956
0xbfed05c8ea5e7843
// -0.400732
0xbfd9a599c3028b24
// -0.112718
0xbfbcdb1756f1d8e8
// -0.064332
0xbfb078177b8870c0
// 0.206664
0x3fca73fa94fef6c6
// -0.526445
0xbfe0d8a3167e7df4
// -0.241352
0xbfcee49f5427c6b4
// 0.788603
0x3fe93c3c6fe7d094
// -0.425830
0xbfdb40cdae5c77b0
// -0.308670
0xbfd3c13db9b175f0
// -0.694528
0xbfe63992e5eb90a2
// -0.490940
0xbfdf6b91535ad68c
// 0.746396
0x3fe7e278e8d17da2
// 0.108771
0x3fbbd868f69793d4
// -0.042865
0xbfa5f26f43426e80
// -0.655153
0xbfe4f702f0b86c99
// -0.287220
0xbfd261d1f50dd9e1
// -0.468616
0xbfddfdcf8a0cc5db
// 0.703188
0x3fe680852a2a886a
// -0.451031
0xbfdcddb172677ace
// 0.423163
0x3fdb1518f2e6ab4f
// -0.820543
0xbfea41e3462efe2c
// -0.146011
0xbfc2b07f3a7567f2
// 0.355420
0x3fd6bf3342a01dd2
// -0.202787
0xbfc9f4eb12c214d0
// 0.915261
0x3fed49d27bab28ec
// -0.344454
0xbfd60b8a908a7213
// 0.050250
0x3fa9ba594d49161a
// 0.915261
0x3fed49d27bab28ec
// 0.303531
0x3fd36d0db1ba1818
// 0.262113
0x3fd0c674f2d95dbf
// -0.038238
0xbfa393e30e234ace
// -0.344454
0xbfd60b8a908a7213
// 0.262113
0x3fd0c674f2d95dbf
// 0.901355
0x3fecd7e689a5efb6
// 0.014391
0x3f8d78cd3a947c0f
// 0.050250
0x3fa9ba594d49161a
// -0.038238
0xbfa393e30e234ace
// 0.014391
0x3f8d78cd3a947c0f
// 0.997901
0x3fefeecd622d8971
// -0.412375
0xbfda645837c0ee60
// 0.748531
0x3fe7f3f7d2b9ccad
// -0.394971
0xbfd94732756dea88
// -0.337115
0xbfd5934a7990322c
// -0.406621
0xbfda06122fc17455
// 0.118560
0x3fbe59fac745d593
// -0.117426
0xbfbe0fa92accb947
// 0.898228
0x3fecbe496173aa37
// -0.398883
0xbfd9874b53a3a2a2
// 0.207685
0x3fca956ceb3d2df7
// 0.888440
0x3fec6e19758345a6
// -0.091837
0xbfb782a4e501e708
// 0.710985
0x3fe6c0636ff93d03
// 0.618475
0x3fe3ca8bfc0e9117
// 0.202198
0x3fc9e19d0242e96b
// 0.266656
0x3fd110e33d4503c8
// -0.182166
0xbfc751343aee5810
// 0.740023
0x3fe7ae43e17e032c
// 0.155547
0x3fc3e8f87f616cf6
// -0.628480
0xbfe41c826449b90c
// -0.920555
0xbfed7530b4acda8d
// -0.159151
0xbfc45f1309fb510b
// 0.319563
0x3fd473b985f3d283
// 0.158517
0x3fc44a4d0e899648
// -0.327117
0xbfd4ef7cc64722bc
// -0.178152
0xbfc6cdacfcc9772d
// -0.867513
0xbfebc2ab2d0c2695
// -0.329662
0xbfd5192edef06f12
// -0.111300
0xbfbc7e29646d93e5
// 0.628728
0x3fe41e8ae72c032e
// -0.348002
0xbfd645a888873058
// 0.686446
0x3fe5f75d32017dce
// -0.388354
0xbfd8daca9dd67df8
// 0.485517
0x3fdf12b5597d1401
// 0.696278
0x3fe647e8f32ad7e0
// 0.103406
0x3fba78d8de23becb
// -0.343451
0xbfd5fb196937526a
// 0.485517
0x3fdf12b5597d1401
// 0.830211
0x3fea911791530d10
// -0.243493
0xbfcf2ac8ff1832ad
// -0.036162
0xbfa283d1ca805802
// 0.120107
0x3fbebf5719d31d2d
// 0.696278
0x3fe647e8f32ad7e0
// -0.243493
0xbfcf2ac8ff1832ad
// 0.650807
0x3fe4d369b578356b
// -0.051860
0xbfaa8d5bdb88e91d
// 0.172245
0x3fc60c2186f64dc5
// 0.103406
0x3fba78d8de23becb
// -0.036162
0xbfa283d1ca805802
// -0.051860
0xbfaa8d5bdb88e91d
// 0.992298
0x3fefc0e80a569f51
// 0.025581
0x3f9a31d2c941b39e
// -0.343451
0xbfd5fb196937526a
// 0.120107
0x3fbebf5719d31d2d
// 0.172245
0x3fc60c2186f64dc5
// 0.025581
0x3f9a31d2c941b39e
// 0.915037
0x3fed47fbfdc95d30
// -0.222148
0xbfcc6f5492d40840
// 0.263245
0x3fd0d90306bd8c23
// 0.730822
0x3fe762e40c9fe594
// -0.588792
0xbfe2d76312bf8400
// -0.023993
0xbf9891961ed42038
// -0.121930
0xbfbf36cac67ac642
// -0.250848
0xbfd00de3f234f18e
// -0.177047
0xbfc6a978a9bec18c
// -0.248802
0xbfcfd8c18e6ac800
// -0.910473
0xbfed22975c7deb16
// 0.655434
0x3fe4f95192ff0676
// -0.391136
0xbfd90860f2297360
// 0.559140
0x3fe1e47979c4964c
// 0.278569
0x3fd1d4120901a8b4
// -0.164864
0xbfc51a407a0edef0
// -0.646114
0xbfe4acf802feab32
// -0.050890
0xbfaa0e45d70fe290
// 0.349165
0x3fd658ba0a7ce075
// 0.660437
0x3fe5224dbdd82ba5
// -0.147825
0xbfc2ebef77d9fe05
// -0.297868
0xbfd310468fdc9175
// -0.843919
0xbfeb01630a4b4e22
// 0.000389
0x3f397b927b1e1600
// -0.278644
0xbfd1d54facfdf2d6
// 0.348471
0x3fd64d578d9eb72c
// -0.601424
0xbfe33eddf1e874d6
// 0.679449
0x3fe5be0bb2383a66
// 0.378019
0x3fd83177acf37967
// -0.070768
0xbfb21ddd9929e750
// -0.169503
0xbfc5b24934964406
// 0.156037
0x3fc3f904f5393378
// -0.210120
0xbfcae533315c6395
// 0.196904
0x3fc93423d89dc554
// -0.029694
0xbf9e680a2e9a6b61
// -0.944378
0xbfee3857c9b0c88d
// 0.484968
0x3fdf09b763e00580
// 0.027975
0x3f9ca58d26546858
// 0.837763
0x3feacef44ba5e97a
// 0.028907
0x3f9d99e5f27c1574
// 0.247671
0x3fcfb3af5178c63a
// -0.087510
0xbfb6670e1265d0d0
// 0.000539
0x3f41acdc78345ec0
// 0.028133
0x3f9ccef0bf071824
// 0.994963
0x3fefd6bba7d803ee
// -0.039998
0xbfa47a8e8e33f7d4
// -0.609171
0xbfe37e545ad683cb
// -0.702436
0xbfe67a5a879f8e32
// 0.340135
0x3fd5c4c75cd7c455
// -0.057655
0xbfad84eccc498326
// 0.128368
0x3fc06e5fe57079a7
// -0.327677
0xbfd4f8a8f6ca6af4
// 0.713038
0x3fe6d134c3042a5e
// -0.116210
0xbfbdbff44f8aa93c
// 0.378572
0x3fd83a874862d3ad
// 0.476847
0x3fde84a901a52f64
// -0.283161
0xbfd21f4da5b10b92
// 0.059462
0x3fae71d2d8a03c86
// -0.851028
0xbfeb3b9ea5c69cc7
// -0.074355
0xbfb308e869c04431
// -0.431865
0xbfdba3ad2eb06299
// -0.869545
0xbfebd3502f540180
// -0.359248
0xbfd6fdeb5e626de5
// 0.299077
0x3fd3241284a056ba
// 0.130657
0x3fc0b95dce1840df
// -0.091182
0xbfb757b299039c20
// 0.237163
0x3fce5b5d091c6a8f
// -0.282465
0xbfd213e76f3bc2e4
// -0.096525
0xbfb8b5e4fd99d0c6
// 0.910360
0x3fed21ab69f5ff71
// -0.160918
0xbfc498f6b1f3f302
// -0.009636
0xbf83bbd9bd000f5f
// -0.528390
0xbfe0e891a93a4e8f
// -0.404330
0xbfd9e08b645825f9
// -0.072991
0xbfb2af8f46edf413
// 0.742900
0x3fe7c5d6d2518b44
// -0.599284
0xbfe32d55949e7c8e
// 0.320581
0x3fd484644c36afcf
// -0.576754
0xbfe274c3ddea5415
// -0.282227
0xbfd21000b52577de
// -0.354669
0xbfd6b2e6712c47d7
// 0.320581
0x3fd484644c36afcf
// 0.935739
0x3fedf192844bce2d
// 0.115612
0x3fbd98bad2e546f4
// 0.056573
0x3facf7252e081da5
// 0.071094
0x3fb2333d338e1837
// -0.576754
0xbfe274c3ddea5415
// 0.115612
0x3fbd98bad2e546f4
// 0.792004
0x3fe95818c8957bbe
// -0.101780
0xbfba0e4296d9eb43
// -0.127905
0xbfc05f3280cc59ba
// -0.282227
0xbfd21000b52577de
// 0.056573
0x3facf7252e081da5
// -0.101780
0xbfba0e4296d9eb43
// 0.950195
0x3fee67ffe200faa5
// -0.062589
0xbfb005d0644abf95
// -0.354669
0xbfd6b2e6712c47d7
// 0.071094
0x3fb2333d338e1837
// -0.127905
0xbfc05f3280cc59ba
// -0.062589
0xbfb005d0644abf95
// 0.921346
0x3fed7baa65bc37fe
// -0.205745
0xbfca55dd6e915038
// -0.090154
0xbfb71455befa9024
// 0.191213
0x3fc879a8fedf8a59
// 0.087760
0x3fb67768654a2fc2
// -0.951460
0xbfee725d3a57cca3
// 0.256181
0x3fd065431dd3567b
// -0.460528
0xbfdd7949bca10dcd
// 0.125138
0x3fc00489720ca165
// -0.838177
0xbfead257aaf5cd94
// -0.063922
0xbfb05d3430c8a718
// 0.152414
0x3fc3824c2058292d
// 0.177161
0x3fc6ad349d736372
// 0.957259
0x3feea1de4cf2eaab
// 0.080716
0x3fb4a9d488c28c4e
// 0.150078
0x3fc335c48f3b0c0e
// 0.279579
0x3fd1e49ee94e8511
// -0.798626
0xbfe98e58ed289adf
// 0.047473
0x3fa84e5bb5738f4c
// 0.525749
0x3fe0d2f03693a686
// 0.073250
0x3fb2c07ed3a2bf5c
// -0.889183
0xbfec742f706484e6
// -0.332560
0xbfd548aaad9cef02
// 0.170819
0x3fc5dd618e09691d
// -0.082649
0xbfb52879b6bd8956
// 0.250495
0x3fd0081d61438a93
// -0.003134
0xbf69abf2b8ee5a00
// 0.834454
0x3feab3d8b0ea882f
// -0.237527
0xbfce674afc6f7bb6
// -0.192392
0xbfc8a04de8a16997
// 0.458523
0x3fdd586efc90bfcb
// -0.434313
0xbfdbcbc9d7e922c5
// -0.364001
0xbfd74bc9b8795e98
// 0.274604
0x3fd1931de7c428ab
// -0.066012
0xbfb0e62839e552b2
// 0.774022
0x3fe8c4ca3487377b
// 0.245202
0x3fcf62c524c0d75b
// -0.255966
0xbfd061bfc22a7d54
// -0.163259
0xbfc4e5abe25b14a8
// -0.920702
0xbfed76645f3933c6
// -0.003389
0xbf6bc3515532aec0
// 0.853573
0x3feb5078ae25e669
// -0.052039
0xbfaaa4cecc3588b8
// 0.336240
0x3fd584f576379264
// 0.180879
0x3fc72707240c70d2
// 0.350614
0x3fd67076a103a34f
// 0.150503
0x3fc343ae085c1417
// -0.320879
0xbfd48948e41942e2
// -0.853500
0xbfeb4fdf5514d11e
// 0.279675
0x3fd1e632a94ff05c
// 0.260202
0x3fd0a724b16c2003
// -0.484502
0xbfdf02150530a204
// -0.743822
0xbfe7cd63d15e44fa
// 0.015745
0x3f901f68c434e940
// 0.332158
0x3fd5421253c528e8
// -0.318449
0xbfd46178ebd94272
// 0.181448
0x3fc739aef86fffb5
// -0.182770
0xbfc764fe612e7c38
// -0.445519
0xbfdc836239d310e9
// -0.654523
0xbfe4f1d981dc0b70
// -0.553882
0xbfe1b965edc3b066
// -0.248116
0xbfcfc2437982dc9d
// -0.135676
0xbfc15dd4c432862e
// -0.738235
0xbfe79f9f09ff8761
// -0.045222
0xbfa7274a94989641
// 0.610733
0x3fe38b1f873619ec
// -0.706551
0xbfe69c1151af48fc
// 0.606729
0x3fe36a53209d7bbf
// -0.149498
0xbfc322be65a8f27f
// 0.017157
0x3f9191a4c789e6e0
// -0.331694
0xbfd53a7b6665c0df
// -0.414196
0xbfda822f85333beb
// -0.163695
0xbfc4f3f20251f064
// 0.483657
0x3fdef43db14f3092
// -0.677445
0xbfe5ada18b09b18e
// 0.329832
0x3fd51bf9b2042e6f
// -0.739921
0xbfe7ad6f8eb0b87c
// 0.146314
0x3fc2ba6a8604abe7
// -0.570188
0xbfe23efb2d018070
// -0.021287
0xbf95cc559daefe8a
// -0.324871
0xbfd4caae5cfc56c5
// 0.146314
0x3fc2ba6a8604abe7
// 0.987696
0x3fef9b34e6adf229
// 0.047948
0x3fa88cb2259d383b
// 0.001790
0x3f5d54359ef26ce1
// 0.027319
0x3f9bf98afd3b5ff6
// -0.570188
0xbfe23efb2d018070
// 0.047948
0x3fa88cb2259d383b
// 0.813144
0x3fea0546dbb80c60
// -0.006976
0xbf7c92e8074b5531
// -0.106463
0xbfbb412a3a9e3ba5
// -0.021287
0xbf95cc559daefe8a
// 0.001790
0x3f5d54359ef26ce1
// -0.006976
0xbf7c92e8074b5531
// 0.999740
0x3feffdddd0468aaf
// -0.003975
0xbf7047bea47b9f46
// -0.324871
0xbfd4caae5cfc56c5
// 0.027319
0x3f9bf98afd3b5ff6
// -0.106463
0xbfbb412a3a9e3ba5
// -0.003975
0xbf7047bea47b9f46
// 0.939342
0x3fee0f15fc042f43
// -0.046041
0xbfa792aed0060740
// -0.517494
0xbfe08f4f78e0d517
// 0.604294
0x3fe3565fad1ac7d5
// -0.510048
0xbfe0524fcd98b257
// 0.323667
0x3fd4b6f7b8dbdde6
// 0.147303
0x3fc2dad031e48fc7
// -0.517673
0xbfe090c69e44503c
// -0.079412
0xbfb4545bfb66df23
// 0.705783
0x3fe695c709ddb2c3
// 0.453740
0x3fdd0a14d73f7db5
// 0.601918
0x3fe342e97a0f893f
// 0.303463
0x3fd36bef439a5708
// 0.652254
0x3fe4df43fac33899
// 0.291229
0x3fd2a37dab24fc56
// -0.188031
0xbfc811636c142772
// -0.775022
0xbfe8ccfb0fa6b70e
// 0.250542
0x3fd008e366ec6804
// 0.445462
0x3fdc8271819e6ee1
// 0.369418
0x3fd7a489b46b2b7b
// 0.040790
0x3fa4e272eae2f5d0
// 0.114968
0x3fbd6e90db583e56
// 0.556196
0x3fe1cc5ae02afdb5
// -0.068201
0xbfb175a0af6e9483
// -0.142960
0xbfc24c8245f64ab0
// 0.807676
0x3fe9d87a5100f384
// -0.349520
0xbfd65e891dfb18b4
// 0.113267
0x3fbcff138ead1a76
// -0.438004
0xbfdc0842d2ca1048
// -0.448642
0xbfdcb68afa82dda6
// -0.686935
0xbfe5fb5eabc91520
// -0.087616
0xbfb66dfb09a28e9a
// -0.168662
0xbfc596b3fd21745a
// 0.138392
0x3fc1b6d227353ab3
// 0.779519
0x3fe8f1d24fac9363
// -0.580581
0xbfe2941e875ba56a
// 0.873970
0x3febf79075438ae2
// 0.036800
0x3fa2d76a9e47a693
// 0.163935
0x3fc4fbd177c4124f
// -0.220288
0xbfcc3262e0e82b14
// -0.399275
0xbfd98db87bde54e1
// -0.309005
0xbfd3c6bc9ea0e0f1
// -0.291123
0xbfd2a1c23f5e6477
// 0.810550
0x3fe9f005f343e8b8
// -0.366785
0xbfd779677e5cdd9e
// -0.168052
0xbfc582b72c09202b
// 0.104169
0x3fbaaad50ecf992a
// -0.934140
0xbfede478fa0cf868
// -0.324245
0xbfd4c06c5b794f87
// -0.089514
0xbfb6ea5ef4d476da
// 0.058177
0x3fadc9513b2f341a
// -0.331222
0xbfd532bdc899a6e0
// 0.757324
0x3fe83bfed1cd63e9
// 0.136602
0x3fc17c2cda686208
// 0.274833
0x3fd196df0433a73c
// 0.471762
0x3fde3158fcfc40b1
// 0.369781
0x3fd7aa7d1912dd9f
// -0.246506
0xbfcf8d7f1ce92238
// 0.400848
0x3fd9a77cc57785b9
// -0.328543
0xbfd506d8a7d81893
// 0.730669
0x3fe761a4fb83b027
// -0.558074
0xbfe1dbbd6ac978f7
// -0.034487
0xbfa1a84626ef2a40
// -0.415475
0xbfda97251cdb48f2
// -0.692573
0xbfe6298f1d91b787
// 0.187316
0x3fc7f9f75c8457e7
// 0.646154
0x3fe4ad4b471e5b99
// 0.556382
0x3fe1cde1df70631e
// -0.341263
0xbfd5d74065bc5c34
// -0.376476
0xbfd8182d67377a58
// -0.121365
0xbfbf11cde191d15a
// 0.156821
0x3fc412b519f37514
// -0.234404
0xbfce00f6f823714b
// -0.729096
0xbfe754c14c88a4e5
// 0.441741
0x3fdc457a170c5532
// 0.440166
0x3fdc2bad5c89c690
// -0.894427
0xbfec9f25cb795bd0
// 0.447214
0x3fdc9f25aeda35f4
// 0.447214
0x3fdc9f25aeda35f4
// 0.894427
0x3fec9f25cb795bd0
// -0.755985
0xbfe83107341a21fe
// -0.653012
0xbfe4e5798664311a
// 0.045407
0x3fa73fa299c7b87c
// -0.000543
0xbf41cc3387f96400
// 0.377927
0x3fd82ff57bf0255a
// -0.378774
0xbfd83dd51e8ad83d
// 0.844748
0x3feb082d05e0ee49
// -0.010104
0xbf84b1a7df9804cc
// 0.377927
0x3fd82ff57bf0255a
// -0.463738
0xbfddade171a8fb03
// -0.385416
0xbfd8aaa904e6c046
// -0.702547
0xbfe67b4442e0923f
// 0.377927
0x3fd82ff57bf0255a
// -0.463738
0xbfddade171a8fb02
// -0.368501
0xbfd795869a48bfe7
// 0.711565
0x3fe6c52463e6844b
// -0.707408
0xbfe6a31526055000
// -0.699129
0xbfe65f44bef1c2d6
// 0.103842
0x3fba9566126f4c66
// 0.003060
0x3f6911ce0fd8e5c0
// -0.000082
0xbf156e4f6114e000
// 0.353403
0x3fd69e27624351b0
// -0.222573
0xbfcc7d43745a4f8a
// 0.908213
0x3fed1014b3c1398b
// 0.026765
0x3f9b6856e7c76277
// -0.000715
0xbf476df8d1b948c0
// 0.353403
0x3fd69e27624351b0
// -0.392292
0xbfd91b508004d7fe
// -0.257511
0xbfd07b0fc369e6e8
// 0.808971
0x3fe9e3175b03e1dc
// -0.021611
0xbf9621385798fa47
// 0.353403
0x3fd69e27624351b0
// -0.392292
0xbfd91b508004d7fd
// -0.221420
0xbfcc57811a940c5a
// -0.433688
0xbfdbc18d1ddef8e0
// -0.695773
0xbfe643c681da26c9
// 0.353403
0x3fd69e27624351b0
// -0.392292
0xbfd91b508004d7fd
// -0.221420
0xbfcc57811a940c54
// -0.395922
0xbfd956c9f43d4a5c
// 0.717936
0x3fe6f954931c7508

@ -0,0 +1,692 @@
D
345
// -1.030780
0xbff07e1393312ff6
// -0.876937
0xbfec0fdda943030b
// 0.780764
0x3fe8fc04bb8a02d4
// 0.000000
0x3c98000000000000
// 1.000000
0x3ff0000000000000
// 0.000000
0x3c98000000000000
// -0.804313
0xbfe9bcedf2dd6650
// -1.000000
0xbff0000000000000
// 1.174783
0x3ff2cbe9551fc84a
// -0.641006
0xbfe4831fb47e5b67
// 0.069415
0x3fb1c534696bdee4
// 0.000000
0x0
// -0.269079
0xbfd13898d1fdb00b
// 0.000000
0x0
// 0.624426
0x3fe3fb4bf7d0d83f
// 0.000000
0x0
// -1.000000
0xbff0000000000001
// -0.000000
0xbc94000000000000
// -0.197186
0xbfc93d64acfcfdbd
// -1.000000
0xbfeffffffffffffe
// 0.714927
0x3fe6e0af969300dd
// 0.801127
0x3fe9a2d42b940e2e
// -0.162908
0xbfc4da280548d972
// 0.365930
0x3fd76b64c76f66d3
// -1.000000
0xbff0000000000001
// -0.000000
0xbcc0000000000000
// -0.523481
0xbfe0c05bee7cbbee
// 1.000000
0x3feffffffffffffe
// 0.201441
0x3fc9c8d057694e2b
// 0.386050
0x3fd8b509f792ebf0
// -0.296783
0xbfd2fe7f955dbbb7
// 0.866395
0x3febb98209cf8234
// 0.089770
0x3fb6fb238d6d3613
// -0.393146
0xbfd9294f47078aed
// 0.397475
0x3fd9703a8de43cc2
// 1.092584
0x3ff17b3947d96dc5
// -0.760951
0xbfe859b556c68252
// 0.000000
0x3c52800000000000
// 0.000000
0x3c68800000000000
// 0.000000
0x3c79800000000000
// 0.286380
0x3fd2540df3671960
// 0.000000
0x0
// 0.000000
0x3c6ae00000000000
// 0.000000
0x3c65400000000000
// -0.041778
0xbfa563e837455cbd
// 0.000000
0x0
// 0.000000
0x0
// -0.000000
0xbc60000000000000
// -0.362264
0xbfd72f563b5a0626
// 0.284381
0x3fd2334aa55d26c5
// -0.857402
0xbfeb6fd66af6c76c
// -0.229682
0xbfcd663c748a53f2
// 0.287899
0x3fd26cededa09b90
// -0.395585
0xbfd95142a53b44f7
// 0.112956
0x3fbceab636e18f5a
// -0.911457
0xbfed2aa786ab5910
// 0.282420
0x3fd2132afed4e4d9
// 0.003387
0x3f6bbe78fa5d1cd3
// 0.000000
0x3c60400000000000
// -0.000000
0xbca2400000000000
// -0.503397
0xbfe01bd3bc54e0b5
// -0.907326
0xbfed08d193c02bf6
// 0.000000
0x0
// -0.000000
0xbc70000000000000
// -1.000000
0xbfefffffffffffff
// 0.000000
0x3ca0000000000000
// -0.000000
0xbcaa000000000000
// 0.000000
0x3cae000000000000
// 0.778703
0x3fe8eb21b09fbfa9
// -1.000000
0xbff0000000000001
// 0.000000
0x3cac000000000000
// 0.000000
0x3c90000000000000
// 0.276710
0x3fd1b59e315d8ca6
// 0.220653
0x3fcc3e5cb5e9158b
// -1.000000
0xbfeffffffffffffd
// 0.000000
0x0
// 0.094149
0x3fb81a2b3ac81efb
// -0.322146
0xbfd49e0be4172d62
// 0.152850
0x3fc39092ea075bea
// 1.000000
0x3ff0000000000000
// 1.436208
0x3ff6fab508d9279e
// 0.701372
0x3fe671a301de4bbb
// -0.349707
0xbfd66198c448a5bb
// -0.000000
0xbc91000000000000
// -0.501513
0xbfe00c65c1595ef0
// 0.000000
0x0
// -0.074481
0xbfb31135bb78560b
// 0.000000
0x0
// 0.247380
0x3fcfaa251adc060f
// 0.000000
0x0
// -1.000000
0xbff0000000000000
// -0.000000
0xbc90000000000000
// 0.099767
0x3fb98a5202b34f5a
// 1.000000
0x3ff0000000000001
// -0.536297
0xbfe12958ed2d74d2
// 0.195722
0x3fc90d6a95364a17
// 0.528671
0x3fe0eae020138ff2
// 0.148821
0x3fc30c8d9e1be4a2
// 0.243725
0x3fcf3264c47f8c42
// 0.711041
0x3fe6c0da1113bb0f
// 1.000000
0x3ff0000000000000
// 0.000000
0x3cb8000000000000
// -0.097436
0xbfb8f1971bffec97
// 1.000000
0x3feffffffffffffd
// -0.302835
0xbfd361a800e2fd33
// -0.204330
0xbfca277c8b52042b
// 0.054645
0x3fabfa717adaa8c9
// 0.031986
0x3fa060734b42ed53
// 0.380393
0x3fd8585d456e6fc4
// 0.840003
0x3feae14e62bf062f
// -1.000000
0xbff0000000000001
// 0.000000
0x3c82000000000000
// 0.213275
0x3fcb4c9a336ea70c
// 1.000000
0x3ff0000000000000
// 0.654937
0x3fe4f53ee0d468bd
// 0.756210
0x3fe832de7662d634
// -0.178630
0xbfc6dd5a9c05369a
// 0.141949
0x3fc22b6039f15b51
// 0.007258
0x3f7dba0f3fe71253
// 0.488339
0x3fdf40f24b000be9
// -0.130655
0xbfc0b94b03eb162a
// 1.668658
0x3ffab2d2bdb97c12
// -0.614324
0xbfe3a88bccf054ab
// 1.498826
0x3ff7fb30ae33f76e
// -0.200453
0xbfc9a86de179f466
// -0.000000
0xbc60000000000000
// -0.000000
0xbc40000000000000
// -0.000000
0xbc8c000000000000
// 0.360632
0x3fd71499bfd0e5cd
// 0.000000
0x0
// 0.000000
0x3c7c000000000000
// -0.000000
0xbc98000000000000
// 0.176471
0x3fc696975d309bcf
// 0.000000
0x0
// 0.000000
0x0
// -0.000000
0xbc60000000000000
// 0.221767
0x3fcc62e0941cc409
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// -0.893000
0xbfec937425627366
// 0.107023
0x3fbb65dd8023c928
// 0.380150
0x3fd85460bc478262
// -0.215832
0xbfcba06376f82a3a
// -0.212467
0xbfcb321a86ae2311
// -0.243465
0xbfcf29d86cbacb08
// -0.426134
0xbfdb45c604bf6d1e
// -0.871284
0xbfebe18e30f1df25
// -0.126406
0xbfc02e15391bf23b
// -0.112027
0xbfbcadd16c2cf640
// 0.000000
0x3c6e000000000000
// 0.000000
0x3c7f000000000000
// -0.231872
0xbfcdadfd74949ccd
// 0.553856
0x3fe1b92f942b64a3
// 0.000000
0x0
// -0.000000
0xbc94000000000000
// 0.737455
0x3fe7993ae5ae6858
// 0.179819
0x3fc70452d32a9251
// 0.000000
0x0
// 0.000000
0x0
// -1.000000
0xbfeffffffffffffe
// -0.000000
0xbc84000000000000
// 0.000000
0x3c90000000000000
// 0.000000
0x3ca9000000000000
// 0.432956
0x3fdbb58f1bb99107
// 1.000000
0x3ff0000000000001
// 0.000000
0x3cac000000000000
// -0.000000
0xbcc3c00000000000
// -0.244436
0xbfcf49ab77cd059f
// 0.030138
0x3f9edc600553fca0
// -1.000000
0xbff0000000000000
// -0.000000
0xbca0000000000000
// -0.850907
0xbfeb3aa090e1f576
// -0.381389
0xbfd868aceb7ea775
// -0.225587
0xbfcce0056ccbc9c8
// -1.000000
0xbfeffffffffffffd
// -0.150033
0xbfc3344600ab2dc6
// 0.113421
0x3fbd092d0679fdd3
// 0.756024
0x3fe8315a0e878121
// -0.821045
0xbfea460059efd1ee
// -1.000000
0xbff0000000000002
// 0.000000
0x3cb0000000000000
// 0.000000
0x3c98000000000000
// 0.000000
0x3cb8000000000000
// -0.122228
0xbfbf4a572281d91a
// 1.000000
0x3feffffffffffffd
// 0.000000
0x3c91000000000000
// 0.000000
0x3ca5000000000000
// 0.167137
0x3fc564c2e5790064
// 0.008915
0x3f824240b3c74e47
// -1.000000
0xbfeffffffffffffc
// 0.000000
0x0
// 0.475952
0x3fde75fdf1587afe
// -0.754309
0xbfe8234c8cf7e705
// 0.283030
0x3fd21d2bc8e061da
// -1.000000
0xbfeffffffffffffc
// 0.279013
0x3fd1db5ad0207d2b
// -0.034421
0xbfa19fa449527b08
// -0.267138
0xbfd118ca4fef3eef
// 0.517864
0x3fe092578f33cbc3
// 1.011727
0x3ff03008baead983
// -0.847233
0xbfeb1c878cf60675
// 1.351495
0x3ff59fb93285eeed
// 0.024249
0x3f98d4cbf27dfb26
// -0.367819
0xbfd78a5ac432504b
// -0.084092
0xbfb587127b1cbcbb
// 0.000000
0x3c64000000000000
// -0.000000
0xbc68000000000000
// 0.000000
0x3c18000000000000
// 0.000000
0x3c4c000000000000
// 0.327709
0x3fd4f92fbffc6cc1
// 0.000000
0x0
// 0.000000
0x3c94000000000000
// 0.000000
0x3c3c000000000000
// 0.000000
0x3c58000000000000
// 0.012235
0x3f890e77a90abd76
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x3bc0000000000000
// -0.000000
0xbc28000000000000
// 0.186716
0x3fc7e64d0026dfd6
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.658554
0x3fe512e065000b78
// -0.724371
0xbfe72e0d1f1d94d8
// 0.091897
0x3fb78690e804069a
// -0.073218
0xbfb2be6a153d6199
// -0.166692
0xbfc5562b3772faa9
// -0.140819
0xbfc2065d0bd794f5
// 0.100983
0x3fb9da0176bb06f4
// 0.547503
0x3fe185255963f975
// 0.701395
0x3fe671d39e56f1f4
// -0.445071
0xbfdc7c0a4f55a421
// -0.575425
0xbfe269e15f89c7f3
// -0.003574
0xbf6d4652471f8cfa
// -0.000000
0xbcbdda0000000000
// -0.000000
0xbcc4f80000000000
// 0.000000
0x3cbae50000000000
// 0.740910
0x3fe7b58890dfe81a
// -0.398579
0xbfd982533c358bc3
// 0.000000
0x0
// -0.000000
0xbccd000000000000
// 0.000000
0x3cc2c00000000000
// -0.109908
0xbfbc22ef872a5ef0
// -0.313929
0xbfd4176ac6e5ecd6
// 0.000000
0x0
// 0.000000
0x0
// -0.000000
0xbca8000000000000
// -0.795435
0xbfe9743442f99dde
// -0.173597
0xbfc63869ab5dd9d9
// 0.355523
0x3fd6c0e5493a02fb
// 0.231744
0x3fcda9c96eff9bc8
// 0.396289
0x3fd95ccd2dff9e75
// 0.064924
0x3fb09ed4f1eccfb2
// -0.958097
0xbfeea8ba98b750a4
// -0.175388
0xbfc6731a9ede7c97
// -0.114325
0xbfbd445f20996c39
// -0.195498
0xbfc9061704deae3c
// -0.647616
0xbfe4b9446cffca9d
// -0.093667
0xbfb7fa8869820ab0
// -0.790632
0xbfe94cdb5420aa05
// 0.309088
0x3fd3c81aa7de6fe8
// 0.528550
0x3fe0e9e286a9534c
// 0.228974
0x3fcd4f04c109de5d
// 0.269604
0x3fd1413052448a7f
// -0.784228
0xbfe91864bb0781f1
// -0.863233
0xbfeb9f9abc2d4b4c
// 0.504806
0x3fe0275e66a89fe0
// -0.077190
0xbfb3c2b621ab8b6b
// 0.786892
0x3fe92e37714aa2be
// 0.443195
0x3fdc5d4d50eeb0f7
// 0.311324
0x3fd3ecba48c791d1
// 0.000000
0x3cbe000000000000
// -1.000000
0xbff0000000000001
// 0.000000
0x3cb1000000000000
// -0.000000
0xbcae000000000000
// -0.000000
0xbcc3000000000000
// -0.000000
0xbcae000000000000
// -0.277775
0xbfd1c712b6d8d275
// -1.000000
0xbff0000000000000
// -0.000000
0xbcaa000000000000
// -0.000000
0xbca0000000000000
// 0.000000
0x3c90000000000000
// 0.419219
0x3fdad47c7002a75d
// 0.339695
0x3fd5bd903c2f0e5e
// -1.000000
0xbfeffffffffffffc
// 0.000000
0x3ca0000000000000
// 0.000000
0x3cc4000000000000
// -0.485384
0xbfdf1088ac9f9d6e
// -0.891748
0xbfec893219c81aa1
// -0.071731
0xbfb25cfa7c727d11
// 1.000000
0x3ff0000000000002
// 0.000000
0x3c90000000000000
// -0.117802
0xbfbe28494323ffe7
// 0.140126
0x3fc1efa573c8f10c
// 0.477551
0x3fde9030c6e3e685
// -0.562126
0xbfe1fcef26db380a
// -1.000000
0xbff0000000000000
// -2.236068
0xc001e37798040fef
// 0.894427
0x3fec9f25aeda35f6
// -0.236068
0xbfce37799e787897
// -0.447214
0xbfdc9f25923b1037
// -2.645556
0xc0052a190800c4f1
// 0.755857
0x3fe82ffa91bfdccf
// 0.748964
0x3fe7f782ade4f2ef
// 0.748703
0x3fe7f55f61db9632
// -0.215222
0xbfcb8c67de6f0915
// 0.656054
0x3fe4fe649555cbc3
// 0.659776
0x3fe51ce2bdade12a
// 0.660096
0x3fe51f824e17bfe6
// -0.215222
0xbfcb8c67de6f0915
// 0.397732
0x3fd974702c49cea0
// -0.061232
0xbfaf59d7e3fdac5c
// -0.060960
0xbfaf3631aec185eb
// -0.215222
0xbfcb8c67de6f0915
// 0.397732
0x3fd974702c49cea0
// 0.407224
0x3fda0ff6340f47ef
// 0.000973
0x3f4fe49684b9c240
// -2.827225
0xc0069e27eba00810
// 0.692271
0x3fe62714beae3dc9
// 0.692247
0x3fe626e2e77d24f5
// 0.691670
0x3fe62229aeebbdf5
// 0.691621
0x3fe621c1c25c2ebd
// -0.206982
0xbfca7e6469d9877f
// 0.728666
0x3fe7513bd239807a
// 0.707704
0x3fe6a58208f0b8fc
// 0.708344
0x3fe6aac05232f8fa
// 0.708399
0x3fe6ab33ae619aee
// -0.206982
0xbfca7e6469d9877f
// 0.392750
0x3fd922d19c75c05f
// -0.141295
0xbfc215f5bc729f2b
// -0.140750
0xbfc2041763345944
// -0.140719
0xbfc20312f01e177e
// -0.206982
0xbfca7e6469d9877f
// 0.392750
0x3fd922d19c75c05f
// 0.352912
0x3fd6961e2c9471e0
// -0.005568
0xbf76ce373dc950d6
// -0.005504
0xbf768baccdf62a23
// -0.206982
0xbfca7e6469d9877f
// 0.392750
0x3fd922d19c75c05f
// 0.352912
0x3fd6961e2c9471de
// 0.398654
0x3fd9838a2e3cfcd8
// 0.000197
0x3f29c4a1ca65a660

@ -0,0 +1,156 @@
D
77
// 1.242551
0x3ff3e17cbf8fe591
// 0.000000
0x0
// 1.214389
0x3ff36e230b111c2f
// 0.000000
0x0
// 1.363206
0x3ff5cfb0e79597c1
// 0.000000
0x0
// 1.268599
0x3ff44c2e476e3da2
// 1.126311
0x3ff2055ec134345a
// 1.425830
0x3ff6d0336b971dec
// 1.052812
0x3ff0d8513493b0b0
// 1.202787
0x3ff33e9d6258429a
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 1.412375
0x3ff699160df03b98
// 1.096941
0x3ff18d118c78334e
// 0.000000
0x0
// 0.000000
0x0
// 1.182166
0x3ff2ea26875dcb02
// 1.735409
0x3ffbc43c2e43fcd2
// 1.954341
0x3fff44fad38d0917
// 0.000000
0x0
// 1.388354
0x3ff636b2a7759f7e
// 0.000000
0x0
// 1.222148
0x3ff38dea925a8108
// 1.277111
0x3ff46f0be7cbe364
// 1.601424
0x3ff99f6ef8f43a6b
// 1.143917
0x3ff24d7b7a92af5e
// 1.327677
0x3ff53e2a3db29abd
// 1.092611
0x3ff17b55d3e59b6c
// 1.599284
0x3ff996aaca4f3e47
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 1.205745
0x3ff34abbadd22a07
// 1.479683
0x3ff7acc79c2b5c60
// 0.000000
0x0
// 0.000000
0x0
// 1.003134
0x3ff00cd5f95c772d
// 1.725283
0x3ffb9ac24e8eb790
// 1.232694
0x3ff3b91dbbcef8ac
// 1.194661
0x3ff31d54e2e56be4
// 1.484502
0x3ff7c085414c2881
// 1.273686
0x3ff4610413c16a60
// 1.736912
0x3ffbca63f3ddee8b
// 1.577059
0x3ff93ba2850cbf56
// 1.739921
0x3ffbd6b7c7585c3e
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 1.046041
0x3ff0bc957680303a
// 1.590546
0x3ff972e04652c5b1
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 1.349520
0x3ff597a2477ec62d
// 1.176015
0x3ff2d0f56bfe2ef7
// 1.104097
0x3ff1aa61dca61eb6
// 1.823283
0x3ffd2c2abcbf4774
// 0.000000
0x0
// 1.331222
0x3ff54caf722669b8
// 1.036140
0x3ff094073a877ec7
// 1.621797
0x3ff9f2e150214714
// 1.519774
0x3ff850fe4506f010
// 0.000000
0x0
// 1.894427
0x3ffe4f92e5bcade8
// 0.000000
0x0
// 1.755985
0x3ffc18839a0d10ff
// 1.519317
0x3ff84f1f11c0baba
// 1.715514
0x3ffb72be770585ae
// 0.000000
0x0
// 1.707408
0x3ffb518a9302a800
// 1.367280
0x3ff5e061143cc31a
// 1.601160
0x3ff99e59ee4a8652
// 1.725738
0x3ffb9c9f2a71dcc5
// 0.000000
0x0

@ -0,0 +1,12 @@
D
5
// 1.092321
0x3ff17a25b9d7356d
// 1.152027
0x3ff26eb424061df6
// 1.028846
0x3ff076279b0a37e9
// 0.000000
0x0
// 0.000000
0x0

@ -0,0 +1,62 @@
D
30
// 1.000000
0x3ff0000000000000
// -0.900884
0xbfecd409fa5e38e5
// -0.139183
0xbfc1d0c29f9f68cb
// 1.000000
0x3ff0000000000000
// 0.185600
0x3fc7c1c05c0b3ea6
// 0.011106
0x3f86be9a0d3b9634
// 0.153317
0x3fc39fe0c2c3fdcd
// -0.369477
0xbfd7a5825225dd0c
// 0.402847
0x3fd9c83cf1c3ec4e
// 0.551871
0x3fe1a8edef756a5e
// -0.273190
0xbfd17bf2424aa6d6
// 1.000000
0x3ff0000000000000
// -0.009121
0xbf82ae1330e11254
// 0.112010
0x3fbcacaea8fc5248
// 0.453014
0x3fdcfe3033955f11
// 0.122649
0x3fbf65e4ea65fd4b
// -0.514702
0xbfe0786febdaa6ec
// -0.539507
0xbfe143a3cf8eecd8
// 0.139155
0x3fc1cfd84592ef18
// -0.147234
0xbfc2d88cbeef49c7
// -0.315984
0xbfd439170d2f1a09
// -0.118983
0xbfbe75ac8a6e1faf
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0
// 0.000000
0x0

@ -15,6 +15,16 @@ a double precision computation.
/*
Comparisons for QR
*/
#define SNR_QR_THRESHOLD 20
#define REL_QR_ERROR (3.0e-2)
#define ABS_QR_ERROR (3.0e-2)
/*
Comparisons for inverse
*/
@ -153,6 +163,122 @@ Comparison for Cholesky
memcpy((void*)bp,(const void*)inp2,sizeof(float16_t)*internal);
static void checkInnerTailOverflow(float16_t *b)
{
ASSERT_TRUE(b[0] == 0);
ASSERT_TRUE(b[1] == 0);
ASSERT_TRUE(b[2] == 0);
ASSERT_TRUE(b[3] == 0);
ASSERT_TRUE(b[4] == 0);
ASSERT_TRUE(b[5] == 0);
ASSERT_TRUE(b[6] == 0);
ASSERT_TRUE(b[7] == 0);
}
void UnaryTestsF16::test_householder_f16()
{
int16_t vecDim;
const int16_t *dimsp = dims.ptr();
const int nbVectors = dims.nbSamples();
const float16_t *inp1=input1.ptr();
float16_t *outp=output.ptr();
float16_t *outBetap=outputBeta.ptr();
for(int i=0; i < nbVectors ; i++)
{
vecDim = *dimsp++;
float16_t beta = arm_householder_f16(inp1,DEFAULT_HOUSEHOLDER_THRESHOLD_F16,vecDim,outp);
*outBetap = beta;
outp += vecDim;
inp1 += vecDim;
outBetap++;
checkInnerTailOverflow(outp);
checkInnerTailOverflow(outBetap);
}
ASSERT_EMPTY_TAIL(output);
ASSERT_EMPTY_TAIL(outputBeta);
ASSERT_SNR(output,ref,(float16_t)SNR_THRESHOLD);
ASSERT_SNR(outputBeta,refBeta,(float16_t)SNR_THRESHOLD);
ASSERT_CLOSE_ERROR(output,ref,ABS_ERROR,REL_ERROR);
ASSERT_CLOSE_ERROR(outputBeta,refBeta,ABS_ERROR,REL_ERROR);
}
void UnaryTestsF16::test_mat_qr_f16()
{
int16_t rows, columns, rank;
const int16_t *dimsp = dims.ptr();
const int nbMatrixes = dims.nbSamples() / 3;
const float16_t *inp1=input1.ptr();
float16_t *outTaup=outputTau.ptr();
float16_t *outRp=outputR.ptr();
float16_t *outQp=outputQ.ptr();
float16_t *pTmpA=a.ptr();
float16_t *pTmpB=b.ptr();
(void) outTaup;
(void) outRp;
for(int i=0; i < nbMatrixes ; i++)
{
rows = *dimsp++;
columns = *dimsp++;
rank = *dimsp++;
(void)rank;
in1.numRows=rows;
in1.numCols=columns;
in1.pData = (float16_t*)inp1;
outR.numRows = rows;
outR.numCols = columns;
outR.pData = (float16_t*)outRp;
outQ.numRows = rows;
outQ.numCols = rows;
outQ.pData = (float16_t*)outQp;
arm_status status=arm_mat_qr_f16(&in1,DEFAULT_HOUSEHOLDER_THRESHOLD_F16,&outR,&outQ,outTaup,pTmpA,pTmpB);
ASSERT_TRUE(status==ARM_MATH_SUCCESS);
inp1 += rows * columns;
outRp += rows * columns;
outQp += rows * rows;
outTaup += columns;
checkInnerTailOverflow(outRp);
checkInnerTailOverflow(outQp);
checkInnerTailOverflow(outTaup);
}
ASSERT_EMPTY_TAIL(outputR);
ASSERT_EMPTY_TAIL(outputQ);
ASSERT_EMPTY_TAIL(outputTau);
//ASSERT_SNR(refQ,outputQ,(float16_t)SNR_QR_THRESHOLD);
//ASSERT_SNR(refR,outputR,(float16_t)SNR_QR_THRESHOLD);
//ASSERT_SNR(refTau,outputTau,(float16_t)SNR_QR_THRESHOLD);
ASSERT_CLOSE_ERROR(refQ,outputQ,ABS_QR_ERROR,REL_QR_ERROR);
ASSERT_CLOSE_ERROR(refR,outputR,ABS_QR_ERROR,REL_QR_ERROR);
ASSERT_CLOSE_ERROR(refTau,outputTau,ABS_QR_ERROR,REL_QR_ERROR);
}
void UnaryTestsF16::test_mat_vec_mult_f16()
{
@ -602,6 +728,34 @@ void UnaryTestsF16::test_mat_inverse_f16()
a.create(MAXMATRIXDIM*MAXMATRIXDIM,UnaryTestsF16::TMPA_F16_ID,mgr);
b.create(MAXMATRIXDIM*MAXMATRIXDIM,UnaryTestsF16::TMPB_F16_ID,mgr);
break;
case TEST_HOUSEHOLDER_F16_11:
input1.reload(UnaryTestsF16::INPUTS_HOUSEHOLDER_F16_ID,mgr);
dims.reload(UnaryTestsF16::DIMS_HOUSEHOLDER_S16_ID,mgr);
ref.reload(UnaryTestsF16::REF_HOUSEHOLDER_V_F16_ID,mgr);
refBeta.reload(UnaryTestsF16::REF_HOUSEHOLDER_BETA_F16_ID,mgr);
output.create(ref.nbSamples(),UnaryTestsF16::TMPA_F16_ID,mgr);
outputBeta.create(refBeta.nbSamples(),UnaryTestsF16::TMPB_F16_ID,mgr);
break;
case TEST_MAT_QR_F16_12:
input1.reload(UnaryTestsF16::INPUTS_QR_F16_ID,mgr);
dims.reload(UnaryTestsF16::DIMS_QR_S16_ID,mgr);
refTau.reload(UnaryTestsF16::REF_QR_TAU_F16_ID,mgr);
refR.reload(UnaryTestsF16::REF_QR_R_F16_ID,mgr);
refQ.reload(UnaryTestsF16::REF_QR_Q_F16_ID,mgr);
outputTau.create(refTau.nbSamples(),UnaryTestsF16::TMPA_F16_ID,mgr);
outputR.create(refR.nbSamples(),UnaryTestsF16::TMPB_F16_ID,mgr);
outputQ.create(refQ.nbSamples(),UnaryTestsF16::TMPC_F16_ID,mgr);
a.create(47,UnaryTestsF16::TMPC_F16_ID,mgr);
b.create(47,UnaryTestsF16::TMPD_F16_ID,mgr);
break;
}

@ -15,6 +15,24 @@ a double precision computation.
/*
Comparisons for Householder
*/
#define SNR_HOUSEHOLDER_THRESHOLD 140
#define REL_HOUSEHOLDER_ERROR (1.0e-7)
#define ABS_HOUSEHOLDER_ERROR (1.0e-7)
/*
Comparisons for QR decomposition
*/
#define SNR_QR_THRESHOLD 90
#define REL_QR_ERROR (1.0e-4)
#define ABS_QR_ERROR (2.0e-4)
/*
Comparisons for inverse
*/
@ -185,6 +203,119 @@ static void checkInnerTailOverflow(float32_t *b)
A[j*n + w] = tmp; \
}
void UnaryTestsF32::test_householder_f32()
{
int32_t vecDim;
const int16_t *dimsp = dims.ptr();
const int nbVectors = dims.nbSamples();
const float32_t *inp1=input1.ptr();
float32_t *outp=output.ptr();
float32_t *outBetap=outputBeta.ptr();
for(int i=0; i < nbVectors ; i++)
{
vecDim = *dimsp++;
float32_t beta = arm_householder_f32(inp1,DEFAULT_HOUSEHOLDER_THRESHOLD_F32,vecDim,outp);
*outBetap = beta;
outp += vecDim;
inp1 += vecDim;
outBetap++;
checkInnerTailOverflow(outp);
checkInnerTailOverflow(outBetap);
}
ASSERT_EMPTY_TAIL(output);
ASSERT_EMPTY_TAIL(outputBeta);
ASSERT_SNR(output,ref,(float32_t)SNR_HOUSEHOLDER_THRESHOLD);
ASSERT_SNR(outputBeta,refBeta,(float32_t)SNR_HOUSEHOLDER_THRESHOLD);
ASSERT_CLOSE_ERROR(output,ref,ABS_HOUSEHOLDER_ERROR,REL_HOUSEHOLDER_ERROR);
ASSERT_CLOSE_ERROR(outputBeta,refBeta,ABS_HOUSEHOLDER_ERROR,REL_HOUSEHOLDER_ERROR);
}
void UnaryTestsF32::test_mat_qr_f32()
{
int32_t rows, columns, rank;
int nb;
const int16_t *dimsp = dims.ptr();
const int nbMatrixes = dims.nbSamples() / 3;
const float32_t *inp1=input1.ptr();
float32_t *outTaup=outputTau.ptr();
float32_t *outRp=outputR.ptr();
float32_t *outQp=outputQ.ptr();
float32_t *pTmpA=a.ptr();
float32_t *pTmpB=b.ptr();
(void) outTaup;
(void) outRp;
(void) outQp;
(void)nbMatrixes;
(void)nb;
nb=0;
for(int i=0; i < nbMatrixes ; i++)
//for(int i=0; i < 1 ; i++)
{
rows = *dimsp++;
columns = *dimsp++;
rank = *dimsp++;
(void)rank;
//printf("--> %d %d\n",nb,i);
nb += rows * columns;
in1.numRows=rows;
in1.numCols=columns;
in1.pData = (float32_t*)inp1;
outR.numRows = rows;
outR.numCols = columns;
outR.pData = (float32_t*)outRp;
outQ.numRows = rows;
outQ.numCols = rows;
outQ.pData = (float32_t*)outQp;
arm_status status=arm_mat_qr_f32(&in1,DEFAULT_HOUSEHOLDER_THRESHOLD_F32,&outR,&outQ,outTaup,pTmpA,pTmpB);
ASSERT_TRUE(status==ARM_MATH_SUCCESS);
inp1 += rows * columns;
outRp += rows * columns;
outQp += rows * rows;
outTaup += columns;
checkInnerTailOverflow(outRp);
checkInnerTailOverflow(outQp);
checkInnerTailOverflow(outTaup);
}
ASSERT_EMPTY_TAIL(outputR);
ASSERT_EMPTY_TAIL(outputQ);
ASSERT_EMPTY_TAIL(outputTau);
ASSERT_SNR(refQ,outputQ,(float32_t)SNR_QR_THRESHOLD);
ASSERT_SNR(refR,outputR,(float32_t)SNR_QR_THRESHOLD);
ASSERT_SNR(refTau,outputTau,(float32_t)SNR_QR_THRESHOLD);
ASSERT_CLOSE_ERROR(refQ,outputQ,ABS_QR_ERROR,REL_QR_ERROR);
ASSERT_CLOSE_ERROR(refR,outputR,ABS_QR_ERROR,REL_QR_ERROR);
ASSERT_CLOSE_ERROR(refTau,outputTau,ABS_QR_ERROR,REL_QR_ERROR);
}
void UnaryTestsF32::test_mat_vec_mult_f32()
{
@ -870,6 +1001,35 @@ void UnaryTestsF32::test_mat_inverse_f32()
break;
case TEST_HOUSEHOLDER_F32_13:
input1.reload(UnaryTestsF32::INPUTS_HOUSEHOLDER_F32_ID,mgr);
dims.reload(UnaryTestsF32::DIMS_HOUSEHOLDER_S16_ID,mgr);
ref.reload(UnaryTestsF32::REF_HOUSEHOLDER_V_F32_ID,mgr);
refBeta.reload(UnaryTestsF32::REF_HOUSEHOLDER_BETA_F32_ID,mgr);
output.create(ref.nbSamples(),UnaryTestsF32::TMPA_F32_ID,mgr);
outputBeta.create(refBeta.nbSamples(),UnaryTestsF32::TMPB_F32_ID,mgr);
break;
case TEST_MAT_QR_F32_14:
input1.reload(UnaryTestsF32::INPUTS_QR_F32_ID,mgr);
dims.reload(UnaryTestsF32::DIMS_QR_S16_ID,mgr);
refTau.reload(UnaryTestsF32::REF_QR_TAU_F32_ID,mgr);
refR.reload(UnaryTestsF32::REF_QR_R_F32_ID,mgr);
refQ.reload(UnaryTestsF32::REF_QR_Q_F32_ID,mgr);
outputTau.create(refTau.nbSamples(),UnaryTestsF32::TMPA_F32_ID,mgr);
outputR.create(refR.nbSamples(),UnaryTestsF32::TMPB_F32_ID,mgr);
outputQ.create(refQ.nbSamples(),UnaryTestsF32::TMPC_F32_ID,mgr);
a.create(47,UnaryTestsF32::TMPC_F32_ID,mgr);
b.create(47,UnaryTestsF32::TMPD_F32_ID,mgr);
break;
}
@ -886,6 +1046,9 @@ void UnaryTestsF32::test_mat_inverse_f32()
case TEST_MAT_LDL_F32_11:
//outputll.dump(mgr);
break;
case TEST_MAT_QR_F32_14:
//outputR.dump(mgr);
break;
}
//output.dump(mgr);
}

@ -1,7 +1,7 @@
#include "UnaryTestsF64.h"
#include "Error.h"
#define SNR_THRESHOLD 120
#define SNR_THRESHOLD 250
/*
@ -9,8 +9,26 @@ Reference patterns are generated with
a double precision computation.
*/
#define REL_ERROR (1.0e-6)
#define ABS_ERROR (1.0e-5)
#define REL_ERROR (1.0e-12)
#define ABS_ERROR (1.0e-12)
/*
Comparisons for householder
*/
#define SNR_HOUSEHOLDER_THRESHOLD 270
#define REL_HOUSEHOLDER_ERROR (1.0e-13)
#define ABS_HOUSEHOLDER_ERROR (1.0e-13)
/*
Comparison for QR decomposition
*/
#define SNR_QR_THRESHOLD 270
#define REL_QR_ERROR (1.0e-13)
#define ABS_QR_ERROR (1.0e-13)
/*
@ -121,6 +139,11 @@ Comparison for Cholesky
A[j*n + w] = tmp; \
}
static void checkInnerTailOverflow(float64_t *b)
{
ASSERT_TRUE(b[0] == 0);
ASSERT_TRUE(b[1] == 0);
}
void UnaryTestsF64::test_mat_add_f64()
@ -128,6 +151,140 @@ void UnaryTestsF64::test_mat_add_f64()
}
void UnaryTestsF64::test_householder_f64()
{
int64_t vecDim;
const int16_t *dimsp = dims.ptr();
const int nbVectors = dims.nbSamples();
const float64_t *inp1=input1.ptr();
float64_t *outp=output.ptr();
float64_t *outBetap=outputBeta.ptr();
for(int i=0; i < nbVectors ; i++)
{
vecDim = *dimsp++;
float64_t beta = arm_householder_f64(inp1,DEFAULT_HOUSEHOLDER_THRESHOLD_F64,vecDim,outp);
*outBetap = beta;
outp += vecDim;
inp1 += vecDim;
outBetap++;
checkInnerTailOverflow(outp);
checkInnerTailOverflow(outBetap);
}
ASSERT_EMPTY_TAIL(output);
ASSERT_EMPTY_TAIL(outputBeta);
ASSERT_SNR(output,ref,(float64_t)SNR_HOUSEHOLDER_THRESHOLD);
ASSERT_SNR(outputBeta,refBeta,(float64_t)SNR_HOUSEHOLDER_THRESHOLD);
ASSERT_CLOSE_ERROR(output,ref,ABS_HOUSEHOLDER_ERROR,REL_HOUSEHOLDER_ERROR);
ASSERT_CLOSE_ERROR(outputBeta,refBeta,ABS_HOUSEHOLDER_ERROR,REL_HOUSEHOLDER_ERROR);
}
#include "dsp/debug.h"
void UnaryTestsF64::test_mat_qr_f64()
{
int64_t rows, columns, rank;
int nb;
const int16_t *dimsp = dims.ptr();
const int nbMatrixes = dims.nbSamples() / 3;
const float64_t *inp1=input1.ptr();
float64_t *outTaup=outputTau.ptr();
float64_t *outRp=outputR.ptr();
float64_t *outQp=outputQ.ptr();
float64_t *pTmpA=a.ptr();
float64_t *pTmpB=b.ptr();
(void) outTaup;
(void) outRp;
(void) outQp;
(void)nbMatrixes;
(void)nb;
(void)dimsp;
(void)inp1;
nb=0;
for(int i=0; i < nbMatrixes ; i++)
//for(int i=0; i < 1 ; i++)
{
rows = *dimsp++;
columns = *dimsp++;
rank = *dimsp++;
(void)rank;
//printf("--> %d %d : %lld %lld\n",nb,i,rows,columns);
nb += rows * columns;
in1.numRows=rows;
in1.numCols=columns;
in1.pData = (float64_t*)inp1;
outR.numRows = rows;
outR.numCols = columns;
outR.pData = (float64_t*)outRp;
outQ.numRows = rows;
outQ.numCols = rows;
outQ.pData = (float64_t*)outQp;
arm_status status=arm_mat_qr_f64(&in1,DEFAULT_HOUSEHOLDER_THRESHOLD_F64,&outR,&outQ,outTaup,pTmpA,pTmpB);
ASSERT_TRUE(status==ARM_MATH_SUCCESS);
// Set Householder reflectors into R matrix to 0
//float64_t *p = outRp ;
//printf("%d %d %d\n",in1.numCols, outR.numRows,outR.numCols);
#if 0
for(int col=0 ; col < in1.numCols; col++)
{
float64_t *pa = p + outR.numCols;
for(int k=0;k<outR.numRows-col-1; k++)
{
*pa = 0;
pa += outR.numCols;
}
p += 1 + outR.numCols;
}
#endif
//PM_f64("Corrected R",&outR);
inp1 += rows * columns;
outRp += rows * columns;
outQp += rows * rows;
outTaup += columns;
checkInnerTailOverflow(outRp);
checkInnerTailOverflow(outQp);
checkInnerTailOverflow(outTaup);
}
ASSERT_EMPTY_TAIL(outputR);
ASSERT_EMPTY_TAIL(outputQ);
ASSERT_EMPTY_TAIL(outputTau);
ASSERT_SNR(refQ,outputQ,(float64_t)SNR_QR_THRESHOLD);
ASSERT_SNR(refR,outputR,(float64_t)SNR_QR_THRESHOLD);
ASSERT_SNR(refTau,outputTau,(float64_t)SNR_QR_THRESHOLD);
ASSERT_CLOSE_ERROR(refQ,outputQ,ABS_QR_ERROR,REL_QR_ERROR);
ASSERT_CLOSE_ERROR(refR,outputR,ABS_QR_ERROR,REL_QR_ERROR);
ASSERT_CLOSE_ERROR(refTau,outputTau,ABS_QR_ERROR,REL_QR_ERROR);
}
void UnaryTestsF64::test_mat_sub_f64()
{
LOADDATA2();
@ -615,6 +772,34 @@ void UnaryTestsF64::test_mat_inverse_f64()
break;
case TEST_HOUSEHOLDER_F64_11:
input1.reload(UnaryTestsF64::INPUTS_HOUSEHOLDER_F64_ID,mgr);
dims.reload(UnaryTestsF64::DIMS_HOUSEHOLDER_S16_ID,mgr);
ref.reload(UnaryTestsF64::REF_HOUSEHOLDER_V_F64_ID,mgr);
refBeta.reload(UnaryTestsF64::REF_HOUSEHOLDER_BETA_F64_ID,mgr);
output.create(ref.nbSamples(),UnaryTestsF64::TMPA_F64_ID,mgr);
outputBeta.create(refBeta.nbSamples(),UnaryTestsF64::TMPB_F64_ID,mgr);
break;
case TEST_MAT_QR_F64_12:
input1.reload(UnaryTestsF64::INPUTS_QR_F64_ID,mgr);
dims.reload(UnaryTestsF64::DIMS_QR_S16_ID,mgr);
refTau.reload(UnaryTestsF64::REF_QR_TAU_F64_ID,mgr);
refR.reload(UnaryTestsF64::REF_QR_R_F64_ID,mgr);
refQ.reload(UnaryTestsF64::REF_QR_Q_F64_ID,mgr);
outputTau.create(refTau.nbSamples(),UnaryTestsF64::TMPA_F64_ID,mgr);
outputR.create(refR.nbSamples(),UnaryTestsF64::TMPB_F64_ID,mgr);
outputQ.create(refQ.nbSamples(),UnaryTestsF64::TMPC_F64_ID,mgr);
a.create(47,UnaryTestsF64::TMPC_F64_ID,mgr);
b.create(47,UnaryTestsF64::TMPD_F64_ID,mgr);
break;
}

@ -3282,7 +3282,7 @@ group Root {
Pattern INPUTSINV_F32_ID : InputInvert1_f32.txt
Pattern DIMSUNARY1_S16_ID : DimsUnary1_s16.txt
Pattern DIMSINVERT1_S16_ID : DimsInvert1_s16.txt
Pattern REFADD1_F32_ID : RefAdd1_f32.txt
Pattern REFSUB1_F32_ID : RefSub1_f32.txt
Pattern REFSCALE1_F32_ID : RefScale1_f32.txt
@ -3321,6 +3321,17 @@ group Root {
Pattern REF_LT_SOLVE_F32_ID : RefLTSolve1_f32.txt
Pattern REF_UT_SOLVE_F32_ID : RefUTSolve1_f32.txt
Pattern INPUTS_QR_F32_ID : InputMatrixQR1_f32.txt
Pattern DIMS_QR_S16_ID : DimsQR1_s16.txt
Pattern REF_QR_TAU_F32_ID : RefTau1_f32.txt
Pattern REF_QR_R_F32_ID : RefR1_f32.txt
Pattern REF_QR_Q_F32_ID : RefQ1_f32.txt
Pattern INPUTS_HOUSEHOLDER_F32_ID : InputVectorHouseHolder1_f32.txt
Pattern DIMS_HOUSEHOLDER_S16_ID : DimsHouseholder1_s16.txt
Pattern REF_HOUSEHOLDER_V_F32_ID : RefVectorHouseholder1_f32.txt
Pattern REF_HOUSEHOLDER_BETA_F32_ID : RefValueHouseholder1_f32.txt
Output D_F32_ID : Output
Output LL_F32_ID : Output
@ -3351,6 +3362,8 @@ group Root {
test solve lower triangular:test_solve_lower_triangular_f32
test matrix LDL decomposition DPO:test_mat_ldl_f32
test matrix LDL decomposition SDPO:test_mat_ldl_f32
test householder:test_householder_f32
test QR decomposition:test_mat_qr_f32
}
}
@ -3505,6 +3518,18 @@ group Root {
Pattern REF_LT_SOLVE_F64_ID : RefLTSolve1_f64.txt
Pattern REF_UT_SOLVE_F64_ID : RefUTSolve1_f64.txt
Pattern INPUTS_QR_F64_ID : InputMatrixQR1_f64.txt
Pattern DIMS_QR_S16_ID : DimsQR1_s16.txt
Pattern REF_QR_TAU_F64_ID : RefTau1_f64.txt
Pattern REF_QR_R_F64_ID : RefR1_f64.txt
Pattern REF_QR_Q_F64_ID : RefQ1_f64.txt
Pattern INPUTS_HOUSEHOLDER_F64_ID : InputVectorHouseHolder1_f64.txt
Pattern DIMS_HOUSEHOLDER_S16_ID : DimsHouseholder1_s16.txt
Pattern REF_HOUSEHOLDER_V_F64_ID : RefVectorHouseholder1_f64.txt
Pattern REF_HOUSEHOLDER_BETA_F64_ID : RefValueHouseholder1_f64.txt
Output D_F64_ID : Output
Output LL_F64_ID : Output
Output PERM_S16_ID : Output
@ -3533,6 +3558,8 @@ group Root {
test solve lower triangular:test_solve_lower_triangular_f64
test matrix LDL decomposition DPO:test_mat_ldl_f64
test matrix LDL decomposition SDPO:test_mat_ldl_f64
test householder:test_householder_f64
test QR decomposition:test_mat_qr_f64
}
}

@ -827,6 +827,18 @@ group Root {
Pattern REF_LT_SOLVE_F16_ID : RefLTSolve1_f16.txt
Pattern REF_UT_SOLVE_F16_ID : RefUTSolve1_f16.txt
Pattern INPUTS_QR_F16_ID : InputMatrixQR1_f16.txt
Pattern DIMS_QR_S16_ID : DimsQR1_s16.txt
Pattern REF_QR_TAU_F16_ID : RefTau1_f16.txt
Pattern REF_QR_R_F16_ID : RefR1_f16.txt
Pattern REF_QR_Q_F16_ID : RefQ1_f16.txt
Pattern INPUTS_HOUSEHOLDER_F16_ID : InputVectorHouseHolder1_f16.txt
Pattern DIMS_HOUSEHOLDER_S16_ID : DimsHouseholder1_s16.txt
Pattern REF_HOUSEHOLDER_V_F16_ID : RefVectorHouseholder1_f16.txt
Pattern REF_HOUSEHOLDER_BETA_F16_ID : RefValueHouseholder1_f16.txt
Output D_F16_ID : Output
Output LL_F16_ID : Output
Output PERM_S16_ID : Output
@ -834,6 +846,8 @@ group Root {
Output OUT_F16_ID : Output
Output TMPA_F16_ID : TmpA
Output TMPB_F16_ID : TmpB
Output TMPC_F16_ID : TmpC
Output TMPD_F16_ID : TmpD
Functions {
test matrix add:test_mat_add_f16
@ -846,6 +860,8 @@ group Root {
test matrix cholesky decomposition:test_mat_cholesky_dpo_f16
test solve upper triangular:test_solve_upper_triangular_f16
test solve lower triangular:test_solve_lower_triangular_f16
test householder:test_householder_f16
test QR decomposition:test_mat_qr_f16
}
}

@ -19,7 +19,7 @@ from cmsisdsp_svm import *
__version__ = cmsisdsp.version.__version__
# CMSIS-DSP Version used to build the wrapper
cmsis_dsp_version="1.10.0"
cmsis_dsp_version="1.10.2"
# CMSIS-DSP Commit hash used to build the wrapper
@ -29,4 +29,8 @@ commit_hash="d9cfca31b66fe837a603ed3520cb6a7947e86ca6"
# (So several CMSIS-DSP versions may have same version number hence the commit hash)
developmentVersion=True
__all__ = ["datatype", "fixedpoint", "mfcc"]
__all__ = ["datatype", "fixedpoint", "mfcc"]
# Default values
DEFAULT_HOUSEHOLDER_THRESHOLD_F64=1.0e-16
DEFAULT_HOUSEHOLDER_THRESHOLD_F32=1.0e-12

@ -1 +1 @@
__version__ = "1.4.0"
__version__ = "1.5.0"

@ -132,7 +132,7 @@ interpolationMod = interpolation + common
filteringMod = filtering + common + support + fastmath + basic
controllerMod = controller + common
matrixMod = matrix
matrixMod = matrix + basic
supportMod = support
complexfMod = complexf + fastmath + common + basic
basicMod = basic
@ -243,7 +243,12 @@ def build():
setup (name = 'cmsisdsp',
version = main_ns['__version__'],
packages=["cmsisdsp","cmsisdsp.sdf","cmsisdsp.sdf.nodes","cmsisdsp.sdf.nodes.host","cmsisdsp.sdf.scheduler"],
packages=["cmsisdsp",
"cmsisdsp.sdf",
"cmsisdsp.sdf.nodes",
"cmsisdsp.sdf.nodes.host",
"cmsisdsp.sdf.scheduler",
"cmsisdsp.sdf.scheduler.templates"],
description = 'CMSIS-DSP Python API',
long_description=open("PythonWrapper_README.md").read(),
long_description_content_type='text/markdown',
@ -281,7 +286,7 @@ def build():
"Environment :: Console",
"Intended Audience :: Developers",
],
keywords=['development','dsp','cmsis','cmsis-dsp','Arm','signal processing','maths'],
keywords=['development','dsp','cmsis','cmsis-dsp','Arm','signal processing','maths','ml','cortex-m','cortex-a'],
install_requires=['numpy>=1.19',
'networkx>=2.5',
'jinja2>= 2.0, <3.0',
@ -289,8 +294,8 @@ def build():
'markupsafe<2.1'
],
project_urls={ # Optional
'Bug Reports': 'https://github.com/ARM-software/CMSIS_5/issues',
'Source': 'https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DSP',
'Bug Reports': 'https://github.com/ARM-software/CMSIS-DSP/issues',
'Source': 'https://github.com/ARM-software/CMSIS-DSP',
}
)

Loading…
Cancel
Save