Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions M2/Macaulay2/d/interface.dd
Original file line number Diff line number Diff line change
Expand Up @@ -2127,6 +2127,16 @@ export rawMatrixEntry(e:Expr):Expr := (
);
setupfun("rawMatrixEntry",rawMatrixEntry);

export rawMatrixEntries(e:Expr):Expr := (
when e is M:RawMutableMatrixCell do
toExpr(Ccode(RawRingElementArrayOrNull, "IM2_MutableMatrix_get_entries(", M.p, ")"))
else
when e is M:RawMatrixCell do
toExpr(Ccode(RawRingElementArrayOrNull, "IM2_Matrix_get_entries(", M.p, ")"))
else WrongArg("a raw matrix or mutable matrix")
);
setupfun("rawMatrixEntries",rawMatrixEntries);

export rawSortColumns(e:Expr):Expr := (
when e is s:Sequence do
if length(s) != 3 then WrongNumArgs(3) else
Expand Down
53 changes: 53 additions & 0 deletions M2/Macaulay2/e/interface/matrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,59 @@ const RingElement /* or null */ *IM2_Matrix_get_entry(const Matrix *M,
}
}

/* Returns the entries of the matrix in a flat array in row major order
*/
engine_RawRingElementArrayOrNull IM2_Matrix_get_entries(const Matrix *M)
{
try
{
int ncols = M->n_cols();
int nrows = M->n_rows();
if(nrows < 0 || ncols < 0)
{
ERROR("internal error: matrix has a negative size %d by %d",
nrows,
ncols);
}
//TODO overflow detection/handling.
//This also runs into the problem that the arrays from "d"
//only use an int for their length field.
int nentries = nrows * ncols;
engine_RawRingElementArray entries =
getmemarraytype(engine_RawRingElementArray, nentries);
entries->len = nentries;
RingElement *zero =
RingElement::make_raw(M->get_ring(), M->get_ring()->zero());
//populate the matrix with zeros
std::fill_n(entries->array, nentries, zero);
//walk through the columns
for(int c = 0; c < ncols; c++)
{
const vec &column = M->elem(c);
for(const vecterm &term : column)
{
if(term.comp < 0 || term.comp >= nrows)
{
ERROR("internal error: matrix contains invalid entries:"
"row index %d out of range 0 .. %d",
term.comp,
nrows - 1);
//Ignoring the entry and continuing
continue;
}
entries->array[term.comp * ncols + c] =
RingElement::make_raw(M->get_ring(), term.coeff);
}
}
return entries;
} catch (const exc::engine_error &e)
{
ERROR(e.what());
return nullptr;
}
return nullptr;
}

const Matrix *IM2_Matrix_identity(const FreeModule *F, int preference)
{
#ifdef DEVELOPMENT
Expand Down
2 changes: 2 additions & 0 deletions M2/Macaulay2/e/interface/matrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ const RingElement /* or null */ *IM2_Matrix_get_entry(
int r,
int c); /* drg: connected rawMatrixEntry, OK*/

engine_RawRingElementArrayOrNull IM2_Matrix_get_entries(const Matrix *M);

/*******************************************************************************/
const Matrix *IM2_Matrix_identity(
const FreeModule *F,
Expand Down
40 changes: 40 additions & 0 deletions M2/Macaulay2/e/interface/mutable-matrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,46 @@ IM2_MutableMatrix_get_entry(const MutableMatrix *M, int r, int c)
return RingElement::make_raw(M->get_ring(), result);
}

engine_RawRingElementArrayOrNull
IM2_MutableMatrix_get_entries(const MutableMatrix *M)
{
try
{
int ncols = M->n_cols();
int nrows = M->n_rows();
if(nrows < 0 || ncols < 0)
{
ERROR("internal error: matrix has a negative size %d by %d",
nrows,
ncols);
}
//TODO overflow detection/handling.
//This also runs into the problem that the arrays from "d"
//only use an int for their length field.
int nentries = nrows * ncols;
engine_RawRingElementArray entries =
getmemarraytype(engine_RawRingElementArray, nentries);
entries->len = nentries;
for(int r = 0; r < nrows; r++)
{
for(int c = 0; c < ncols; c++)
{
ring_elem result;
M->get_entry(r, c, result);
entries->array[r * ncols + c] =
RingElement::make_raw(M->get_ring(), result);
}
}
return entries;
} catch (const exc::engine_error& e)
{
ERROR(e.what());
return nullptr;
}
return nullptr;
}


M2_bool IM2_MutableMatrix_set_entry(MutableMatrix *M,
int r,
int c,
Expand Down
3 changes: 3 additions & 0 deletions M2/Macaulay2/e/interface/mutable-matrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ const RingElement /* or null */ *
IM2_MutableMatrix_get_entry(const MutableMatrix *M, int r, int c);
/* drg: connected rawMatrixEntry, OK*/

engine_RawRingElementArrayOrNull
IM2_MutableMatrix_get_entries(const MutableMatrix *M);

/* Each of these routines returns false if there was an error. */

M2_bool IM2_MutableMatrix_set_entry(MutableMatrix *M,
Expand Down
7 changes: 6 additions & 1 deletion M2/Macaulay2/m2/engine.m2
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,12 @@ target RawMatrix := o -> rawTarget o
source RawMatrix := o -> rawSource o
transposeSequence := t -> pack(#t, mingle t)
isHomogeneous RawMatrix := rawIsHomogeneous
entries RawMutableMatrix := entries RawMatrix := m -> table(rawNumberOfRows m,rawNumberOfColumns m,(i,j)->rawMatrixEntry(m,i,j))
entries RawMutableMatrix :=
entries RawMatrix := m -> (
allEntries := rawMatrixEntries m;
ncols := rawNumberOfColumns m;
table(rawNumberOfRows m, ncols, (i,j) -> allEntries#(i*ncols+j))
)

ZZ * RawMatrix := (n,f) -> (
R := rawRing rawTarget f;
Expand Down
Loading