#include "fmpz.h"
#include "fmpq.h"
#include "gr.h"
#include "gr_mat.h"
static void
_gr_mat_resize(gr_mat_t mat, slong r, slong c, gr_ctx_t ctx)
{
gr_mat_clear(mat, ctx);
gr_mat_init(mat, r, c, ctx);
}
int
_gr_mat_check_resize(gr_mat_t mat, slong r, slong c, gr_ctx_t ctx)
{
if (MATRIX_CTX(ctx)->all_sizes)
{
_gr_mat_resize(mat, r, c, MATRIX_CTX(ctx)->base_ring);
return GR_SUCCESS;
}
else
{
if (r != MATRIX_CTX(ctx)->nrows || c != MATRIX_CTX(ctx)->ncols)
return GR_DOMAIN;
if (mat->r != r || mat->c != c)
_gr_mat_resize(mat, r, c, MATRIX_CTX(ctx)->base_ring);
return GR_SUCCESS;
}
}
static void
matrix_init(gr_mat_t res, gr_ctx_t ctx)
{
gr_mat_init(res, MATRIX_CTX(ctx)->nrows, MATRIX_CTX(ctx)->ncols, MATRIX_CTX(ctx)->base_ring);
}
static int
matrix_ctx_write(gr_stream_t out, gr_ctx_t ctx)
{
gr_ctx_ptr elem_ctx = MATRIX_CTX(ctx)->base_ring;
if (MATRIX_CTX(ctx)->all_sizes)
{
gr_stream_write(out, "Matrices (any shape) over ");
}
else
{
if (gr_ctx_is_ring(ctx) == T_TRUE)
gr_stream_write(out, "Ring of ");
else
gr_stream_write(out, "Space of ");
gr_stream_write_si(out, MATRIX_CTX(ctx)->nrows);
gr_stream_write(out, " x ");
gr_stream_write_si(out, MATRIX_CTX(ctx)->ncols);
gr_stream_write(out, " ");
gr_stream_write(out, "matrices over ");
}
gr_ctx_write(out, elem_ctx);
return GR_SUCCESS;
}
static truth_t matrix_ctx_is_ring(gr_ctx_t ctx)
{
int shape_ok = (!MATRIX_CTX(ctx)->all_sizes && MATRIX_CTX(ctx)->nrows == MATRIX_CTX(ctx)->ncols);
if (!shape_ok)
return T_FALSE;
if (MATRIX_CTX(ctx)->nrows == 0)
return T_TRUE;
return gr_ctx_is_ring(MATRIX_CTX(ctx)->base_ring);
}
static truth_t matrix_ctx_is_commutative_ring(gr_ctx_t ctx)
{
int shape_ok = (!MATRIX_CTX(ctx)->all_sizes && MATRIX_CTX(ctx)->nrows == MATRIX_CTX(ctx)->ncols);
if (!shape_ok)
return T_FALSE;
if (MATRIX_CTX(ctx)->nrows == 0)
return T_TRUE;
if (MATRIX_CTX(ctx)->nrows == 1)
return gr_ctx_is_commutative_ring(MATRIX_CTX(ctx)->base_ring);
return gr_ctx_is_zero_ring(MATRIX_CTX(ctx)->base_ring);
}
static truth_t matrix_ctx_is_rational_vector_space(gr_ctx_t ctx)
{
if (MATRIX_CTX(ctx)->all_sizes)
return T_FALSE;
if (MATRIX_CTX(ctx)->nrows == 0 || MATRIX_CTX(ctx)->ncols == 0)
return T_TRUE;
return gr_ctx_is_rational_vector_space(MATRIX_CTX(ctx)->base_ring);
}
static truth_t matrix_ctx_is_real_vector_space(gr_ctx_t ctx)
{
if (MATRIX_CTX(ctx)->all_sizes)
return T_FALSE;
if (MATRIX_CTX(ctx)->nrows == 0 || MATRIX_CTX(ctx)->ncols == 0)
return T_TRUE;
return gr_ctx_is_real_vector_space(MATRIX_CTX(ctx)->base_ring);
}
static truth_t matrix_ctx_is_complex_vector_space(gr_ctx_t ctx)
{
if (MATRIX_CTX(ctx)->all_sizes)
return T_FALSE;
if (MATRIX_CTX(ctx)->nrows == 0 || MATRIX_CTX(ctx)->ncols == 0)
return T_TRUE;
return gr_ctx_is_complex_vector_space(MATRIX_CTX(ctx)->base_ring);
}
static truth_t matrix_ctx_is_approx_commutative_ring(gr_ctx_t ctx)
{
int shape_ok = (!MATRIX_CTX(ctx)->all_sizes && MATRIX_CTX(ctx)->nrows == MATRIX_CTX(ctx)->ncols);
if (!shape_ok)
return T_FALSE;
if (MATRIX_CTX(ctx)->nrows == 0)
return T_TRUE;
if (MATRIX_CTX(ctx)->nrows == 1)
return gr_ctx_is_approx_commutative_ring(MATRIX_CTX(ctx)->base_ring);
if (gr_ctx_is_zero_ring(MATRIX_CTX(ctx)->base_ring) == T_TRUE)
return T_TRUE;
return T_UNKNOWN;
}
truth_t gr_ctx_matrix_is_fixed_size(gr_ctx_t ctx)
{
return (MATRIX_CTX(ctx)->all_sizes) ? T_FALSE : T_TRUE;
}
static truth_t
matrix_ctx_is_threadsafe(gr_ctx_t ctx)
{
return gr_ctx_is_threadsafe(MATRIX_CTX(ctx)->base_ring);
}
static gr_ptr matrix_ctx_base(gr_ctx_t ctx) { return MATRIX_CTX(ctx)->base_ring; }
static void
matrix_clear(gr_mat_t res, gr_ctx_t ctx)
{
gr_mat_clear(res, MATRIX_CTX(ctx)->base_ring);
}
static void
matrix_swap(gr_mat_t mat1, gr_mat_t mat2, gr_ctx_t ctx)
{
gr_mat_swap(mat1, mat2, MATRIX_CTX(ctx)->base_ring);
}
static void
matrix_set_shallow(gr_mat_t res, const gr_mat_t mat, gr_ctx_t ctx)
{
*res = *mat;
}
static int
matrix_write(gr_stream_t out, gr_mat_t mat, gr_ctx_t ctx)
{
return gr_mat_write(out, mat, MATRIX_CTX(ctx)->base_ring);
}
static int
matrix_randtest(gr_mat_t res, flint_rand_t state, gr_ctx_t ctx)
{
if (MATRIX_CTX(ctx)->all_sizes)
_gr_mat_resize(res, n_randint(state, 7), n_randint(state, 7), MATRIX_CTX(ctx)->base_ring);
return gr_mat_randtest(res, state, MATRIX_CTX(ctx)->base_ring);
}
static truth_t
matrix_equal(const gr_mat_t mat1, const gr_mat_t mat2, gr_ctx_t ctx)
{
return gr_mat_equal(mat1, mat2, MATRIX_CTX(ctx)->base_ring);
}
static int
matrix_set(gr_mat_t res, const gr_mat_t mat, gr_ctx_t ctx)
{
if (res->r != mat->r || res->c != mat->c)
_gr_mat_resize(res, mat->r, mat->c, MATRIX_CTX(ctx)->base_ring);
return gr_mat_set(res, mat, MATRIX_CTX(ctx)->base_ring);
}
static int
matrix_set_si(gr_mat_t res, slong v, gr_ctx_t ctx)
{
if (MATRIX_CTX(ctx)->all_sizes)
return GR_DOMAIN;
return gr_mat_set_si(res, v, MATRIX_CTX(ctx)->base_ring);
}
static int
matrix_set_ui(gr_mat_t res, ulong v, gr_ctx_t ctx)
{
if (MATRIX_CTX(ctx)->all_sizes)
return GR_DOMAIN;
return gr_mat_set_ui(res, v, MATRIX_CTX(ctx)->base_ring);
}
static int
matrix_set_fmpz(gr_mat_t res, const fmpz_t v, gr_ctx_t ctx)
{
if (MATRIX_CTX(ctx)->all_sizes)
return GR_DOMAIN;
return gr_mat_set_fmpz(res, v, MATRIX_CTX(ctx)->base_ring);
}
static int
matrix_set_fmpq(gr_mat_t res, const fmpq_t v, gr_ctx_t ctx)
{
if (MATRIX_CTX(ctx)->all_sizes)
return GR_DOMAIN;
return gr_mat_set_fmpq(res, v, MATRIX_CTX(ctx)->base_ring);
}
static int
matrix_set_other(gr_mat_t res, gr_srcptr x, gr_ctx_t x_ctx, gr_ctx_t ctx)
{
if (x_ctx == ctx)
{
return matrix_set(res, x, ctx);
}
else if (x_ctx == MATRIX_CTX(ctx)->base_ring)
{
if (MATRIX_CTX(ctx)->all_sizes)
return GR_DOMAIN;
return gr_mat_set_scalar(res, x, x_ctx);
}
else if (x_ctx->which_ring == GR_CTX_GR_MAT)
{
const gr_mat_struct * xmat = x;
if (res->r != xmat->r || res->c != xmat->c)
{
if (MATRIX_CTX(ctx)->all_sizes)
_gr_mat_resize(res, xmat->r, xmat->c, MATRIX_CTX(ctx)->base_ring);
else
return GR_DOMAIN;
}
return gr_mat_set_gr_mat_other(res, xmat, MATRIX_CTX(x_ctx)->base_ring,
MATRIX_CTX(ctx)->base_ring);
}
else
{
int status = GR_SUCCESS;
gr_ptr tmp;
if (MATRIX_CTX(ctx)->all_sizes)
return GR_UNABLE;
GR_TMP_INIT(tmp, MATRIX_CTX(ctx)->base_ring);
status = gr_set_other(tmp, x, x_ctx, MATRIX_CTX(ctx)->base_ring);
if (status == GR_SUCCESS)
status = gr_mat_set_scalar(res, tmp, MATRIX_CTX(ctx)->base_ring);
GR_TMP_CLEAR(tmp, MATRIX_CTX(ctx)->base_ring);
return status;
}
}
static int
matrix_zero(gr_mat_t res, gr_ctx_t ctx)
{
if (MATRIX_CTX(ctx)->all_sizes)
return GR_DOMAIN;
return gr_mat_zero(res, MATRIX_CTX(ctx)->base_ring);
}
static int
matrix_one(gr_mat_t res, gr_ctx_t ctx)
{
if (MATRIX_CTX(ctx)->all_sizes)
return GR_DOMAIN;
return gr_mat_one(res, MATRIX_CTX(ctx)->base_ring);
}
static truth_t
matrix_is_zero(const gr_mat_t mat, gr_ctx_t ctx)
{
return gr_mat_is_zero(mat, MATRIX_CTX(ctx)->base_ring);
}
static truth_t
matrix_is_one(const gr_mat_t mat, gr_ctx_t ctx)
{
return gr_mat_is_one(mat, MATRIX_CTX(ctx)->base_ring);
}
static truth_t
matrix_is_neg_one(const gr_mat_t mat, gr_ctx_t ctx)
{
return gr_mat_is_neg_one(mat, MATRIX_CTX(ctx)->base_ring);
}
static int
matrix_neg(gr_mat_t res, const gr_mat_t mat, gr_ctx_t ctx)
{
if (res->r != mat->r || res->c != mat->c)
_gr_mat_resize(res, mat->r, mat->c, MATRIX_CTX(ctx)->base_ring);
return gr_mat_neg(res, mat, MATRIX_CTX(ctx)->base_ring);
}
#define DEF_MAT_OP_1(op, gr_mat_op) static int \
op (gr_mat_t res, const gr_mat_t mat1, const gr_mat_t mat2, gr_ctx_t ctx) \
{ \
if (mat1->r != mat2->r || mat1->c != mat2->c) \
return GR_DOMAIN; \
if (res->r != mat1->r || res->c != mat1->c) \
_gr_mat_resize(res, mat1->r, mat1->c, MATRIX_CTX(ctx)->base_ring); \
return gr_mat_op(res, mat1, mat2, MATRIX_CTX(ctx)->base_ring); \
}
#define DEF_MAT_SCALAR_OP_1(op, typ, gr_mat_op_scalar) static int \
op (gr_mat_t res, const gr_mat_t mat1, typ x, gr_ctx_t ctx) \
{ \
if (res->r != mat1->r || res->c != mat1->c) \
_gr_mat_resize(res, mat1->r, mat1->c, MATRIX_CTX(ctx)->base_ring); \
return gr_mat_op_scalar(res, mat1, x, MATRIX_CTX(ctx)->base_ring); \
}
#define DEF_MAT_OP_OTHER(op, matrix_op, gr_mat_op_scalar) static int \
op(gr_mat_t res, const gr_mat_t mat, gr_ptr y, gr_ctx_t y_ctx, gr_ctx_t ctx) \
{ \
if (y_ctx == ctx) \
{ \
return matrix_op(res, mat, y, ctx); \
} \
else if (y_ctx == MATRIX_CTX(ctx)->base_ring) \
{ \
int status = GR_SUCCESS; \
if (res->r != mat->r || res->c != mat->c) \
status = _gr_mat_check_resize(res, mat->r, mat->c, ctx); \
if (status != GR_SUCCESS) \
return status; \
return gr_mat_op_scalar(res, mat, y, y_ctx); \
} \
else if (y_ctx->which_ring == GR_CTX_GR_MAT) \
{ \
int status; \
gr_mat_t tmp; \
gr_mat_init(tmp, ((gr_mat_struct *) y)->r, ((gr_mat_struct *) y)->c, MATRIX_CTX(ctx)->base_ring); \
status = matrix_set_other(tmp, y, y_ctx, ctx); \
if (status == GR_SUCCESS) \
{ \
status = matrix_op(res, mat, tmp, ctx); \
} \
gr_mat_clear(tmp, MATRIX_CTX(ctx)->base_ring); \
return status; \
} \
else \
{ \
int status; \
gr_ptr c; \
GR_TMP_INIT(c, MATRIX_CTX(ctx)->base_ring); \
status = gr_set_other(c, y, y_ctx, MATRIX_CTX(ctx)->base_ring); \
if (status == GR_SUCCESS) \
{ \
if (res->r != mat->r || res->c != mat->c) \
status = _gr_mat_check_resize(res, mat->r, mat->c, ctx); \
if (status == GR_SUCCESS) \
status = gr_mat_op_scalar(res, mat, c, MATRIX_CTX(ctx)->base_ring); \
} \
GR_TMP_CLEAR(c, MATRIX_CTX(ctx)->base_ring); \
return status; \
} \
return GR_UNABLE; \
} \
#define DEF_MAT_OTHER_OP(op, matrix_op, gr_scalar_op_mat) static int \
op(gr_mat_t res, gr_ptr x, gr_ctx_t x_ctx, const gr_mat_t mat, gr_ctx_t ctx) \
{ \
if (x_ctx == ctx) \
{ \
return matrix_op(res, x, mat, ctx); \
} \
else if (x_ctx == MATRIX_CTX(ctx)->base_ring) \
{ \
int status = GR_SUCCESS; \
if (res->r != mat->r || res->c != mat->c) \
status = _gr_mat_check_resize(res, mat->r, mat->c, ctx); \
if (status != GR_SUCCESS) \
return status; \
return gr_scalar_op_mat(res, x, mat, x_ctx); \
} \
else if (x_ctx->which_ring == GR_CTX_GR_MAT) \
{ \
int status; \
gr_mat_t tmp; \
gr_mat_init(tmp, ((gr_mat_struct *) x)->r, ((gr_mat_struct *) x)->c, MATRIX_CTX(ctx)->base_ring); \
status = matrix_set_other(tmp, x, x_ctx, ctx); \
if (status == GR_SUCCESS) \
{ \
status = matrix_op(res, tmp, mat, ctx); \
} \
gr_mat_clear(tmp, MATRIX_CTX(ctx)->base_ring); \
return status; \
} \
else \
{ \
int status; \
gr_ptr c; \
GR_TMP_INIT(c, MATRIX_CTX(ctx)->base_ring); \
status = gr_set_other(c, x, x_ctx, MATRIX_CTX(ctx)->base_ring); \
if (status == GR_SUCCESS) \
{ \
if (res->r != mat->r || res->c != mat->c) \
status = _gr_mat_check_resize(res, mat->r, mat->c, ctx); \
if (status == GR_SUCCESS) \
status = gr_scalar_op_mat(res, c, mat, MATRIX_CTX(ctx)->base_ring); \
} \
GR_TMP_CLEAR(c, MATRIX_CTX(ctx)->base_ring); \
return status; \
} \
return GR_UNABLE; \
} \
DEF_MAT_OP_1(matrix_add, gr_mat_add)
DEF_MAT_OP_1(matrix_sub, gr_mat_sub)
static int
matrix_mul(gr_mat_t res, const gr_mat_t mat1, const gr_mat_t mat2, gr_ctx_t ctx)
{
if (mat1->c != mat2->r)
return GR_DOMAIN;
if (res->r != mat1->r || res->c != mat2->c)
{
if (res == mat1 || res == mat2)
{
int status;
gr_mat_t tmp;
gr_mat_init(tmp, mat1->r, mat2->c, MATRIX_CTX(ctx)->base_ring);
status = matrix_mul(tmp, mat1, mat2, ctx);
gr_mat_swap(res, tmp, MATRIX_CTX(ctx)->base_ring);
gr_mat_clear(tmp, MATRIX_CTX(ctx)->base_ring);
return status;
}
else
{
_gr_mat_resize(res, mat1->r, mat2->c, MATRIX_CTX(ctx)->base_ring);
}
}
return gr_mat_mul(res, mat1, mat2, MATRIX_CTX(ctx)->base_ring);
}
static int
matrix_div(gr_mat_t res, const gr_mat_t mat1, const gr_mat_t mat2, gr_ctx_t ctx)
{
return GR_UNABLE;
}
static int
matrix_pow(gr_mat_t res, const gr_mat_t mat1, const gr_mat_t mat2, gr_ctx_t ctx)
{
return GR_UNABLE;
}
DEF_MAT_OP_OTHER(matrix_add_other, matrix_add, gr_mat_add_scalar)
DEF_MAT_OP_OTHER(matrix_sub_other, matrix_sub, gr_mat_sub_scalar)
DEF_MAT_OP_OTHER(matrix_mul_other, matrix_mul, gr_mat_mul_scalar)
DEF_MAT_OP_OTHER(matrix_div_other, matrix_div, gr_mat_div_scalar)
DEF_MAT_OP_OTHER(matrix_pow_other, matrix_pow, gr_mat_pow_scalar)
DEF_MAT_OTHER_OP(matrix_other_add, matrix_add, gr_mat_scalar_add)
DEF_MAT_OTHER_OP(matrix_other_sub, matrix_sub, gr_mat_scalar_sub)
DEF_MAT_OTHER_OP(matrix_other_mul, matrix_mul, gr_mat_scalar_mul)
DEF_MAT_SCALAR_OP_1(matrix_add_ui, ulong, gr_mat_add_ui)
DEF_MAT_SCALAR_OP_1(matrix_add_si, slong, gr_mat_add_si)
DEF_MAT_SCALAR_OP_1(matrix_add_fmpz, const fmpz_t, gr_mat_add_fmpz)
DEF_MAT_SCALAR_OP_1(matrix_add_fmpq, const fmpq_t, gr_mat_add_fmpq)
DEF_MAT_SCALAR_OP_1(matrix_sub_ui, ulong, gr_mat_sub_ui)
DEF_MAT_SCALAR_OP_1(matrix_sub_si, slong, gr_mat_sub_si)
DEF_MAT_SCALAR_OP_1(matrix_sub_fmpz, const fmpz_t, gr_mat_sub_fmpz)
DEF_MAT_SCALAR_OP_1(matrix_sub_fmpq, const fmpq_t, gr_mat_sub_fmpq)
DEF_MAT_SCALAR_OP_1(matrix_mul_ui, ulong, gr_mat_mul_ui)
DEF_MAT_SCALAR_OP_1(matrix_mul_si, slong, gr_mat_mul_si)
DEF_MAT_SCALAR_OP_1(matrix_mul_fmpz, const fmpz_t, gr_mat_mul_fmpz)
DEF_MAT_SCALAR_OP_1(matrix_mul_fmpq, const fmpq_t, gr_mat_mul_fmpq)
DEF_MAT_SCALAR_OP_1(matrix_div_ui, ulong, gr_mat_div_ui)
DEF_MAT_SCALAR_OP_1(matrix_div_si, slong, gr_mat_div_si)
DEF_MAT_SCALAR_OP_1(matrix_div_fmpz, const fmpz_t, gr_mat_div_fmpz)
DEF_MAT_SCALAR_OP_1(matrix_div_fmpq, const fmpq_t, gr_mat_div_fmpq)
DEF_MAT_SCALAR_OP_1(matrix_pow_ui, ulong, gr_mat_pow_ui)
DEF_MAT_SCALAR_OP_1(matrix_pow_si, slong, gr_mat_pow_si)
DEF_MAT_SCALAR_OP_1(matrix_pow_fmpz, const fmpz_t, gr_mat_pow_fmpz)
DEF_MAT_SCALAR_OP_1(matrix_pow_fmpq, const fmpq_t, gr_mat_pow_fmpq)
static int
matrix_inv(gr_mat_t res, const gr_mat_t mat, gr_ctx_t ctx)
{
if (mat->r != mat->c)
return GR_DOMAIN;
if (res->r != mat->r || res->c != mat->c)
_gr_mat_resize(res, mat->r, mat->r, MATRIX_CTX(ctx)->base_ring);
return gr_mat_inv(res, mat, MATRIX_CTX(ctx)->base_ring);
}
static int
matrix_exp(gr_mat_t res, const gr_mat_t mat, gr_ctx_t ctx)
{
if (res->r != mat->r || res->c != mat->c)
_gr_mat_resize(res, mat->r, mat->c, MATRIX_CTX(ctx)->base_ring);
return gr_mat_exp(res, mat, MATRIX_CTX(ctx)->base_ring);
}
static int
matrix_log(gr_mat_t res, const gr_mat_t mat, gr_ctx_t ctx)
{
if (res->r != mat->r || res->c != mat->c)
_gr_mat_resize(res, mat->r, mat->c, MATRIX_CTX(ctx)->base_ring);
return gr_mat_log(res, mat, MATRIX_CTX(ctx)->base_ring);
}
static int
matrix_sqrt(gr_mat_t res, const gr_mat_t mat, gr_ctx_t ctx)
{
if (res->r != mat->r || res->c != mat->c)
_gr_mat_resize(res, mat->r, mat->c, MATRIX_CTX(ctx)->base_ring);
return gr_mat_sqrt(res, mat, MATRIX_CTX(ctx)->base_ring);
}
static int
matrix_rsqrt(gr_mat_t res, const gr_mat_t mat, gr_ctx_t ctx)
{
if (res->r != mat->r || res->c != mat->c)
_gr_mat_resize(res, mat->r, mat->c, MATRIX_CTX(ctx)->base_ring);
return gr_mat_rsqrt(res, mat, MATRIX_CTX(ctx)->base_ring);
}
int _gr_mat_methods_initialized = 0;
gr_static_method_table _gr_mat_methods;
gr_method_tab_input _gr_mat_methods_input[] =
{
{GR_METHOD_CTX_WRITE, (gr_funcptr) matrix_ctx_write},
{GR_METHOD_CTX_IS_RING, (gr_funcptr) matrix_ctx_is_ring},
{GR_METHOD_CTX_IS_COMMUTATIVE_RING, (gr_funcptr) matrix_ctx_is_commutative_ring},
{GR_METHOD_CTX_IS_THREADSAFE, (gr_funcptr) matrix_ctx_is_threadsafe},
{GR_METHOD_CTX_IS_RATIONAL_VECTOR_SPACE, (gr_funcptr) matrix_ctx_is_rational_vector_space},
{GR_METHOD_CTX_IS_REAL_VECTOR_SPACE, (gr_funcptr) matrix_ctx_is_real_vector_space},
{GR_METHOD_CTX_IS_COMPLEX_VECTOR_SPACE, (gr_funcptr) matrix_ctx_is_complex_vector_space},
{GR_METHOD_CTX_IS_APPROX_COMMUTATIVE_RING, (gr_funcptr) matrix_ctx_is_approx_commutative_ring},
{GR_METHOD_CTX_BASE, (gr_funcptr) matrix_ctx_base},
{GR_METHOD_INIT, (gr_funcptr) matrix_init},
{GR_METHOD_CLEAR, (gr_funcptr) matrix_clear},
{GR_METHOD_SWAP, (gr_funcptr) matrix_swap},
{GR_METHOD_SET_SHALLOW, (gr_funcptr) matrix_set_shallow},
{GR_METHOD_RANDTEST, (gr_funcptr) matrix_randtest},
{GR_METHOD_WRITE, (gr_funcptr) matrix_write},
{GR_METHOD_ZERO, (gr_funcptr) matrix_zero},
{GR_METHOD_ONE, (gr_funcptr) matrix_one},
{GR_METHOD_IS_ZERO, (gr_funcptr) matrix_is_zero},
{GR_METHOD_IS_ONE, (gr_funcptr) matrix_is_one},
{GR_METHOD_IS_NEG_ONE, (gr_funcptr) matrix_is_neg_one},
{GR_METHOD_EQUAL, (gr_funcptr) matrix_equal},
{GR_METHOD_SET, (gr_funcptr) matrix_set},
{GR_METHOD_SET_UI, (gr_funcptr) matrix_set_ui},
{GR_METHOD_SET_SI, (gr_funcptr) matrix_set_si},
{GR_METHOD_SET_FMPZ, (gr_funcptr) matrix_set_fmpz},
{GR_METHOD_SET_FMPQ, (gr_funcptr) matrix_set_fmpq},
{GR_METHOD_SET_OTHER, (gr_funcptr) matrix_set_other},
{GR_METHOD_NEG, (gr_funcptr) matrix_neg},
{GR_METHOD_ADD, (gr_funcptr) matrix_add},
{GR_METHOD_ADD_OTHER, (gr_funcptr) matrix_add_other},
{GR_METHOD_OTHER_ADD, (gr_funcptr) matrix_other_add},
{GR_METHOD_ADD_UI, (gr_funcptr) matrix_add_ui},
{GR_METHOD_ADD_SI, (gr_funcptr) matrix_add_si},
{GR_METHOD_ADD_FMPZ, (gr_funcptr) matrix_add_fmpz},
{GR_METHOD_ADD_FMPQ, (gr_funcptr) matrix_add_fmpq},
{GR_METHOD_SUB, (gr_funcptr) matrix_sub},
{GR_METHOD_SUB_OTHER, (gr_funcptr) matrix_sub_other},
{GR_METHOD_OTHER_SUB, (gr_funcptr) matrix_other_sub},
{GR_METHOD_SUB_UI, (gr_funcptr) matrix_sub_ui},
{GR_METHOD_SUB_SI, (gr_funcptr) matrix_sub_si},
{GR_METHOD_SUB_FMPZ, (gr_funcptr) matrix_sub_fmpz},
{GR_METHOD_SUB_FMPQ, (gr_funcptr) matrix_sub_fmpq},
{GR_METHOD_MUL, (gr_funcptr) matrix_mul},
{GR_METHOD_MUL_OTHER, (gr_funcptr) matrix_mul_other},
{GR_METHOD_OTHER_MUL, (gr_funcptr) matrix_other_mul},
{GR_METHOD_MUL_UI, (gr_funcptr) matrix_mul_ui},
{GR_METHOD_MUL_SI, (gr_funcptr) matrix_mul_si},
{GR_METHOD_MUL_FMPZ, (gr_funcptr) matrix_mul_fmpz},
{GR_METHOD_MUL_FMPQ, (gr_funcptr) matrix_mul_fmpq},
{GR_METHOD_DIV_OTHER, (gr_funcptr) matrix_div_other},
{GR_METHOD_DIV_UI, (gr_funcptr) matrix_div_ui},
{GR_METHOD_DIV_SI, (gr_funcptr) matrix_div_si},
{GR_METHOD_DIV_FMPZ, (gr_funcptr) matrix_div_fmpz},
{GR_METHOD_DIV_FMPQ, (gr_funcptr) matrix_div_fmpq},
{GR_METHOD_POW_OTHER, (gr_funcptr) matrix_pow_other},
{GR_METHOD_POW_UI, (gr_funcptr) matrix_pow_ui},
{GR_METHOD_POW_SI, (gr_funcptr) matrix_pow_si},
{GR_METHOD_POW_FMPZ, (gr_funcptr) matrix_pow_fmpz},
{GR_METHOD_POW_FMPQ, (gr_funcptr) matrix_pow_fmpq},
{GR_METHOD_INV, (gr_funcptr) matrix_inv},
{GR_METHOD_EXP, (gr_funcptr) matrix_exp},
{GR_METHOD_SQRT, (gr_funcptr) matrix_sqrt},
{GR_METHOD_RSQRT, (gr_funcptr) matrix_rsqrt},
{GR_METHOD_LOG, (gr_funcptr) matrix_log},
{0, (gr_funcptr) NULL},
};
static void
_gr_ctx_init_matrix(gr_ctx_t ctx, gr_ctx_t base_ring, int all_sizes, slong nrows, slong ncols)
{
ctx->which_ring = GR_CTX_GR_MAT;
ctx->sizeof_elem = sizeof(gr_mat_struct);
ctx->size_limit = WORD_MAX;
if (nrows < 0 || ncols < 0)
flint_throw(FLINT_ERROR, "(%s)\n", __func__);
MATRIX_CTX(ctx)->base_ring = (gr_ctx_struct *) base_ring;
MATRIX_CTX(ctx)->all_sizes = all_sizes;
MATRIX_CTX(ctx)->nrows = nrows;
MATRIX_CTX(ctx)->ncols = ncols;
ctx->methods = _gr_mat_methods;
if (!_gr_mat_methods_initialized)
{
gr_method_tab_init(_gr_mat_methods, _gr_mat_methods_input);
_gr_mat_methods_initialized = 1;
}
}
void gr_ctx_init_matrix_domain(gr_ctx_t ctx, gr_ctx_t base_ring)
{
_gr_ctx_init_matrix(ctx, base_ring, 1, 0, 0);
}
void gr_ctx_init_matrix_space(gr_ctx_t ctx, gr_ctx_t base_ring, slong nrows, slong ncols)
{
_gr_ctx_init_matrix(ctx, base_ring, 0, nrows, ncols);
}