From: Rainer M. <ra...@tb...> - 2006-04-19 15:07:06
|
Andrew > Mutually recursive functions require forward declarations e.g.: Of course. Thanks! > if a forward declaration is required or if we decide we must have > private prototypes > (my preference no!) > then the private prototypes go in the relevant C file at the top of the > file Can you explain why you don't like this? Is this a general style question or can there be any problems with the redundant declarations? As said, I like to have all existing functions listed somewhere to keep the overview. But if this is not necessary/considered unstylish/problematic in general, then I'll happily agree that redundancies are bad - well, at least in code :-) . Rainer On Wed, 19 Apr 2006, Andrew Finney wrote: > Rainer > > you wrote: > >> Can't you always just write the function before it is used? >> Does this also >> work for recursive functions? Sorry for my illiteracy with such basic >> stuff :-) > > Mutually recursive functions require forward declarations e.g.: > > void f(); > > void g() > { > f(); > } > > void f() > { > g(); > } > >>> d) any other case is public! >> >> I.e. either in ...internal.h or in API .h files, right? > > if a forward declaration is required or if we decide we must have > private prototypes > (my preference no!) > then the private prototypes go in the relevant C file at the top of the > file > > otherwise > > if the function is private to the library it goes in XXX_internal.h > > otherwise > > the function must be public/API so it goes in XXX.h > > OK? > > yours Andrew > >> -----Original Message----- >> From: Rainer Machne [mailto:ra...@tb...] >> Sent: 19 April 2006 15:25 >> To: Andrew Finney >> Cc: SOSlib Development >> Subject: RE: [SOSlib-devel] RE: comment on proposed exact >> event implementation[Scanned] >> >> Andrew >> >> On Wed, 19 Apr 2006, Andrew Finney wrote: >>>> Would people support a convention that we still declare >> such private >>>> functions in the header of the c file, in which they are used? >>>> >>> >>> Hmmm >>> >>> Do you mean the .h file or the top section of the .c file? >> >> I meant the top section of the .c file. >> >>> >>> my preference is for >>> >>> a) no redundant prototypes (simple is best) i.e. only used where a >>> forward declaration is needed >> >> Personally, I like to have nice lists of all existing functions, i.e. >> header files (.h) plus declarations at the top section of .c >> files for static functions. It just makes it easier for me to >> recall the exact order of function calls, without parsing >> throught the source. >> >> However, as it is not necessary for doxygen, we could remove >> all declarations of static functions in .c file, if people wish so. >> >> >>> b) if they are necessary they go in the .c file as a first resort >> >> I can't think of a case where this would be necessary, if the >> function is >> only used within this .c file. >> >> Can't you always just write the function before it is used? >> Does this also >> work for recursive functions? Sorry for my illiteracy with such basic >> stuff :-) >> >> >>> c) if they are required to be in a header but they are not >> part of the >>> API >>> they should go in a header like: intergatorInstance_internal.h >>> In the long term we ought to separate the API prototypes from the >>> internal prototypes in two separate sets of headers so that >>> applications >>> can clearly see what is the API. >> >> Agree. >> >> >>> d) any other case is public! >> >> I.e. either in ...internal.h or in API .h files, right? >> >>> e) don't use SBML_ODESOLVER_API unless the function is strictly part >>> of the API (I'm guilty too) >> >> Agree. >> >> >>> >>>> This would also allow to put private functions all together >>>> outside of a doxygen documentation block. Otherwise the >>>> functions will be included in the documentation, or have each >>>> to be surrounded by end/start tags for documentation blocks. >>> >>> Can you explain this in detail please? >>> What do you mean 'outside of a doxygen documentation block'? >> >> >> A doxygen documentation block starts with >> >> /*@{*/ >> >> and ends with >> >> /*}@*/ >> >> >> However, I was wrong with the above statement. >> >> If the function does NOT contain any >> >> /** or /*! >> >> comments, then it will NOT be part of the documentation. >> >> Thus static and non API functions should ONLY use /* comments. >> >> I just corrected the doxygen template c file at >> http://www.tbi.univie.ac.at/~raim/odeSolver/data/doxygenComments.c >> >> Rainer >> >> >>> >>>> -----Original Message----- >>>> From: Rainer Machne [mailto:ra...@tb...] >>>> Sent: 19 April 2006 14:48 >>>> To: Andrew Finney >>>> Cc: SOSlib Development >>>> Subject: RE: [SOSlib-devel] RE: comment on proposed exact >>>> event implementation[Scanned] >>>> >>>> Andrew >>>> >>>> On Wed, 19 Apr 2006, Andrew Finney wrote: >>>> >>>>> Rainer >>>>> >>>>> IntegratorInstance_processEventsAndAssignments >>>>> >>>>> doesn't have a declaration: its not required as its not >> part of the >>>>> API the SBML_ODESOLVER_API qualification is redundant - I >>>> guess that >>>>> confused you >>>> >>>> Exactly, that was it. Sorry for the confusion. >>>> >>>> I understand, that it isn't required to declare such >>>> functions, if they are defined before the are used. >>>> >>>> Would people support a convention that we still declare such >>>> private functions in the header of the c file, in which >> they are used? >>>> >>>> This would also allow to put private functions all together >>>> outside of a doxygen documentation block. Otherwise the >>>> functions will be included in the documentation, or have each >>>> to be surrounded by end/start tags for documentation blocks. >>>> >>>> Rainer >>>> >>>> >>>>> That's my fault. Remind me to update the dynalically >>>> compiled version >>>>> of this function. >>>>> >>>>> you're probably OK as far as CVS goes >>>>> >>>>> Andrew >>>>> >>>>>> -----Original Message----- >>>>>> From: Rainer Machne [mailto:ra...@tb...] >>>>>> Sent: 19 April 2006 14:35 >>>>>> To: Andrew Finney >>>>>> Cc: SOSlib Development >>>>>> Subject: Re: [SOSlib-devel] RE: comment on proposed exact event >>>>>> implementation[Scanned] >>>>>> >>>>>> >>>>>> On Wed, 19 Apr 2006, Andrew Finney wrote: >>>>>> >>>>>>> Rainer >>>>>>> >>>>>>> strange >>>>>>> >>>>>>> I have the declaration at >>>>>>> SBML_odeSolver\src\sbmlsolver\integratorInstance.h line 143 >>>>>> >>>>>> At line 143 I only have a declaration for >>>>>> IntegratorInstance_integrateOneStepWithoutEventProcessing >>>>>> >>>>>> but can't find a declaration for >>>>>> IntegratorInstance_processEventsAndAssignments >>>>>> >>>>>>> >>>>>>> my CVS is saying that I'm in sync >>>>>>> >>>>>>> what do you have? >>>>>> >>>>>> mine too. that's really strange. Maybe cvs update checks only for >>>>>> version numbers and there is a problem with that? >>>>>> >>>>>> I have v 1.27 2006/04/11 13:10:45 afinney >>>>>> >>>>>> Strangely, the only CVS has version 1.26 from 5 weeks ago, while >>>>>> other files there are more recent. >>>>>> >>>>>> Rainer >>>>>> >>>>>>> >>>>>>> yours Andrew >>>>>>> >>>>>>>> -----Original Message----- >>>>>>>> From: Rainer Machne [mailto:ra...@tb...] >>>>>>>> Sent: 19 April 2006 12:42 >>>>>>>> To: Andrew Finney >>>>>>>> Cc: SOSlib Development >>>>>>>> Subject: RE: comment on proposed exact event >>>>>> implementation[Scanned] >>>>>>>> >>>>>>>> Andrew >>>>>>>> >>>>>>>> I have correct the simple event detection, so that it >>>> doesn't set >>>>>>>> trigger flags to 0, if the trigger is actually still fired. >>>>>>>> >>>>>>>> Some questions regarding the new code: >>>>>>>> >>>>>>>> Now that enginge->processEvents is set either to 1 or to 0 in >>>>>>>> II_integrateOneStep and >>>> II_integrateOneStepWithoutEventProcessing, >>>>>>>> respectively, the functions >>>>>>>> >>>>>>>> II_simpleOneStep and II_cvodeOneStep >>>>>>>> >>>>>>>> shouldn't be public anymore. >>>>>>>> >>>>>>>> Before this new switch, they were public, so that >>>>>> applications which >>>>>>>> knew what type of solver is required (currently ODEs or no >>>>>> ODEs, but >>>>>>>> eventually also DAEs or even stochastic solvers) can use these >>>>>>>> `solver'OneStep functions directly. >>>>>>>> >>>>>>>> Should we remove these functions from the API or should we >>>>>> keep the >>>>>>>> possibility to use different solvers directly? >>>>>>>> >>>>>>>> In the second case we need to move the >>>>>> engine->processEvents setting >>>>>>>> to some other place! >>>>>>>> >>>>>>>> Also I didn't find a function declaration for >>>>>>>> II_integrateOneStepWithoutEventProcessing. I guess you >>>> wanted this >>>>>>>> function to be public, or did you just use it for testing? >>>>>>>> >>>>>>>> >>>>>>>> Rainer >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> On Wed, 19 Apr 2006, Andrew Finney wrote: >>>>>>>> >>>>>>>>> Rainer >>>>>>>>> >>>>>>>>> I guess you need to go ahead and modify the code. >>>>>>>>> Any performance hit is my problem. >>>>>>>>> >>>>>>>>> yours Andrew >>>>>>>>> >>>>>>>>>> -----Original Message----- >>>>>>>>>> From: Rainer Machne [mailto:ra...@tb...] >>>>>>>>>> Sent: 19 April 2006 11:47 >>>>>>>>>> To: Andrew Finney >>>>>>>>>> Subject: RE: comment on proposed exact event >>>>>>>> implementation[Scanned] >>>>>>>>>> >>>>>>>>>> Andrew >>>>>>>>>> >>>>>>>>>>> I'm more worried about the performance hit of >>>>>> evaluating the not >>>>>>>>>>> trigger expression. >>>>>>>>>> >>>>>>>>>> Ok, I still don't get what you mean. >>>>>>>>>> >>>>>>>>>> Do you mind, if I correct the current event handling - >>>>>> as outlined >>>>>>>>>> two emails below - and submit it, or do you think it would >>>>>>>> slow down >>>>>>>>>> your models? >>>>>>>>>> >>>>>>>>>> Rainer >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> On Wed, 12 Apr 2006, Andrew Finney wrote: >>>>>>>>>> >>>>>>>>>>> Rainer >>>>>>>>>>> >>>>>>>>>>> you're doing the right thing don't worry :-) >>>>>>>>>>> >>>>>>>>>>>> -----Original Message----- >>>>>>>>>>>> From: Rainer Machne [mailto:ra...@tb...] >>>>>>>>>>>> Sent: 12 April 2006 17:53 >>>>>>>>>>>> To: Andrew Finney >>>>>>>>>>>> Cc: Christoph Flamm >>>>>>>>>>>> Subject: RE: comment on proposed exact event >>>>>>>>>> implementation[Scanned] >>>>>>>>>>>> >>>>>>>>>>>> Andrew >>>>>>>>>>>> >>>>>>>>>>>> On Wed, 12 Apr 2006, Andrew Finney wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Rainer >>>>>>>>>>>>> >>>>>>>>>>>>> Our model is based on simple Jarnac code. >>>>>>>>>>>>> >>>>>>>>>>>>> I'm more worried about the performance hit of >>>>>>>> evaluating the not >>>>>>>>>>>>> trigger expression. >>>>>>>>>>>> >>>>>>>>>>>> I don't really understand what you mean. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> You mean the additional evaluations when >>>>>>>>>>>> >>>>>>>>>>>>>>> else >>>>>>>>>>>>>>> data->trigger[i] = 0; >>>>>>>>>>>> >>>>>>>>>>>> would be replaced by >>>>>>>>>>>> >>>>>>>>>>>>>>> else if ( evaluateAST(trigger, data) == 0 ) >>>>>>>>>>>>>>> data->trigger[i] = 0; >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> ?? >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> The double evaluation could be avoided by putting the >>>>>>>> evaluations >>>>>>>>>>>> within the if/else blocks: >>>>>>>>>>>> >>>>>>>>>>>> if ( data->trigger[i] == 0 ) >>>>>>>>>>>> { >>>>>>>>>>>> if ( evaluateAST(trigger, data) ) >>>>>>>>>>>> { >>>>>>>>>>>> data->trigger[i] = 1; >>>>>>>>>>>> } >>>>>>>>>>>> } >>>>>>>>>>>> else /* only if trigger is 1 */ >>>>>>>>>>>> { >>>>>>>>>>>> if ( !evaluateAST(trigger, data) ) >>>>>>>>>>>> { >>>>>>>>>>>> data->trigger[i] = 0; >>>>>>>>>>>> } >>>>>>>>>>>> } >>>>>>>>>>>> >>>>>>>>>>>> but I don't see a way around the evaluation of >> each trigger. >>>>>>>>>>>> >>>>>>>>>>>> Do I get something wrong? >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Rainer >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> yours Andrew >>>>>>>>>>>>> >>>>>>>>>>>>>> -----Original Message----- >>>>>>>>>>>>>> From: Rainer Machne [mailto:ra...@tb...] >>>>>>>>>>>>>> Sent: 12 April 2006 17:37 >>>>>>>>>>>>>> To: Andrew Finney >>>>>>>>>>>>>> Cc: Christoph Flamm >>>>>>>>>>>>>> Subject: RE: comment on proposed exact event >>>>>>>>>>>> implementation[Scanned] >>>>>>>>>>>>>> >>>>>>>>>>>>>> Andrew >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Wed, 12 Apr 2006, Andrew Finney wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Rainer >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> below is all correct >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> it will make our model run slower or even >> incorrectly but >>>>>>>>>>>> I'll work >>>>>>>>>>>>>>> around it perhaps we'll need yet another option. >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> The current implementation >>>>>>>>>>>>>> >>>>>>>>>>>>>>> if ( data->trigger[i] == 0 && >>>> evaluateAST(trigger, data) ) >>>>>>>>>>>>>>> fired++; (leading to assignment execution in >>>>>> calling code) >>>>>>>>>>>>>>> data->trigger[i] = 1; >>>>>>>>>>>>>>> else >>>>>>>>>>>>>>> data->trigger[i] = 0; >>>>>>>>>>>>>> >>>>>>>>>>>>>> means that event triggers are set to 0, whenever they >>>>>>>>>> have already >>>>>>>>>>>>>> been fired, even when the trigger is still true. >>>>>>>>>>>>>> >>>>>>>>>>>>>> That means that events are again executed in the >> time step >>>>>>>>>>>>>> afterwards, even if they have been true ever since >>>>>> their last >>>>>>>>>>>>>> execution. >>>>>>>>>>>>>> It is a completely wrong interpretation of events! >>>>>>>>>>>>>> >>>>>>>>>>>>>> Does your model really require this? >>>>>>>>>>>>>> >>>>>>>>>>>>>> As in the very old version, triggers should be >>>>>>>> evaluated before >>>>>>>>>>>>>> integration and only set to 0 if they are really false. >>>>>>>>>>>>>> >>>>>>>>>>>>>> Rainer >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>>>> -----Original Message----- >>>>>>>>>>>>>>>> From: Rainer Machne [mailto:ra...@tb...] >>>>>>>>>>>>>>>> Sent: 12 April 2006 17:15 >>>>>>>>>>>>>>>> To: Andrew Finney >>>>>>>>>>>>>>>> Cc: Christoph Flamm >>>>>>>>>>>>>>>> Subject: RE: comment on proposed exact event >>>>>>>>>>>>>> implementation[Scanned] >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Andrew >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Why do we cheat? As I remember, we do exactly the >>>>>>>>>>>> above for the >>>>>>>>>>>>>>>>>> inexact event handling! >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> I have not got the code in front of me... >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> It was more correct in a very old version and >> seems to be >>>>>>>>>>>>>> incorrect >>>>>>>>>>>>>>>> for a while now! >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> In the former file odeIntegrate.c did: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> the function integrate() did >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> for ( i=0; i<data->nt; i++ ) { >>>>>>>>>>>>>>>> data->flag[i] = >> evaluateAST(data->trigger[i],data); >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> before integration, i.e. evaluate trigger state at >>>>>>>> time 0. So >>>>>>>>>>>>>>>> triggers that are already true are set to 1, >> others to 0. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Then in the integration loop the function checkTrigger >>>>>>>>>>>> was called >>>>>>>>>>>>>>>> after the CVode call. It did >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> if(evaluateAST(data->trigger[i],data)==0) >>>>>>>>>>>>>>>> { >>>>>>>>>>>>>>>> data->flag[i] = 0; >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> else if((data->flag[i]==0) && >>>>>>>>>>>>>>>> (evaluateAST(data->trigger[i],data)==1)) >>>>>>>>>>>>>>>> { >>>>>>>>>>>>>>>> data->flag[i] = 1; >>>>>>>>>>>>>>>> ... >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> So trigger flags were set to 0 only when the trigger >>>>>>>>>>>> condition is >>>>>>>>>>>>>>>> really false and to 1 as soon as they become true. >>>>>>>> They stay 1 >>>>>>>>>>>>>>>> (eventually having been set at time 0) as long >>>> as they are >>>>>>>>>>>>>> true, but >>>>>>>>>>>>>>>> their assignments are only evaluated when they >>>>>> were 0 before. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> This should do it, right? >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> In the current version it is wrong: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> It's the line 636 in integratorInstance >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> if ( data->trigger[i] == 0 && >>>>>> evaluateAST(trigger, data) ) >>>>>>>>>>>>>>>> fired++; (leading to assignment execution in >>>>>>>> calling code) >>>>>>>>>>>>>>>> data->trigger[i] = 1; >>>>>>>>>>>>>>>> else >>>>>>>>>>>>>>>> data->trigger[i] = 0; >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> I.e. it misses the evaluation for false >>>> triggers, but just >>>>>>>>>>>>>> sets any >>>>>>>>>>>>>>>> trigger false that was true, even if they are >> still true. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> It might just require to add >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> else if ( evaluateAST(trigger, data) == 0 ) >>>>>>>>>>>>>>>> data->trigger[i] = 0; >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> instead of the simple else. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Right? >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> We should correct that for the simple event handling! >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> I have to think about the other stuff. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Rainer >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> you wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> This can become tricky. As far as I >> understood the root >>>>>>>>>>>>>> finder, it >>>>>>>>>>>>>>>>>> stops integrating at the time where it found >> the root. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Thus we might have to include a code >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> if ( triggerWasTrue ) >>>>>>>>>>>>>>>>>> rootFunction = 1.0; >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> to suppress root finding for triggers that are >>>>>>>> already true. >>>>>>>>>>>>>>>>>> The same should probably be done for combined >>>>>>>>>>>> triggers, for the >>>>>>>>>>>>>>>>>> expression that becomes true first and needs >>>> to wait for >>>>>>>>>>>>>> the second >>>>>>>>>>>>>>>>>> (or all) other inequalities of the trigger. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> My understanding is that the root finder only detects >>>>>>>>>>>> transitions >>>>>>>>>>>>>>>>> because x < 10 maps to x - 10 == 0. The root is only >>>>>>>>>>>> true at the >>>>>>>>>>>>>>>>> transition not at all points x < 10. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> I think we need to be very careful about when and how >>>>>>>>>>>> we suppress >>>>>>>>>>>>>>>>> root expressions. Any suppression inevitably >> means you >>>>>>>>>>>>>> potentially >>>>>>>>>>>>>>>>> miss a transition. Having written that I >> don't know the >>>>>>>>>>>>>> theory but >>>>>>>>>>>>>>>>> I intuitively think that its not possible to resolve >>>>>>>>>> very close >>>>>>>>>>>>>>>>> transitions. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> The issues that I think we need to look out for are: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> a) restarting integration where the root is still true >>>>>>>>>>>>>>>>> we might get stuck there! >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Is that what you were worried about? >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> either fingers crossed cvode will ignore >> the initial >>>>>>>>>>>>>>>> state when root >>>>>>>>>>>>>>>>> finding >>>>>>>>>>>>>>>>> or if not we might need to nudge forward by >>>> an epsilon >>>>>>>>>>>>>> with root >>>>>>>>>>>>>>>>> finding switched off :-( >>>>>>>>>>>>>>>>> (the algorithm I posted didn't include >>>> this concept) >>>>>>>>>>>>>>>>> this might be a good idea since it forces time >>>>>>>>>>>> forward and the >>>>>>>>>>>>>>>>> simulation out of deadlocks. >>>>>>>>>>>>>>>>> the problem is choosing an epsilon. I >> guess it could >>>>>>>>>>>>>> be a very >>>>>>>>>>>>>>>>> small fraction of the time step length. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Perhaps this should be a constant set by >> the user: it >>>>>>>>>>>>>>>> represents the >>>>>>>>>>>>>>>>> minimum gap between event transitions. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> b) the integration, correctly, settles in a state with >>>>>>>>>>>> a root true >>>>>>>>>>>>>>>>> this untypical behaviour but could >>>> happen. it would be >>>>>>>>>>>>>> nice not to >>>>>>>>>>>>>>>>> blow up >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> this should be a test case >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> e.g. x tends to 10 with a trigger x < 10 >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> The problem is that the algorithm may end up >>>> being very >>>>>>>>>>>>>>>> inefficient >>>>>>>>>>>>>>>>> in this case. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> ideally the nudge described above needs to be >>>>>>>>>>>>>> proportional to the >>>>>>>>>>>>>>>>> internal cvode step size >>>>>>>>>>>>>>>>> can we get the internal integration step size >>>>>>>>>>>> from cvode? >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> c) a model with an event based feedback loop >> that drives >>>>>>>>>>>>>>>> the model to a >>>>>>>>>>>>>>>>> state where events >>>>>>>>>>>>>>>>> are firing all the time. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> yours Andrew >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> -----Original Message----- >>>>>>>>>>>>>>>>>> From: Rainer Machne [mailto:ra...@tb...] >>>>>>>>>>>>>>>>>> Sent: 12 April 2006 15:51 >>>>>>>>>>>>>>>>>> To: Andrew Finney >>>>>>>>>>>>>>>>>> Cc: Christoph Flamm >>>>>>>>>>>>>>>>>> Subject: RE: comment on proposed exact event >>>>>>>>>>>>>>>> implementation[Scanned] >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Andrew >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> On Wed, 12 Apr 2006, Andrew Finney wrote: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Rainer >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> a trigger can contain inequality and equality >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> but they are found by equivalent root >> expressions so I >>>>>>>>>>>>>> don't think >>>>>>>>>>>>>>>>>>> they are important >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Oh there is one other really important issue: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> We need to be careful about the SBML >> requirement that >>>>>>>>>>>>>> events are >>>>>>>>>>>>>>>>>>> triggered on all transitions from false to true >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> In MathSBML Bruce Shapiro created following logic >>>>>>>>> roughly< >>>>>>>>>>>>>>>>>> (assume no >>>>>>>>>>>>>>>>>>> delays on events) >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> starting integration.... >>>>>>>>>>>>>>>>>>> triggerWasTrue = false; >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> OnRootFound: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> if (triggerExpression and !triggerWasTrue) >>>>>>>>>>>>>>>>>>> { >>>>>>>>>>>>>>>>>>> fire event; >>>>>>>>>>>>>>>>>>> triggerWasTrue = true; >>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> if (!triggerExpression) >>>>>>>>>>>>>>>>>>> triggerWasTrue = false; >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> We kind achive this in the inexact method but >>>>>> its really a >>>>>>>>>>>>>>>>>> cheat the >>>>>>>>>>>>>>>>>>> above I think is the only way to do it properly... >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Why do we cheat? As I remember, we do exactly the >>>>>>>>>>>> above for the >>>>>>>>>>>>>>>>>> inexact event handling! >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> The exact detection/root finder code needs to >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> * do the same, i.e. handle false/true >>>> transitions when a >>>>>>>>>>>>>>>> root is found >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> and additionally >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> * handle triggers that are (logic) combinations of >>>>>>>>>>>>>>>> in/equalities, i.e. >>>>>>>>>>>>>>>>>> both must be true. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> In/equalities combined by logic operators can >>>> further be >>>>>>>>>>>>>>>> subdivided: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> e.g.: >>>>>>>>>>>>>>>>>> trigger a < 10 || b > 20 >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> can be handled as two separate triggers, while and >>>>>>>>>>>> exclusive OR >>>>>>>>>>>>>>>>>> needs combined handling again as outlined before: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> e.g. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> trigger: a < 10 && b > 20 >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> becomes to root conditions in the function g: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> a - 10 = 0; >>>>>>>>>>>>>>>>>> b - 20 = 0; >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> * keep integrating if only a or b is true >>>>>>>>>>>>>>>>>> * exact event happens when the second conditions also >>>>>>>>>>>>>> becomes true >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> This can become tricky. As far as I >> understood the root >>>>>>>>>>>>>> finder, it >>>>>>>>>>>>>>>>>> stops integrating at the time where it found >> the root. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Thus we might have to include a code >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> if ( triggerWasTrue ) >>>>>>>>>>>>>>>>>> rootFunction = 1.0; >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> to supress root finding for triggers that are >>>>>> already true. >>>>>>>>>>>>>>>>>> The same should probably be done for combined >>>>>>>>>>>> triggers, for the >>>>>>>>>>>>>>>>>> expression that becomes true first and needs >>>> to wait for >>>>>>>>>>>>>> the second >>>>>>>>>>>>>>>>>> (or all) other inequalities of the trigger. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Rainer >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> yours Andrew >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> -----Original Message----- >>>>>>>>>>>>>>>>>>>> From: Rainer Machne [mailto:ra...@tb...] >>>>>>>>>>>>>>>>>>>> Sent: 12 April 2006 15:21 >>>>>>>>>>>>>>>>>>>> To: Christoph Flamm >>>>>>>>>>>>>>>>>>>> Cc: Andrew Finney >>>>>>>>>>>>>>>>>>>> Subject: RE: comment on proposed exact event >>>>>>>>>>>>>>>>>> implementation[Scanned] >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Hi Xtof, >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> On Wed, 12 Apr 2006, Christoph Flamm wrote: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> hi andrew, >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> am i getting that right, in essence the recipe >>>>>>>> to evaluate >>>>>>>>>>>>>>>>>>>> letfChild - >>>>>>>>>>>>>>>>>>>>> rightChild works in general to find the exact >>>>>>>> timepoint of >>>>>>>>>>>>>>>>>>>> the event >>>>>>>>>>>>>>>>>>>>> with root finding? >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> No, for this example of an event: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> e.g. a < 10 && b > 10 becomes 2 root >>>>>> expressions 10 - a >>>>>>>>>>>>>>>>>> == 0 and b >>>>>>>>>>>>>>>>>>>> - 10 > == 0 >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> we need to separately evaluate both trigger >>>>>>>>>> conditions, i.e. >>>>>>>>>>>>>>>>>>>> as Andrew said the event trigger becomes 2 root >>>>>>>>>>>>>>>>>> expressions for the >>>>>>>>>>>>>>>>>>>> g(x,p,t) root finding function!! >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> That means that not every root found be the root >>>>>>>> finder is >>>>>>>>>>>>>>>>>> an event. >>>>>>>>>>>>>>>>>>>> For above event, the first (e.g. a) that moved >>>>>> beyond the >>>>>>>>>>>>>>>>>> threshold >>>>>>>>>>>>>>>>>>>> (10) must wait for the second (b) to also move >>>>>>>>>>>> beyond its own >>>>>>>>>>>>>>>>>>>> threshold. I.e. for such event structures the event >>>>>>>>>>>> assignment >>>>>>>>>>>>>>>>>>>> evaluation must wait until the second root. >>>>>>>>>>>>>>>>>>>> ... or somehow like this. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> ... let's try to formulate this generally: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> * An event trigger is a boolean expression, but can >>>>>>>>>>>> be a logic >>>>>>>>>>>>>>>>>>>> combination of different boolean expressions ... ? >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> * Only equalities and inequalities can be >>>>>>>> evaluated by our >>>>>>>>>>>>>>>>>> leftChild >>>>>>>>>>>>>>>>>>>> - rightChild == 0 condition in the root function >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> * logic operators must be broken down into their >>>>>>>>>>>>>>>>>> in/equality relation >>>>>>>>>>>>>>>>>>>> (which must be in there somewhere??) >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> mmhm ... questions: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> 1) we only need to care about logic operators vs. >>>>>>>>>>>> in/equality >>>>>>>>>>>>>>>>>>>> operators ? >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> 2) must there be in/equalities in a trigger? >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Rainer >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> =;) xtof >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Andrew Finney writes: >>>>>>>>>>>>>>>>>>>>>> Rainer >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> First I assume you run-through a trigger >> expression >>>>>>>>>>>>>>>>>>>> separating out >>>>>>>>>>>>>>>>>>>>>> all the inequalities >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> e.g. a < 10 && b > 10 becomes 2 root >>>>>> expressions 10 - a >>>>>>>>>>>>>>>>>>>> == 0 and b - >>>>>>>>>>>>>>>>>>>>>> 10 == 0 >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> when you find a root you re-evaluate the complete >>>>>>>>>>>>>>>>>> triggers to see >>>>>>>>>>>>>>>>>>>>>> what's really fired. >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> or is there a better approach? >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Are there other forms of events, where this >>>>>> method can >>>>>>>>>>>>>>>>>>>> not be applied? >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Well there is equality e.g. x == 40 I think >>>>>> that should >>>>>>>>>>>>>>>>>> work as x - >>>>>>>>>>>>>>>>>>>>>> 40 == 0 Inequality is fine to you map x >> != 40 to x >>>>>>>>>>>> - 40 == 0 >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> In both cases you need to revaluate the trigger >>>>>>>>>>>>>> expression but >>>>>>>>>>>>>>>>>>>>>> probably with an epsilon (especially >>>> equality) or you >>>>>>>>>>>>>>>>>> may have to >>>>>>>>>>>>>>>>>>>>>> force a value from 39.9999 to 40 after the root >>>>>>>>>>>>>>>> finding process. >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> One thing to very careful of is time dependant >>>>>>>>>>>>>>>> expressions (ones >>>>>>>>>>>>>>>>>>>>>> containing the csymbol for time) not so >> much in the >>>>>>>>>>>>>>>> triggers but >>>>>>>>>>>>>>>>>>>>>> make sure time is set right when you roll >>>>>>>>>>>>>> integration back or >>>>>>>>>>>>>>>>>>>>>> forward...hopefully that's obvious. >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> yours Andrew >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> -----Original Message----- >>>>>>>>>>>>>>>>>>>>>>> From: Rainer Machne >> [mailto:ra...@tb...] >>>>>>>>>>>>>>>>>>>>>>> Sent: 12 April 2006 14:40 >>>>>>>>>>>>>>>>>>>>>>> To: Christoph Flamm >>>>>>>>>>>>>>>>>>>>>>> Cc: Andrew Finney >>>>>>>>>>>>>>>>>>>>>>> Subject: Re: comment on proposed exact event >>>>>>>>>>>>>>>>>>>>>>> implementation[Scanned] >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Hi Andrew and Xtof >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> another question: >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Currently we tell the root function to >>>> evaluate the >>>>>>>>>>>>>> expression >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> leftChildofTrigger - rightChildOfTrigger >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> for which the root finder tries to find a >>>> root, i.e. >>>>>>>>>>>>>>>>>>>> time points >>>>>>>>>>>>>>>>>>>>>>> where this expression evaluates to 0. >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> This is valid for event like >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> if x > 40 >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> where the method will try find a time >> point where >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> x - 40 == 0. >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Is this generally valid? Are there >> other forms of >>>>>>>>>>>>>>>> events, where >>>>>>>>>>>>>>>>>>>>>>> this method can not be applied? >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Rainer >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> On Wed, 12 Apr 2006, Christoph Flamm wrote: >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> hi andrew, >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> yes, you are right root finding is the >>>> only proper >>>>>>>>>>>>>>>>>>>> way to detect >>>>>>>>>>>>>>>>>>>>>>>> events accurately. also the code we need >>>>>> to implement >>>>>>>>>>>>>>>>>>>> would be >>>>>>>>>>>>>>>>>>>>>>>> much simpler with root finding. the >> down side of >>>>>>>>>>>>>>>> this approach >>>>>>>>>>>>>>>>>>>>>>> is, that the >>>>>>>>>>>>>>>>>>>>>>>> integration with root finding turned on >>>> drastically >>>>>>>>>>>>>>>>>>>> slowes down >>>>>>>>>>>>>>>>>>>>>>>> the integration speed especially if we >>>>>> have a lot of >>>>>>>>>>>>>>>> triggers! >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> the other problem which we did not touch >>>> during the >>>>>>>>>>>>>>>>>>>>>>> hackathon is what >>>>>>>>>>>>>>>>>>>>>>>> happens if to events trigger exactely at the >>>>>>>>>>>> same time but >>>>>>>>>>>>>>>>>>>>>>>> influence each other. >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> suppose the following two events: >>>>>>>>>>>>>>>>>>>>>>>> (1) if x > 20 then diminish the concentration >>>>>>>>>> of y to 10 >>>>>>>>>>>>>>>>>>>>>>>> (2) if y > 20 then diminish the concentration >>>>>>>>>> of x to 10 >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> this is something like a cyclic >> dependency of the >>>>>>>>>>>>>>>>>> events. if both >>>>>>>>>>>>>>>>>>>>>>>> events are triggered at the same time, which >>>>>>>>>>>>>>>>>>>> could happen, >>>>>>>>>>>>>>>>>>>>>>> what shall >>>>>>>>>>>>>>>>>>>>>>>> we do? which ever event we execute first >>>>>>>>>> invalidates the >>>>>>>>>>>>>>>>>>>>>>> trigger for >>>>>>>>>>>>>>>>>>>>>>>> the second one. >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> in such a case an priority ordering of the >>>>>>>>>>>> events is needed >>>>>>>>>>>>>>>>>>>>>>> to resolve >>>>>>>>>>>>>>>>>>>>>>>> the problem right? is an answer to >> something like >>>>>>>>>>>>>> that in the >>>>>>>>>>>>>>>>>>>>>>>> SBML specs? >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> i think that the method i suggested at >>>> the hackaton >>>>>>>>>>>>>>>>>>>> would give >>>>>>>>>>>>>>>>>>>>>>>> us a good balance between speed and >> "accuracy of >>>>>>>>>>>> the event >>>>>>>>>>>>>>>>>>>>>>> detection" (but >>>>>>>>>>>>>>>>>>>>>>>> the coding is more difficult!) >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> rainer suggested as an alternative to the mixed >>>>>>>>>>>>>>>>>>>>>>>> root-finding/non-root-finding strategy >>>> to make the >>>>>>>>>>>>>>>>>>>> integration >>>>>>>>>>>>>>>>>>>>>>>> step smaller until the exact time of >> an event is >>>>>>>>>>>>>>>>>>>> localized (this >>>>>>>>>>>>>>>>>>>>>>> also slows >>>>>>>>>>>>>>>>>>>>>>>> down integration speed). >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> so for which solution should we head? >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> =;) xtof >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> p.s. next week i meet an mathematician from the >>>>>>>>>>>>>>>>>>>> MPI-MIS who is >>>>>>>>>>>>>>>>>>>>>>>> an expert for DDEs to discuss which >>>> solving method >>>>>>>>>>>>>>>>>>>> would be best >>>>>>>>>>>>>>>>>>>>>>>> to incooporate into the SOSlib. >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> >>>>>>> >>>>>>> ------------------------------------------------------- >>>>>>> Using Tomcat but need to do more? Need to support web >>>>>> services, security? >>>>>>> Get stuff done quickly with pre-integrated technology to >>>>>> make your job >>>>>>> easier Download IBM WebSphere Application Server >> v.1.0.1 based on >>>>>>> Apache Geronimo >>>>>>> >>>>>> >>>> >> http://sel.as-us.falkag.net/sel?cmd__________________________________ >>>>>> _ >>>>>>> ____________ >>>>>>> sbmlsolver-devel mailing list >>>>>>> sbm...@li... >>>>>>> https://lists.sourceforge.net/lists/listinfo/sbmlsolver-devel >>>>>>> >>>>>> >>>>> >>>> >>> >> > |