/*
 * Copyright (C) 1996-2011 Daniel Waggoner
 *
 * This free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * It is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * If you did not received a copy of the GNU General Public License
 * with this software, see <http://www.gnu.org/licenses/>.
 */

#ifndef __MATRIX_ARRAY__
#define __MATRIX_ARRAY__

#include "dw_matrix.h"
#include "dw_array.h"

#ifdef __cplusplus
extern "C"
{
#endif

extern TElementSpecification dw_VectorSpecs;
extern TElementSpecification dw_MatrixSpecs;

#define dw_CreateArray_vector(dim)     (TVector*)dw_CreateArray(&dw_VectorSpecs,dim)
#define dw_CreateMultidimensionalArray_vector(depth,dim) (void*)dw_CreateMultidimensionalArray(&dw_VectorSpecs,depth,dim);
void* dw_CreateMultidimensionalArrayList_vector(int depth, ...);
#define dw_CreateRectangularArray_vector(row,col) (TVector**)dw_CreateMultidimensionalArrayList_vector(2,row,col)
void* dw_InitializeArray_vector(void* x, PRECISION y);

#define dw_CreateArray_matrix(dim)     (TMatrix*)dw_CreateArray(&dw_MatrixSpecs,dim)
#define dw_CreateMultidimensionalArray_matrix(depth,dim) (void*)dw_CreateMultidimensionalArray(&dw_MatrixSpecs,depth,dim);
void* dw_CreateMultidimensionalArrayList_matrix(int depth, ...);
#define dw_CreateRectangularArray_matrix(row,col) (TMatrix**)dw_CreateMultidimensionalArrayList_matrix(2,row,col)
void* dw_InitializeArray_matrix(void* X, PRECISION y);

#if (PRECISION_SIZE == 8)
  #define dw_CreateArray_scalar(dim)     (double*)dw_CreateArray(&dw_DoubleSpecs,dim)
  #define dw_CreateMultidimensionalArray_scalar(depth,dim) dw_CreateMultidimensionalArray(&dw_DoubleSpecs,depth,dim) 
  #define dw_CreateMultidimensionalArrayList_scalar  dw_CreateMultidimensionalArrayList_double
  #define dw_CreateRectangularArray_scalar(row,col) (double**)dw_CreateMultidimensionalArrayList_double(2,row,col)
  #define dw_InitializeArray_scalar(a,x)  dw_InitializeArray_double(a,x)
#else
  #define dw_CreateArray_scalar(dim) (float*)dw_CreateArray(&dw_FloatSpecs,dim)
  #define dw_CreateMultidimensionalArray_scalar(depth,dim) dw_CreateMultidimensionalArray(&dw_FloatSpecs,depth,dim)
  #define dw_CreateMultidimensionalArrayList_scalar  dw_CreateMultidimensionalArrayList_float
  #define dw_CreateRectangularArray_scalar(row,col) (float**)dw_CreateMultidimensionalArrayList_float(2,row,col)
  #define dw_InitializeArray_scalar(a,x)  dw_InitializeArray_float(a,x)
#endif

/* Tensor Calculus */
TMatrix MatrixTensor(TMatrix X, TMatrix* Y);
TVector VectorTensor(TVector x, TVector* y);

#ifdef __cplusplus
}
#endif

#endif
