[Pntool-developers] SF.net SVN: pntool:[227] spnbox
Brought to you by:
compaqdrew,
miordache
From: <Ste...@us...> - 2009-08-21 15:06:40
|
Revision: 227 http://pntool.svn.sourceforge.net/pntool/?rev=227&view=rev Author: StephenCamp Date: 2009-08-21 15:06:30 +0000 (Fri, 21 Aug 2009) Log Message: ----------- Fixed a minor bug in dp. Added mroadm, the test routine, a partial test script, and the appropriate spnbox.h, deallocation.c, and makefile entries. mroadm runs and passes the current test script, but the script is not guaranteed to test all functionality. Changed the listing of C authors in spnbox.h from "Marian Iordache & Stephen Camp" to "Stephen Camp". Modified Paths: -------------- spnbox/Makefile spnbox/deallocation.c spnbox/dp.c spnbox/spnbox.h spnbox/tests/Makefile Added Paths: ----------- spnbox/mroadm.c spnbox/tests/test-mroadm.c spnbox/tests/test-mroadm.txt Modified: spnbox/Makefile =================================================================== --- spnbox/Makefile 2009-08-20 13:40:31 UTC (rev 226) +++ spnbox/Makefile 2009-08-21 15:06:30 UTC (rev 227) @@ -5,8 +5,8 @@ all: actn.o admcon.o asiph.o avpr.o chkcons.o deallocation.o dp.o\ extendedmatrix.o fvpr.o gcdv.o invar.o ilpadm.o ipslv.o ipsolve.o isadm.o\ - issiph.o linenf.o matrixmath.o MemoryManager.o msplit.o nltrans.o pn2acpn.o\ - pn2eacpn.o reduce.o supervis.o tactn.o liblpsolve55.a + issiph.o linenf.o matrixmath.o MemoryManager.o mroadm.o msplit.o nltrans.o\ + pn2acpn.o pn2eacpn.o reduce.o supervis.o tactn.o liblpsolve55.a actn.o: actn.c spnbox.h MemoryManager.h matrixmath.h ../pnheaders/general.h ../pnheaders/matrix.h $(COMPILER) -c actn.c @@ -68,6 +68,9 @@ MemoryManager.o: MemoryManager.c MemoryManager.h ../pnheaders/general.h ../pnheaders/matrix.h $(COMPILER) -c MemoryManager.c +mroadm.o: mroadm.c spnbox.h ../pnheaders/matrix.h ../pnheaders/general.h matrixmath.h + $(COMPILER) -c mroadm.c + msplit.o: msplit.c spnbox.h MemoryManager.h matrixmath.h ../pnheaders/general.h ../pnheaders/matrix.h $(COMPILER) -c msplit.c Modified: spnbox/deallocation.c =================================================================== --- spnbox/deallocation.c 2009-08-20 13:40:31 UTC (rev 226) +++ spnbox/deallocation.c 2009-08-21 15:06:30 UTC (rev 227) @@ -42,6 +42,11 @@ memset(data, 0, sizeof(ilpadm)); } +void DeallocateMroadm(mroadm_r* data) +{ + DeallocateIlpadm((ilpadm_r*) data); +} + void DeallocateLinenf(linenf_r *data) { FreeMatrixSafe(&data->Dfm); Modified: spnbox/dp.c =================================================================== --- spnbox/dp.c 2009-08-20 13:40:31 UTC (rev 226) +++ spnbox/dp.c 2009-08-21 15:06:30 UTC (rev 227) @@ -319,7 +319,7 @@ } free(d->TD); } - if (d->TDCount) free(d->TD); + if (d->TDCount) free(d->TDCount); DeallocateMatrix(&d->Dm); DeallocateMatrix(&d->Dp); DeallocateMatrix(&d->DI); Added: spnbox/mroadm.c =================================================================== --- spnbox/mroadm.c (rev 0) +++ spnbox/mroadm.c 2009-08-21 15:06:30 UTC (rev 227) @@ -0,0 +1,601 @@ +#include <stdlib.h> +#include "../pnheaders/general.h" +#include "../pnheaders/matrix.h" +#include "matrixmath.h" +#include "spnbox.h" + +typedef struct mroadm_d +{ + /*The matrices.*/ + matrix M, R1, R2, L, D; + /*The number of places and transitions in the original Petri net.*/ + int places, transitions; + /*The uncontrollable and unobservable transitions.*/ + int *Tuc, *Tuo; + int TucCount, TuoCount; + /*The initial marking.*/ + int* m0; + /*B*/ + int* B; + /*The list of constraints that need to be converted.*/ + int *conversionList; + int conversionCount; + /*The per-constraint status messages.*/ + char** dhow; +} mroadm_d; + +static int CheckParams(matrix* L, int* B, matrix* D, int** Tuc, int* TucCount, int** Tuo, int* TuoCount, int* m0); +static mroadm_d CreateData(matrix* L, int* B, matrix* D, int* Tuc, int TucCount, int* Tuo, int TuoCount, int *m0); +static int FindConstraintsToConvert(mroadm_d* d); +static void BuildM(mroadm_d* d); +static int educ(mroadm_d* d); +static void zduo(mroadm_d* d); +static void czero(mroadm_d* d, int row, int col); +static void subtest(mroadm_d* d); +static mroadm_r BuildSolution(mroadm_d* d); +void display(char* beginning, char* middle, char* end, int i, int p); + +mroadm_r mroadm(matrix* L, int* B, matrix* D, int* Tuc, int TucCount, int* Tuo, int TuoCount, int* m0) +{ + mroadm_r result; + memset(&result, 0, sizeof(mroadm_r)); + if (! CheckParams(L, B, D, &Tuc, &TucCount, &Tuo, &TuoCount, m0)) return result; + + if (! NumberOfRows(*L)) + { + result.how = HOW_OK; + display("Empty set of constraints!", "", "", 1, 1); + return result; + } + if (! NumberOfRows(*D)) + { + result.how = HOW_OK; + result.ba = tcalloc(NumberOfRows(*L), sizeof(int)); + memcpy(result.ba, B, NumberOfRows(*L) * sizeof(int)); + AllocateMatrixType(2, &result.La, NumberOfRows(*L), NumberOfColumns(*L)); + CopyMatrix(L, &result.La); + return result; + } + + mroadm_d data = CreateData(L, B, D, Tuc, TucCount, Tuo, TuoCount, m0); + + /*Get the list of constraints that need to be converted and convert them.*/ + if (FindConstraintsToConvert(&data)) + { + BuildM(&data); + if (educ(&data)) + { + zduo(&data); + } + subtest(&data); + + /*Reduce the constraint-related rows of M. We'll need a copy of the last part + of a row of M, the part that was originally an identity. Allocate space for + it now.*/ + matrix mrow; + AllocateMatrixType(1, &mrow, 1, NumberOfColumns(data.M) - data.TucCount - data.TuoCount - 1); + int i, j; + for (i = 0; i < data.conversionCount; i++) + { + CopyBlock(1, NumberOfColumns(data.M) - data.TucCount - data.TuoCount - 1, &data.M, i + data.places, data.TucCount + data.TuoCount + 1, &mrow, 0, 0); + int d = gcdv(&mrow, -1, -1); + for (j = 0; j < NumberOfColumns(data.M); j++) + { + SetMatrixEl(&data.M, i + data.places, j, GetMatrixEl(&data.M, i + data.places, j) / d); + } + } + DeallocateMatrix(&mrow); + + /*The constraint-related parts of M now become parts of the transformation + matrices.*/ + for (i = 0; i < data.conversionCount; i++) + { + CopyBlock(1, NumberOfColumns(data.R1), &data.M, i + data.places, data.TucCount + data.TuoCount + 1, &data.R1, data.conversionList[i], 0); + SetMatrixEl(&data.R2, data.conversionList[i], data.conversionList[i], GetMatrixEl(&data.M, data.places + i, data.TucCount + data.TuoCount + data.places + i + 1)); + } + } + /*Get rid of intermediate variables.*/ + DeallocateMatrix(&data.M); + free(data.conversionList); + + /*Cleanup output.*/ + if (is_verbose() >= VRB_MROADM) + { + printf("\n"); + } + + /*Build the solution.*/ + return BuildSolution(&data); +} + +/******************************************************************************* +CheckParams checks to make sure the parameters are valid. Returns a logical +value, nonzero for valid and zero for invalid.*/ +int CheckParams(matrix* L, int* B, matrix* D, int** Tuc, int* TucCount, int** Tuo, int* TuoCount, int* m0) +{ + /*D, L, and B are all required.*/ + if (! (D && L)) + { + merror(0, "MROADM: A required pointer was null!"); + return 0; + } + /*The constraint matrix must have as many columns as there are places.*/ + if (NumberOfColumns(*L) != NumberOfRows(*D)) + { + merror(0, "MROADM: The dimensions of the constraint and incidence matrices are inconsistent"); + return 0; + } + /*Make sure that null pointers and counters at zero agree.*/ + if (! *Tuc) *TucCount = 0; + else if (! *TucCount) *Tuc = 0; + if (! *Tuo) *TuoCount = 0; + else if (! *TuoCount) *Tuo = 0; + return 1; +} + +/******************************************************************************* +CreateData creates the initial parts of the mroadm_d data structure, which holds +information about the problem and is passed to various subroutines of the +problem. CreateData allocates space for some of the matrices and sets various +counters.*/ +mroadm_d CreateData(matrix* L, int* B, matrix* D, int* Tuc, int TucCount, int* Tuo, int TuoCount, int *m0) +{ + mroadm_d data; + memset(&data, 0, sizeof(mroadm_d)); + + data.places = NumberOfRows(*D); + data.transitions = NumberOfColumns(*D); + data.TucCount = TucCount; + data.Tuc = Tuc; + data.TuoCount = TuoCount; + data.Tuo = Tuo; + data.L = *L; + data.D = *D; + data.B = B; + data.m0 = m0; + + /*R1 will have as many rows as there are constraints and columns as there are + places.*/ + AllocateMatrixType(2, &data.R1, NumberOfRows(*L), data.places); + /*R2 defaults to an identity with as many rows and columns as there are + constraints. Setup the per-constraint status messages to default to OK while + we're in the loop.*/ + AllocateMatrixType(2, &data.R2, NumberOfRows(*L), NumberOfRows(*L)); + data.dhow = tcalloc(NumberOfRows(*L), sizeof(char*)); + int i; + for (i = 0; i < NumberOfRows(*L); i++) + { + SetMatrixEl(&data.R2, i, i, 1); + data.dhow[i] = HOW_OK; + } + return data; +} + +/******************************************************************************* +FindConstraintsToConvert fills in the list of which constraints need to be +converted. It returns the number of constraints that need to be converted.*/ +int FindConstraintsToConvert(mroadm_d* d) +{ + /*Allocate space for the list of constraints that need to be converted.*/ + d->conversionList = tcalloc(NumberOfRows(d->L), sizeof(int)); + + /*Iterate through constraints.*/ + int i, j, ucFlag, uoFlag, feasible; + for (i = 0; i < NumberOfRows(d->L); i++) + { + /*If m0 has been provided, make sure the constraint works with it.*/ + feasible = 1; + if (d->m0) + { + if (MultiplyVector(&d->L, (matrix*) d->m0, i, MULTIPLYVECTOR_ARRAY, 0) > (d->B ? d->B[i] : 0)) + { + feasible = 0; + } + } + /*Make sure there exist no uncontrollable transitions such that the current + constraint row times the incidence column is greater than 0.*/ + ucFlag = 1; + for (j = 0; j < d->TucCount; j++) + { + if (MultiplyVector(&d->L, &d->D, i, d->Tuc[j], 0) > 0) + { + ucFlag = 0; + break; + } + } + /*Make sure there exist no unobservable transitions such that the current + constraint row times the incidence column is nonzero.*/ + uoFlag = 1; + for (j = 0; j < d->TuoCount; j++) + { + if (MultiplyVector(&d->L, &d->D, i, d->Tuo[j], 0)) + { + uoFlag = 0; + break; + } + } + + if (! feasible) + { + d->dhow[i] = HOW_INFEASIBLE; + display("The transformation is infeasible due to the unitial marking","",".",i,NumberOfRows(d->L)); + } + else if (ucFlag && uoFlag) + { + d->dhow[i] = HOW_OK; + display("No transformation is necessary","",".",i,NumberOfRows(d->L)); + } + else + { + /*Transformation is necessary.*/ + d->conversionList[d->conversionCount++] = i; + } + } + return d->conversionCount; +} + +/******************************************************************************* +BuildM fills in the matrix M, which is used for processing by the mroadm +algorithm.*/ +void BuildM(mroadm_d* d) +{ + /*Build M. In matlab: + Lz = L(conversionList,:) + mm = [m0; Lz * m0 - b(conversionList) - ones(conversionCount,1)] + M = [[Duc, Duo, Lz*Duc, Lz*Duo] mm eye(places + conversionCount)] + Allocate space.*/ + AllocateMatrixType(2, &d->M, d->places + d->conversionCount, d->TucCount + d->TuoCount + 1 + d->places + d->conversionCount); + /*Copy in [Duc; Lz*Duc]*/ + int i, j; + for (i = 0; i < d->TucCount; i++) + { + CopyBlock(d->places, 1, &d->D, 0, d->Tuc[i], &d->M, 0, i); + for (j = 0; j < d->conversionCount; j++) + { + SetMatrixEl(&d->M, d->places + j, i, MultiplyVector(&d->L, &d->D, d->conversionList[j], d->Tuc[i], 0)); + } + } + for (i = 0; i < d->TuoCount; i++) + { + CopyBlock(d->places, 1, &d->D, 0, d->Tuo[i], &d->M, 0, i + d->TucCount); + for (j = 0; j < d->conversionCount; j++) + { + SetMatrixEl(&d->M, d->places + j, i + d->TucCount, MultiplyVector(&d->L, &d->D, d->conversionList[j], d->Tuo[i], 0)); + } + } + /*Build mm*/ + if (d->m0) + { + for (i = 0; i < d->places; i++) + { + SetMatrixEl(&d->M, i, d->TucCount + d->TuoCount, d->m0[i]); + } + for (i = 0; i < d->conversionCount; i++) + { + SetMatrixEl(&d->M, d->places + i, d->TucCount + d->TuoCount, + MultiplyVector(&d->L, (matrix*) d->m0, d->conversionList[i], + MULTIPLYVECTOR_ARRAY, 0) - (d->B ? d->B[d->conversionList[i]] - 1 : 0)); + } + } + else + { + for (i = 0; i < d->conversionCount; i++) + { + SetMatrixEl(&d->M, d->places + i, d->TucCount + d->TuoCount, -1); + } + } + /*Fill in the identity.*/ + for (i = 0; i < d->places + d->conversionCount; i++) + { + SetMatrixEl(&d->M, i, d->TucCount + d->TuoCount + 1 + i, 1); + } +} + +/******************************************************************************* +educ eliminates positive elements from Duc.*/ +int educ(mroadm_d* d) +{ + int success = 1, i, j, upperlimit; + upperlimit = d->places; + /*At some point we are going to need to swap some rows of M. Allocate a + matrix to hold intermediate values.*/ + matrix mrow; + AllocateMatrixType(1, &mrow, 1, NumberOfColumns(d->M)); + for (i = 0; i < upperlimit; i++) + { + /*See if there are any elements below the main diagonal less than 0.*/ + for (j = i; j < d->places; j++) + { + if (GetMatrixEl(&d->M, j, i) < 0) break; + } + if (j < d->places) + { + if (j != i) + { + /*Swap rows*/ + CopyBlock(1, NumberOfColumns(d->M), &d->M, i, 0, &mrow, 0, 0); + CopyBlock(1, NumberOfColumns(d->M), &d->M, j, 0, &d->M, i, 0); + CopyBlock(1, NumberOfColumns(d->M), &mrow, 0, 0, &d->M, j, 0); + } + czero(d, i, i); + } + else + { + /*Find out if there exist any elements of M with certain characteristics. + First, any elements in the constraint-related rows of M and in the current + column such that they are greater than 0, and second, any elements in the + same rows and in the mm column that are greater than or equal to 0?*/ + for (j = d->places; j < d->places + d->conversionCount; j++) + { + if (GetMatrixEl(&d->M, j, i) > 0) break; + if (GetMatrixEl(&d->M, j, d->TucCount + d->TuoCount)) break; + } + if (j < d->places + d->conversionCount) + { + success = 0; + break; + } + } + } + /*If we have not already failed, check another failure condition: Are there + any elements in the constraint-related rows of M and the uncontrollable- + transition columns that are greater than 0?*/ + if (success) + { + for (i = d->places; i < d->places + d->conversionCount; i++) + { + for (j = 0; j < d->TucCount; j++) + { + if (GetMatrixEl(&d->M, i, j) > 0) break; + } + if (j < d->TucCount) break; + } + if (i < d->places + d->conversionCount) success = 0; + } + DeallocateMatrix(&mrow); + return success; +} + +/******************************************************************************* +zduo performs the operations relevant to zeroing elements of Duo.*/ +void zduo(mroadm_d* d) +{ + int success = 1, i, j, k, upperlimit; + upperlimit = d->places; + /*At some point we are going to need to swap some rows of M. Allocate a + matrix to hold intermediate values.*/ + matrix mrow; + AllocateMatrixType(1, &mrow, 1, NumberOfColumns(d->M)); + for (i = 0; i < upperlimit; i++) + { + /*See if there are any elements below the main diagonal less than 0.*/ + for (k = i; k < d->places; k++) + { + if (GetMatrixEl(&d->M, k, i) < 0) break; + } + if (k < d->places && k != i) + { + /*Swap rows*/ + CopyBlock(1, NumberOfColumns(d->M), &d->M, i, 0, &mrow, 0, 0); + CopyBlock(1, NumberOfColumns(d->M), &d->M, k, 0, &d->M, i, 0); + CopyBlock(1, NumberOfColumns(d->M), &mrow, 0, 0, &d->M, k, 0); + } + if (k < d->places) + { + k = 1; + } + else + { + k = 0; + } + /*See if there are any elements below the main diagonal greater than 0.*/ + for (j = i; j < d->places; j++) + { + if (GetMatrixEl(&d->M, j, i) > 0) break; + } + if (j < d->places) + { + if (j != i) + { + /*Swap rows*/ + CopyBlock(1, NumberOfColumns(d->M), &d->M, i + k, 0, &mrow, 0, 0); + CopyBlock(1, NumberOfColumns(d->M), &d->M, j, 0, &d->M, i + k, 0); + CopyBlock(1, NumberOfColumns(d->M), &mrow, 0, 0, &d->M, j, 0); + } + czero(d, i + k, i); + } + if (k) + { + czero(d, i, i); + } + /*Find out if there exist any elements of M with certain characteristics. + First, any elements in the constraint-related rows of M and in the current + column such that they are greater than 0, and second, any elements in the + same rows and in the mm column that are greater than or equal to 0? + If there are, fail.*/ + for (j = d->places; j < d->places + d->conversionCount; j++) + { + if (GetMatrixEl(&d->M, j, i) > 0) break; + if (GetMatrixEl(&d->M, j, d->TucCount + d->TuoCount)) break; + } + if (j < d->places + d->conversionCount) + { + success = 0; + break; + } + } + DeallocateMatrix(&mrow); +} + +/******************************************************************************* +czero performs the operations related to column zeroing.*/ +void czero(mroadm_d* d, int row, int col) +{ + /*Iterate through the places corresponding to the second group of rows in M + (the ones related to constraints to be converted)*/ + int i, j, x, a, b; + + for (i = d->places; i < d->places + d->conversionCount; i++) + { + /*Get the two places of interest.*/ + /*If the places are of opposite sign, do the processing.*/ + if (GetMatrixEl(&d->M, i, col) * GetMatrixEl(&d->M, row, col) < 0) + { + /*Reduce the row (sort of)*/ + a = GetMatrixEl(&d->M, i, col); + b = GetMatrixEl(&d->M, row, col); + int c = gcdv(0, a, b); + for (j = 0; j < NumberOfColumns(d->M); j++) + { + x = GetMatrixEl(&d->M, i, j) * abs(b) / c; + x += GetMatrixEl(&d->M, row, j) * abs(a) / c; + SetMatrixEl(&d->M, i, j, x); + } + } + } + /*Now iterate through places from the one given as a parameter.*/ + for (i = row; i < row + d->places; i++) + { + /*Process if the places are of opposite sign.*/ + if (GetMatrixEl(&d->M, i, col) * GetMatrixEl(&d->M, row, col) < 0) + { + while (GetMatrixEl(&d->M, i, col)) + { + a = GetMatrixEl(&d->M, i, col); + b = GetMatrixEl(&d->M, row, col); + if (abs(b) > abs(a)) + { + int c = (-b / a) - (! (b % a)); + for (j = 0; j < NumberOfColumns(d->M); j++) + { + x = GetMatrixEl(&d->M, row, j) + c * GetMatrixEl(&d->M, i, j); + SetMatrixEl(&d->M, row, j, x); + } + } + else + { + int c = -a / b; + for (j = 0; j < NumberOfColumns(d->M); j++) + { + x = GetMatrixEl(&d->M, i, j) + c * GetMatrixEl(&d->M, row, j); + SetMatrixEl(&d->M, i, j, x); + } + } + } + } + } +} + +/******************************************************************************* +subtest runs a series of tests on the constraint set based on the contents of M +and modifies the per-constraint status messages as appropriate.*/ +void subtest(mroadm_d* d) +{ + int i, j, flag; + /*Iterate through the places to transform.*/ + for (i = 0; i < d->conversionCount; i++) + { + /*According to the Matlab comments, this tests the marking.*/ + if (GetMatrixEl(&d->M, d->places + i, d->TucCount + d->TuoCount)) flag = 1; + /*Test to see if there are any elements in constraint*Duc > 0.*/ + flag = 0; + for (j = 0; j < d->TucCount && ! flag; j++) + { + if (GetMatrixEl(&d->M, d->places + i, j) > 0) + { + flag = 1; + } + } + /*Test to see if there are any elements in constraint*Duo != 0.*/ + for (j = 0; j < d->TuoCount && ! flag; j++) + { + if (GetMatrixEl(&d->M, d->places + i, d->TucCount + j)) + { + flag = 1; + } + } + if (flag) + { + d->dhow[d->conversionList[i]] = HOW_NOTSOLVED; + } + else + { + d->dhow[d->conversionList[i]] = HOW_OK; + } + } +} + +/******************************************************************************* +BuildSolution builds a final solution given the data from the problem.*/ +mroadm_r BuildSolution(mroadm_d* d) +{ + mroadm_r res; + memset(&res, 0, sizeof(mroadm_r)); + + res.dhow = d->dhow; + /*The overall status message.*/ + int i, j, k; + res.how = HOW_OK; + for (i = 0; i < NumberOfRows(d->L); i++) + { + if (! strcmp(d->dhow[i], HOW_NOTSOLVED)) + { + res.how = HOW_NOTSOLVED; + } + if (! strcmp(d->dhow[i], HOW_INFEASIBLE)) + { + res.how = HOW_IMPOSSIBLE; + break; + } + } + /*R1 and R2.*/ + res.R1 = d->R1; + res.R2 = d->R2; + /*La*/ + /*Do the multiplication. This can be simplified by the fact that R2 is a + diagonal matrix.*/ + matrix R2L; + AllocateMatrixType(2, &R2L, NumberOfRows(d->R2), NumberOfColumns(d->L)); + for (i = 0; i < NumberOfRows(R2L); i++) + { + for (j = 0; j < NumberOfColumns(R2L); j++) + { + k = GetMatrixEl(&d->R2, i, i) * GetMatrixEl(&d->L, i, j); + SetMatrixEl(&R2L, i, j, k); + } + } + /*Do the addition.*/ + res.La = AddMatrix(&d->R1, &R2L, (matrix*) 2); + DeallocateMatrix(&R2L); + /*Build the new B.*/ + res.ba = tcalloc(NumberOfRows(res.La), sizeof(int)); + for (i = 0; i < NumberOfRows(res.La); i++) + { + res.ba[i] = (GetMatrixEl(&d->R2, i, i) * (d->B ? d->B[i] + 1 : 1)) - 1; + } + return res; +} + +/******************************************************************************* +display does some display (if the verbosity threshold is high enough)*/ +void display(char* beginning, char* middle, char* end, int i, int p) +{ + if (is_verbose() >= VRB_MROADM) + { + if (p <= 1) + { + printf("MROADM: %s%s%s\n", beginning, middle, end); + } + else + { + printf("MROADM, constraint %d: %s%s%s\n", i, beginning, middle, end); + } + } +} + +/******************************************************************************* +Finds the absolute value of a number.*/ +int abs(int a) +{ + return (a < 0) ? -a : a; +} Modified: spnbox/spnbox.h =================================================================== --- spnbox/spnbox.h 2009-08-20 13:40:31 UTC (rev 226) +++ spnbox/spnbox.h 2009-08-21 15:06:30 UTC (rev 227) @@ -32,6 +32,9 @@ //may be deallocated, but the individual messages should not be. } ilpadm_r; +/*The type returned by mroadm is identical to the type returned by ilpadm.*/ +typedef ilpadm_r mroadm_r; + typedef struct linenf_r {/*The values returned from linenf*/ matrix Dfm; //The modified Petri net output matrix @@ -206,6 +209,7 @@ void DeallocateIpslv(ipslv_r *data); void DeallocateIpsolve(ipsolve_r *data); void DeallocateIlpadm(ilpadm_r *data); +void DeallocateMroadm(mroadm_r *data); void DeallocateLinenf(linenf_r *data); void DeallocateMsplit(msplit_r *data); void DeallocateNltrans(nltrans_r *data); @@ -238,8 +242,9 @@ various spnbox functions will print output.*/ #define VRB_CHKCONS 4 #define VRB_REDUCE 3 -#define VRB_DP 2 +#define VRB_DP 1 #define VRB_ILPADM 2 +#define VRB_MROADM 2 #define VRB_ASIPH 3 #define VRB_MAX 10 @@ -293,7 +298,7 @@ array, respectively. Same as dpl in Matlab. See ipl, ipCount for defaults. Written for Matlab by Marian V. Iordache, mar...@le.... -Converted to C by Marian V. Iordache and Stephen Camp, ste...@le....*/ +Converted to C by Stephen Camp, ste...@le....*/ ilpadm_r ilpadm(matrix* L, int* b, matrix* D, int TucCount, int* Tuc, int TuoCount, int* Tuo, int* m0); /*ILP_ADM - transformation to admissible constraints based on linear integer programming @@ -334,8 +339,40 @@ program-wide verbosity level. Written for Matlab by Marian V. Iordache, mar...@le.... -Converted to C by Marian V. Iordache and Stephen Camp, ste...@le....*/ +Converted to C by Stephen Camp, ste...@le....*/ +mroadm_r mroadm(matrix* L, int* B, matrix* D, int* Tuc, int TucCount, int* Tuo, int TuoCount, int* m0); +/* +MRO_ADM - transformation to admissible constraints based on matrix row + operations + +[La, ba, R1, R2, how, dhow] = mro_adm(L, b, D, Tuc, Tuo, m0, vrb) + +The function transforms a marking constraint L*places <= b to an admissible +marking constraint (R1 + R2*L)*places <= R2*(b+1). If the transformation is +possible for the given initial marking, 'ok' is returned in a variable +how; else 'impossible' is returned; similarly, dhow{i} is 'ok' if the +transformation of the constraint i of Lm <= b was possible. + +D - the incidence matrix +Tuc - the uncontrollable transitions (e.g. for Tuc = [2, 5], the second and + the fifth columns of D correspond to uncontrollable transitions +Tuo - the unobservable transitions +m0 - the initial marking +vrb - use vrb = 0 to suppress messages. Default is vrb = 1. + +Use m0 = [] or only the first five arguments if the initial marking is +not of interest. +Usage in C: +mroadm_r mroadm(matrix* L, int* B, matrix* D, int* Tuc, int TucCount, int* Tuo, +int TuoCount, int* m0); +The parameters have the same meaning as in Matlab with the same notes and +exceptions as for ilpadm. + +Written for Matlab by Marian V. Iordache, mar...@le... +Converted to C by Stephen Camp, ste...@le... +*/ + supervis_r supervis(matrix* PlantIn, matrix* PlantOut, matrix* L); /* supervis_r supervis(const matrix PlantIn, const matrix PlantOut, const matrix L) @@ -351,7 +388,7 @@ This is the approach in the papers by Moody and Yamalidou. Written for Matlab by Marian V. Iordache, mar...@le... - Converted to C by Marian V. Iordache & Stephen Camp, ste...@le... + Converted to C by Stephen Camp, ste...@le... */ ipsolve_r ipsolve(matrix* L, double* B, double* f, short int *IntList, double *ub, double *lb, short int *ctype); @@ -389,7 +426,7 @@ This interface to the LP_SOLVE package has been written by Marian V. Iordache, mar...@le.... -It was converted to C by Marian V. Iordache and Stephen Camp, ste...@le....*/ +It was converted to C by Stephen Camp, ste...@le....*/ /*Most complete C syntax (all optional parameters included): ipsolve_r ipsolve(int numberOfArguments, matrix *L, double *B, double *f, short *IntList, double *ub, double *lb, short *ctype) All parameters after the first three are optional.*/ @@ -458,7 +495,7 @@ ms0 = bf - Lf*m0 - Cf*v0 Written by Marian V. Iordache, mar...@le... -Converted to C by Marian V. Iordache and Stephen Camp, ste...@le...*/ +Converted to C by Stephen Camp, ste...@le...*/ int* isadm(matrix* Dm, matrix* Dp, matrix* L, int* b, int* m0, matrix* F, matrix* C, int TucCount, int* Tuc, int TuoCount, int* Tuo); /* @@ -513,7 +550,7 @@ See LINENF and PNCGRAPH. Written for Matlab by Marian V. Iordache, mar...@le.... -Converted to C by Marian V. Iordache and Stephen Camp, ste...@le.... +Converted to C by Stephen Camp, ste...@le.... */ nltrans_r nltrans(matrix* D, int* UnraisableTransitions, int urtCount); @@ -540,7 +577,7 @@ of elements in the array. Written by Marian V. Iordache, mar...@le.... -Converted to C by Marian V. Iordache and Stephen Camp, ste...@le... +Converted to C by Stephen Camp, ste...@le... */ pn2acpn_r pn2acpn(matrix* Dm, matrix* Dp, int* Mask, matrix* MX, matrix* L0, matrix* L, int *ipl, int ipCount, int* dpl, int dpCount); @@ -580,7 +617,7 @@ M. Iordache -- Sep. 4, 2000 revised on Oct. 24, 2001 -Converted to C by Marian V. Iordache and Stephen Camp, ste...@le... +Converted to C by Stephen Camp, ste...@le... Stephen Camp -- Jun. 18, 2009 */ @@ -631,7 +668,7 @@ This is the extension for extended asymmetric choice nets; M. Iordache, July 2003 -Converted to C by M. Iordache and Stephen Camp, Ste...@le.... +Converted to C by Stephen Camp, Ste...@le.... Matlab code was under construction at time of conversion to C. Stephen Camp, June 2009 */ @@ -666,7 +703,7 @@ The C implementation may be changed to implement the newer CHK_CON.M sometime in the future. Written by Marian V. Iordache, mar...@le.... -Converted to C by Marian Iordache and Stephen Camp, ste...@le.... +Converted to C by Stephen Camp, ste...@le.... */ reduce_r reduce(matrix* L0, int* B0); @@ -686,7 +723,7 @@ L0 and B0 are L and B, respectively, from the Matlab version. Written for Matlab by Marian V. Iordache, mar...@le.... -Converted to C by Marian Iordache and Stephen Camp, ste...@le.... +Converted to C by Stephen Camp, ste...@le.... */ actn_r actn(matrix* Dm, matrix* Dp, int* X, int XCount, matrix *Dcm, matrix *Dcp, int update, int checkUnique); @@ -727,7 +764,7 @@ structure will be set to 0 regardless of the actual state of the result. Written for Matlab by Marian V. Iordache, mar...@le.... -Converted to C by Marian Iordache and Stephen Camp, ste...@le.... +Converted to C by Stephen Camp, ste...@le.... */ tactn_r tactn(matrix* Dm, matrix* Dp, int* IncludeT, int IncludeTCount, int* ExcludeT, int ExcludeTCount, matrix *Dcm, matrix *Dcp, int checkUnique); @@ -801,7 +838,7 @@ Marian V. Iordache, Sep. 5, 2000. Revised on Oct. 24, 2001, and enhanced in February 2002. -Converted to C by Marian V. Iordache and Stephen Camp, ste...@le.... +Converted to C by Stephen Camp, ste...@le.... */ issiph_r issiph(matrix *Dm, matrix *Dp, void *PlaceSet, int MultiplePlaceSets); @@ -827,7 +864,7 @@ to an integer array, where each integer is a flag as described above. Written for Matlab by Marian V. Iordache, mar...@le.... -Converted to C by Marian V. Iordache and Stephen Camp, ste...@le.... +Converted to C by Stephen Camp, ste...@le.... */ asiph_r asiph(matrix *Dm, matrix *Dp, int* list, int listCount, matrix *PS, matrix *Dma, matrix *Dpa); @@ -865,7 +902,7 @@ See also MSIPH, SIPH2, MINSIPH Written for Matlab by Marian V. Iordache, mar...@le... -Converted to C by Marian V. Iordache and Stephen Camp, ste...@le... +Converted to C by Stephen Camp, ste...@le... lst feature is not yet fully implemented! (the case when a source place appears in the list has not been considered). @@ -931,7 +968,7 @@ how - is set to 0 if no admissible constraint could be found. Written for Matlab by Marian V. Iordache, mar...@le.... -Converted to C by Marian V. Iordache and Stephen Camp, ste...@le.... +Converted to C by Stephen Camp, ste...@le.... C Usage: The admcon function takes a pointer to a structure of type admcon_p, which @@ -973,7 +1010,7 @@ [str] = avpr(x,var,1) Written for Matlab by Marian V. Iordache, mar...@le.... -Converted to C by Marian V. Iordache and Stephen Camp, ste...@le.... +Converted to C by Stephen Camp, ste...@le.... C Usage: Parameters have the same meaning and names as in Matlab. If chr is a null pointer it will default to m, as in Matlab. @@ -996,7 +1033,7 @@ [str] = fvpr(x,2) Written for Matlab by Marian V. Iordache, mar...@le.... -Converted to C by Marian V. Iordache and Stephen Camp, ste...@le.... +Converted to C by Stephen Camp, ste...@le.... C Usage: Parameters have the same meaning and names as in Matlab. Use mode = DISPLAY_MATRIX for vector a pointer to a matrix. length is ignored. Use mode = DISPLAY_INTS for vector a pointer to an array of integers. @@ -1087,7 +1124,7 @@ their column number in the incidence matrix. Written for Matlab by Marian V. Iordache, mar...@le... -Converted to C by Marian V. Iordache and Stephen Camp, ste...@le... +Converted to C by Stephen Camp, ste...@le... Marian V. Iordache, March 1999 @@ -1148,8 +1185,7 @@ only parameter and returns the solution matrix. Since the pntool matrix type does not support non-integer matrices, nothing has been implemented to deal with them. -Converted from Matlab to C by Marian V. Iordache, mar...@le..., and -Stephen Camp, ste...@le.... +Converted to C by Stephen Camp, ste...@le.... */ #endif Modified: spnbox/tests/Makefile =================================================================== --- spnbox/tests/Makefile 2009-08-20 13:40:31 UTC (rev 226) +++ spnbox/tests/Makefile 2009-08-21 15:06:30 UTC (rev 227) @@ -43,6 +43,7 @@ ADMCON=admcon.o $(EXTENDEDMATRIX) $(IPSOLVE) ASIPH=asiph.o $(ACTN) $(EXTENDEDMATRIX) ILPADM=ilpadm.o $(IPSOLVE) +MROADM=mroadm.o $(GCDV) LINENF=linenf.o $(ILPADM) NLTRANS=nltrans.o $(IPSOLVE) PN2EACPN=pn2eacpn.o $(NLTRANS) @@ -55,7 +56,7 @@ COMMONHEADER=../spnbox.h test.h ../../pnheaders/general.h ../../pnheaders/pns.h ../../pnheaders/matrix.h ../matrixmath.h ../MemoryManager.h StructuredIO.h #Targets -all: avpr dp dp4 extendedmatrix fvpr gcdv invar ipslv ipsolve isadm issiph msplit matrixmath pn2acpn supervis actn admcon asiph ilpadm linenf nltrans pn2eacpn reduce tactn +all: avpr dp dp4 extendedmatrix fvpr gcdv invar ipslv ipsolve isadm issiph msplit matrixmath pn2acpn supervis actn admcon asiph ilpadm mroadm linenf nltrans pn2eacpn reduce tactn avpr: test-avpr.o $(AVPR) $(COMMON) $(COMPILER) -o avpr.exe test-avpr.o $(AVPR) $(COMMON) extendedmatrix: test-extendedmatrix.o $(EXTENDEDMATRIX) $(COMMON) @@ -89,7 +90,9 @@ asiph: test-asiph.o $(COMMON) $(ASIPH) $(COMPILER) -o asiph.exe test-asiph.o $(COMMON) $(ASIPH) ilpadm: test-ilpadm.o $(COMMON) $(ILPADM) - $(COMPILER) -o ilpadm.exe test-ilpadm.o $(COMMON) $(ILPADM) + $(COMPILER) -o ilpadm.exe test-ilpadm.o $(COMMON) $(ILPADM) +mroadm: test-mroadm.o $(COMMON) $(MROADM) + $(COMPILER) -o mroadm.exe test-mroadm.o $(COMMON) $(MROADM) linenf: test-linenf.o $(COMMON) $(LINENF) $(COMPILER) -o linenf.exe test-linenf.o $(COMMON) $(LINENF) nltrans: test-nltrans.o $(COMMON) $(NLTRANS) @@ -152,6 +155,8 @@ $(MEMWCOMP) -c ../matrixmath.c MemoryManager.o: ../MemoryManager.h ../MemoryManager.c ../../pnheaders/general.h ../../pnheaders/matrix.h $(MEMWCOMP) -c ../MemoryManager.c +mroadm.o: ../mroadm.c ../spnbox.h ../../pnheaders/matrix.h ../../pnheaders/general.h ../matrixmath.h + $(MEMWCOMP) -c ../mroadm.c msplit.o: ../spnbox.h ../../pnheaders/matrix.h ../matrixmath.h ../MemoryManager.h ../msplit.c $(MEMWCOMP) -c ../msplit.c nltrans.o: ../nltrans.c ../spnbox.h ../../pnheaders/matrix.h ../matrixmath.h ../MemoryManager.h @@ -204,6 +209,8 @@ $(MEMWCOMP) -c test-linenf.c test-matrixmath.o: test-matrixmath.c $(COMMONHEADER) $(MEMWCOMP) -c test-matrixmath.c +test-mroadm.o: test-mroadm.c $(COMMONHEADER) + $(MEMWCOMP) -c test-mroadm.c test-msplit.o: test-msplit.c $(COMMONHEADER) $(MEMWCOMP) -c test-msplit.c test-nltrans.o: test-nltrans.c $(COMMONHEADER) Added: spnbox/tests/test-mroadm.c =================================================================== --- spnbox/tests/test-mroadm.c (rev 0) +++ spnbox/tests/test-mroadm.c 2009-08-21 15:06:30 UTC (rev 227) @@ -0,0 +1,60 @@ +#include "test.h" + +int main(int argc, char* argv[]) +{ + + /*all correct solutions will satisfy La*m0 <= ba, La*D(:, Tuc) <= 0, and La*D(:, Tuo) = 0. + Also, a correct solution will satisfy that for all nonnegative integer vectors m, if La*m <= ba, then L*m <= b.*/ + + char InDesc[] = "matrix D, indexarray Tuc, indexarray Tuo, matrix L, arrayi B, arrayi m0"; + char OutDesc[] = "string Message, matrix La, arrayi Ba"; + + mroadm_r answer; + matrix D, L; + int BCount, m0Count, TucCount, TuoCount; + int *B, *m0, *Tuc, *Tuo, *InFilled, OutFilled[3]; + FILE* input; + MemoryManager mem; + + mem = CreateMemoryManager(10, 10, 0, 0); + + /*Set the verbosity level to maximum*/ + setverbose(VRB_MAX); + + if (! (input = ParseCmdLine(argc, argv))) + { + return 0; + } + + while (ParseStructure(input, InDesc, &InFilled, &mem, &D, &Tuc, &TucCount, &Tuo, &TuoCount, &L, &B, &BCount, &m0, &m0Count)) + { + /*Display the problem.*/ + DisplayStructure(InDesc, InFilled, &D, Tuc, TucCount, InFilled[0] ? NumberOfColumns(D) : 0, Tuo, TuoCount, InFilled[0] ? NumberOfColumns(D) : 0, &L, B, BCount, m0, m0Count); + + /*Solve the problem.*/ + answer = mroadm(InFilled[3] ? &L : 0, InFilled[4] ? B : 0, InFilled[0] ? &D : 0, InFilled[1] ? Tuc : 0, TucCount, InFilled[2] ? Tuo : 0, TuoCount, InFilled[5] ? m0 : 0); + + OutFilled[0] = 1; + OutFilled[1] = 1; + if (answer.ba) + { + OutFilled[2] = 1; + } + else + { + OutFilled[2] = 0; + } + + /*Show the solution*/ + printf("\nSolution:\n"); + DisplayStructure(OutDesc, OutFilled, answer.how, &answer.La, answer.ba, NumberOfRows(answer.La)); + printf("--------------------------------------------------------------------------------\n"); + + /*Clear and re-initialize dynamic memory log and loop again.*/ + FreeMemory(&mem); + DeallocateIlpadm(&answer); + mem = CreateMemoryManager(10, 10, 0, 0); + } + FreeMemory(&mem); + return 0; +} Added: spnbox/tests/test-mroadm.txt =================================================================== --- spnbox/tests/test-mroadm.txt (rev 0) +++ spnbox/tests/test-mroadm.txt 2009-08-21 15:06:30 UTC (rev 227) @@ -0,0 +1,146 @@ +echo Example 1 +D 3 3 +-1 0 1 +1 -1 0 +0 1 -1 + +L 1 3 +0 0 1 + +B 1 1 + +m0 3 +3 0 0 + +Tuc 1 +1 + +done + +echo Example 2 +D 3 3 +-1 0 1 +1 -1 0 +0 1 -1 + +m0 3 +3 0 0 + +Tuc 1 +1 + +L 1 3 +0 0 1 + +B 1 1 + +done + +echo Example 3 +D 4 4 +-1 -1 0 1 +1 0 -1 0 +0 1 -1 0 +0 0 1 -1 + +m0 4 +3 0 0 0 +Tuc 1 +2 + +L 1 4 +0 0 0 1 + +B 1 1 +done + +echo Example 4 +D 4 4 +-1 0 0 1 +0 -1 0 2 +2 1 -2 0 +0 0 1 -2 + +m0 4 +1 2 0 2 + +L 1 4 +0 0 0 1 + +B 1 2 + +Tuc 1 2 + +done +echo Example 5 +D 3 3 +-1 1 0 +-1 0 1 +2 -1 -1 + +L 2 3 +-1 0 -1 +0 -1 -1 + +B 2 +-1 -1 + +Tuo 1 0 + +m0 3 +1 1 0 + +done + +echo Example 6 +echo This uses the data from Example 5 but supplies no initial marking. +D 3 3 +-1 1 0 +-1 0 1 +2 -1 -1 + +L 2 3 +-1 0 -1 +0 -1 -1 + +B 2 +-1 -1 + +Tuo 1 0 + +done + +echo Example 7 +echo This reuses the data from Example 2 but supplies no constraint vector. +D 3 3 +-1 0 1 +1 -1 0 +0 1 -1 + +m0 3 +3 0 0 + +Tuc 1 +1 + +L 1 3 +0 0 1 + +done + +echo Example 8 +echo This reuses the data from Example 2 but supplies neither constraint vector +echo nor initial marking. +D 3 3 +-1 0 1 +1 -1 0 +0 1 -1 + +Tuc 1 +1 + +L 1 3 +0 0 1 + +done +quit This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |