Maple 9 Advanced Programming Guide.pdf

Maple 9 Advanced Programming Guide.pdf

ID:33929265

大小:3.64 MB

页数:454页

时间:2019-02-28

上传者:不努力梦想只是梦
Maple 9 Advanced Programming Guide.pdf_第1页
Maple 9 Advanced Programming Guide.pdf_第2页
Maple 9 Advanced Programming Guide.pdf_第3页
Maple 9 Advanced Programming Guide.pdf_第4页
Maple 9 Advanced Programming Guide.pdf_第5页
资源描述:

《Maple 9 Advanced Programming Guide.pdf》由会员上传分享,免费在线阅读,更多相关内容在学术论文-天天文库

Maple9AdvancedProgrammingGuideM.B.MonaganK.O.GeddesK.M.HealG.LabahnS.M.VorkoetterJ.McCarronP.DeMarco•cMaplesoft,adivisionofWaterlooMapleInc.2003. ii¯Maple,Maplesoft,Maplet,andOpenMaplearetrademarksofWater-looMapleInc.•cMaplesoft,adivisionofWaterlooMapleInc.2003.Allrightsre-served.Theelectronicversion(PDF)ofthisbookmaybedownloadedandprintedforpersonaluseorstoredasacopyonapersonalmachine.Theelectronicversion(PDF)ofthisbookmaynotbedistributed.Informationinthisdocumentissubjecttochangewithoutnoticeanddoesnotrep-resentacommitmentonthepartofthevendor.Thesoftwaredescribedinthisdocumentisfurnishedunderalicenseagreementandmaybeusedorcopiedonlyinaccordancewiththeagreement.Itisagainstthelawtocopythesoftwareonanymediumasspecißcallyallowedintheagreement.WindowsisaregisteredtrademarkofMicrosoftCorporation.JavaandallJavabasedmarksaretrademarksorregisteredtrade-marksofSunMicrosystems,Inc.intheUnitedStatesandothercountries.MaplesoftisindependentofSunMicrosystems,Inc.Allothertrademarksarethepropertyoftheirrespectiveowners.ThisdocumentwasproducedusingaspecialversionofMaplethatreadsandupdatesLATEXßles.PrintedinCanadaISBN1-894511-44-1 ContentsPreface1Audience..............................1WorksheetGraphicalInterface..................2ManualSet.............................2Conventions.............................3CustomerFeedback.........................31Procedures,Variables,andExtendingMaple5PrerequisiteKnowledge...................5InThisChapter.......................51.1NestedProcedures......................5ScopingRules.........................6LocalVersusGlobalVariables................6TheQuick-SortAlgorithm..................8Example............................8CreatingaUniformRandomNumberGenerator.....111.2ProceduresThatReturnProcedures............14ConveyingValues.......................14CreatingaNewtonIteration.................14Example1...........................15Example2...........................16AShiftOperator.......................171.3LocalVariablesandInvokingProcedures..........19Example1...........................19Example2...........................20ProcedureasaReturnedObject..............22Example3...........................22Example4...........................24Exercises...........................261.4InteractiveInput.......................27iii iv¯ContentsReadingStringsfromtheTerminal.............27Example1...........................28ReadingExpressionsfromtheTerminal..........28Example2...........................29ConvertingStringstoExpressions.............301.5ExtendingMaple.......................31DeßningNewTypes.....................31Exercises...........................33NeutralOperators......................33Example1...........................34Exercise............................37ExtendingCommands....................391.6Conclusion..........................422ProgrammingwithModules43Modules............................43Examples...........................44ModuleVersusProcedure..................45AccessingModuleExports..................46InThisChapter.......................462.1SyntaxandSemantics....................47TheModuleDeßnition....................47TheModuleBody......................48ModuleParameters......................48NamedModules.......................48Declarations..........................50ExportedLocalVariables..................52ModuleOptions........................57ImplicitScopingRules....................58LexicalScopingRules....................58ModulesandTypes......................60Example:ASymbolicDiÞerentiator............612.2Records............................722.3Packages............................78WhatIsaPackage......................78WritingMaplePackagesbyUsingModules........80TheLinkedListPackage..................80CodeCoverageProßlingPackage..............87TheShapesPackage.....................942.4TheuseStatement......................103OperatorRebinding.....................106 Contents¯v2.5ModelingObjects.......................108PriorityQueues........................111AnObject-orientedShapesPackage............1152.6InterfacesandImplementations...............117Interfaces...........................118GenericGraphAlgorithms..................124QuotientFields........................129AGenericGroupImplementation..............1382.7ExtendedExample:ASearchEngine............159IntroductiontoSearching..................159InvertedTermOccurrenceIndexing.............161TheVectorSpaceModel...................164TermWeighting........................167BuildingaSearchEnginePackage.............168LatentSemanticAnalysis..................172TheSearchEnginePackage.................173UsingthePackage......................1802.8Conclusion..........................1843InputandOutput185InThisChapter.......................1853.1ATutorialExample.....................1863.2FileTypesandModes....................190BuÞeredFilesversusUnbuÞeredFiles...........190TextFilesversusBinaryFiles................190ReadModeversusWriteMode...............191ThedefaultandterminalFiles..............1913.3FileDescriptorsversusFileNames.............1923.4FileManipulationCommands................193OpeningandClosingFiles..................193PositionDeterminationandAdjustment..........194DetectingtheEndofaFile.................195DeterminingFileStatus...................195RemovingFiles........................1963.5InputCommands.......................197ReadingTextLinesfromaFile...............197ReadingArbitraryBytesfromaFile............197FormattedInput.......................198ReadingMapleStatements.................204ReadingTabularData....................2043.6OutputCommands......................206 vi¯ContentsConßguringOutputParametersUsingtheinterfaceCom-mand.........................206One-DimensionalExpressionOutput............206Two-DimensionalExpressionOutput............207WritingMapleStringstoaFile...............210WritingBytestoaFile....................210FormattedOutput......................211WritingTabularData....................215FlushingaBuÞeredFile...................216RedirectingthedefaultOutputStream..........2173.7ConversionCommands....................218ConversionbetweenStringsandListsofIntegers.....218ParsingMapleExpressionsandStatements........218FormattedConversiontoandfromStrings.........2203.8NotestoCProgrammers...................2213.9Conclusion..........................2214NumericalProgramminginMaple223Floating-PointCalculations.................223InThisChapter.......................223WhyUseNumericalComputations.............2234.1TheBasicsofevalf.....................2244.2HardwareFloating-PointNumbers.............227Newton'sMethod.......................230ComputingwithArraysofNumbers............2324.3Floating-PointModelsinMaple...............235SoftwareFloats........................235RoundoÞError........................2364.4ExtendingtheevalfCommand...............238DeßningNewConstants...................238DeßningNewFunctions...................2404.5UsingtheMatlabPackage..................2434.6Conclusion..........................2445ProgrammingwithMapleGraphics245MaplePlots..........................245CreatingPlottingProcedures................245InThisChapter.......................2455.1BasicPlottingProcedures..................246AlteringaPlot........................2485.2ProgrammingwithPlottingLibraryProcedures......249 Contents¯viiPlottingaLoop........................249Exercise............................251ARibbonPlotProcedure..................2515.3MaplePlotDataStructures.................254ThePLOTDataStructure..................256ArgumentsInsideaPLOTStructure.............257ASumPlot..........................259ThePLOT3DDataStructure.................262ObjectsInsideaPLOT3DDataStructure..........2645.4ProgrammingwithPlotDataStructures..........266WritingGraphicPrimitives.................266PlottingGears........................268PolygonMeshes........................2725.5ProgrammingwiththeplottoolsPackage........273APieChart..........................275ADropshadowProcedure..................276CreatingaTiling.......................278ASmithChart........................280Exercise............................281ModifyingPolygonMeshes.................2815.6VectorFieldPlots......................286DrawingaVector.......................286GeneratingaVectorPlotField...............2885.7GeneratingGridsofPoints.................2965.8Animation...........................301AnimationinStaticForm..................302GraphicalObjectasInput..................302MethodsforCreatingAnimations..............303TwoandThreeDimensions.................305DemonstratingPhysicalObjectsinMotion........3065.9ProgrammingwithColor...................308GeneratingColorTables...................309UsingAnimation.......................310AddingColorInformationtoPlots.............312CreatingAChessBoardPlot................3155.10Conclusion..........................3166AdvancedConnectivity319InThisChapter.......................319CodeGeneration.......................319ExternalCalling:UsingCompiledCodeinMaple.....319 viii¯ContentsOpenMaple:UsingMapleinCompiledCode........3196.1CodeGeneration.......................319TheCodeGenerationPackage................319CallingCodeGenerationFunctions.............320TranslationProcess......................321ExtendingtheCodeGenerationTranslationFacilities...324DeßningaCustomTranslator................3256.2ExternalCalling:UsingCompiledCodeinMaple.....330Method1:CallingExternalFunctions...........332ExternalDeßnition......................334TypeSpecißcation......................335ScalarDataFormats.....................336StructuredDataFormats..................336SpecifyingArgumentPassingConventions.........338Method2:GeneratingWrappers..............338AdditionalTypesandOptions...............339StructuredDataFormats..................339EnumeratedTypes......................339ProcedureCallFormats...................340CallbyReference.......................340ArrayOptions........................340Non-passedArguments....................341ArgumentCheckingandEáciencyConsiderations....342Conversions..........................342CompilerOptions.......................344EvaluationRules.......................348Method3:CustomizingWrappers..............350ExternalFunctionEntryPoint...............350InspectingAutomaticallyGeneratedWrappers......352ExternalAPI.........................356SystemIntegrity.......................3746.3OpenMaple:UsingMapleinCompiledCode........374InterfaceOverview......................375Call-backFunctions.....................380MapleOnlineHelpDatabase................386TechnicalIssues........................389FileStructure.........................389BuildingtheSampleProgram................3906.4Conclusion..........................392AInternalRepresentationandManipulation397 Contents¯ixA.1InternalOrganization....................397Components..........................398InternalFunctions......................398FlowofControl........................399A.2InternalRepresentationsofDataTypes..........400LogicalAND.........................401AssignmentStatement....................401BinaryObject.........................401BreakStatement.......................401NameConcatenation.....................402ComplexValue........................402CommunicationsControlStructure.............402TypeSpecißcationorTest..................403Debug.............................403EquationorTestforEquality................403ErrorStatement.......................403ExpressionSequence.....................404Floating-PointNumber....................404For/WhileLoopStatement.................404ForeignData.........................405FunctionCall.........................406Garbage............................406HardwareFloat........................406IfStatement..........................407LogicalIMPLIES.......................407NotEqualorTestforInequality..............407NegativeInteger.......................407PositiveInteger........................408LessThanorEqual......................409LessThan...........................409LexicallyScopedVariablewithinanExpression......409List..............................410LocalVariablewithinanExpression............410Member............................410ModuleDeßnition......................410ModuleInstance.......................412Identißer............................412NextStatement........................413LogicalNOT.........................413LogicalOR..........................413ProcedureParameterwithinanExpression........413 x¯ContentsPower.............................414ProcedureDeßnition.....................414Product,Quotient,Power..................416Range.............................416Rational............................416ReadStatement........................417ReturnStatement......................417RectangularTable......................417SaveStatement........................419Series.............................419Set...............................419StatementSequence.....................420StopMaple..........................420String.............................420Sum,DiÞerence........................421Table..............................421TableReference........................421TryStatement........................422UnevaluatedExpression...................422UseStatement........................422LogicalXOR.........................423PolynomialswithIntegerCoeácientsmodulon......423A.3TheUseofHashinginMaple................424BasicHashTables......................424DynamicHashTables....................425TheSimplißcationTable...................426TheNameTable.......................427RememberTables.......................427MapleLanguageArraysandTables.............428MapleLanguageRectangularTables............429A.4Portability...........................429Index431 PrefaceThismanualdescribesadvancedMapleTMprogrammingconcepts,includ-ing:¯Variablescope,procedures,modules,andpackages¯Advancedinputandoutput¯Numericalprogramming¯ProgrammingwithMapleplots¯Connectivity:translatingMaplecodetootherprogramminglan-guages,callingexternallibrariesfromMaple,andcallingMaplecodefromexternallibraries¯InternalrepresentationandmanipulationAudienceThismanualprovidesinformationforexperiencedMapleprogrammers.Youshouldbefamiliarwiththefollowing.¯MapleOnlineHelpIntroduction¯Exampleworksheets¯HowtouseMapleinteractively¯TheIntroductoryProgrammingGuide1 2¯PrefaceWorksheetGraphicalInterfaceYoucanaccessthepoweroftheMaplecomputationenginethroughavari-etyofuserinterfaces:thestandardworksheet,thecommand-line1version,theclassicworksheet(notavailableonMacintosh•r),andcustom-builtTMMapletapplications.ThefullMaplesystemisavailablethroughalloftheseinterfaces.Inthismanual,anyreferencestothegraphicalMapleinterfacerefertothestandardworksheetinterface.Formoreinformationonthevariousinterfaceoptions,refertothe?versionshelppage.ManualSetTherearethreeothermanualsavailableforMapleusers,theMapleGet-tingStartedGuide,theMapleLearningGuide,andtheMapleIntro-ductoryProgrammingGuide.2¯TheMapleGettingStartedGuidecontainsanintroductiontothegraphicaluserinterfaceandatutorialthatoutlinesusingMapletosolvemathematicalproblemsandcreatetechnicaldocuments.Italsoincludesinformationfornewusersabouttheonlinehelpsystem,NewUser'sTour,exampleworksheets,andtheMaplesoftWebsite.¯TheMapleLearningGuideexplainshowMapleandtheMaplelan-guagework.Itdescribesthemostimportantcommandsandusesthemtosolvetechnicalproblems.UserhintsforMapletapplicationsarealsodescribedinthisguide.¯TheMapleIntroductoryProgrammingGuideintroducesthebasicMapleprogrammingconcepts,suchasexpressions,datastructures,loopinganddecisionmechanisms,procedures,inputandoutput,de-bugging,andtheMapletUserInterfaceCustomizationSystem.TheMaplesoftwarealsohasanonlinehelpsystem.TheMaplehelpsys-temallowsyoutosearchinmanywaysandisalwaysavailable.Therearealsoexamplesthatyoucancopy,paste,andexecuteimmediately.1Thecommand-lineversionprovidesoptimumperformance.However,theworksheetinterfaceiseasiertouseandrenderstypeset,editablemathoutputandhigherqualityplots.2TheStudentEditiondoesnotincludetheMapleIntroductoryProgrammingGuideandtheMapleAdvancedProgrammingGuide.Theseprogrammingguidescanbepur-chasedfromschoolandspecialtybookstoresordirectlyfromMaplesoft. Conventions¯3ConventionsThismanualusesthefollowingtypographicalconventions.¯courierfont-Maplecommand,packagename,andoptionname¯boldromanfont-dialog,menu,andtextßeld¯italics-neworimportantconcept,optionnameinalist,andmanualtitles¯Note-additionalinformationrelevanttothesection¯Important-informationthatmustbereadandfollowedCustomerFeedbackMaplesoftwelcomesyourfeedback.Forsuggestionsandcommentsrelatedtothisandothermanuals,emaildoc@maplesoft.com. 4¯Preface 1Procedures,Variables,andExtendingMaplePrerequisiteKnowledgeBeforereadingthischapter,youmusthaveanunderstandingofMapleevaluationrulesforvariablesandparametersasdescribedinchapter6oftheIntroductoryProgrammingGuide.InThisChapterNestedProceduresYoucandeßneaMapleprocedurewithinanotherMapleprocedure.ProceduresThatReturnProceduresYoucancreateproceduresthatreturnproceduresbyusingMapleevaluationrules.LocalVariablesLocalvariablescanexistaftertheprocedurewhichcre-atedthemhasexited.Thisfeatureallowsaproceduretoreturnaproce-dure.Thenewprocedurerequiresauniqueplacetostoreinformation.InteractiveInputYoucanwriteinteractiveprocedures,queryingtheuserformissinginformationorcreatinganinteractivetutorialoratest.ExtendingMapleTheMaplesoftwareincludesusefulmechanismsforextendingMaplefunctionality,whichreducetheneedtowritespecial-purposeprocedures.SeveralMaplecommandscanbeextended.1.1NestedProceduresYoucandeßneaMapleprocedureinsideanotherMapleprocedure.SomeMaplecommandsareveryusefulinsideaprocedure.Intheworksheet5 6¯Chapter1:Procedures,Variables,andExtendingMapleenvironment,themapcommandisusedtoapplyanoperationtotheelementsofastructure.Forexample,youcandivideeachelementofalistbyanumber,suchas8.>lst:=[8,4,2,16]:>map(x->x/8,lst);11[1;;;2]24Consideravariationonthemapcommand,whichappearsinthefol-lowingprocedure.ExampleThisnewproceduredivideseachelementofalistbytheßrstelementofthatlist.>nest:=proc(x::list)>localv;>v:=x[1];>map(y->y/v,x);>endproc:>nest(lst);11[1;;;2]24Theprocedurenestcontainsasecondprocedure,map,whichinthiscaseistheMaplecommandmap.Mapleappliesitslexicalscopingrules,whichdeclarethevwithinthecalltomapasthesamevasintheouterprocedure,nest.ScopingRulesThissectionexplainsMaplescopingrules.YouwilllearnhowMaplede-termineswhichvariablesarelocaltoaprocedureandwhichareglobal.YoumusthaveabasicunderstandingofMapleevaluationrulesforpa-rameters,andforlocalandglobalvariables.Formoreinformation,refertochapter6oftheIntroductoryProgrammingGuide.LocalVersusGlobalVariablesIngeneral,whenwritingaprocedure,youshouldexplicitlydeclarewhichvariablesareglobalandwhicharelocal.Declaringthescopeofthevari-ablesmakesyourprocedureeasiertoreadanddebug.However,sometimesdeclaringthevariablesisnotthebestmethod.Inthepreviousnestpro-cedure,thevariableinthemapcommandisdeßnedbythesurrounding 1.1NestedProcedures¯7procedure.Whathappensifyoudeßnethisvariable,v,aslocaltotheinvocationoftheprocedurewithinmap?>nest2:=proc(x::list)>localv;>v:=x[1];>map(proc(y)localv;y/v;end,x);>endproc:>nest2(lst);84216[;;;]vvvvThenest2procedureproducesdiÞerentresults.Whenthevariablesaredeclaredintheinnerprocedure,thepropervaluesfromtheenclosingprocedurearenotused.Eitheravariableislocaltoaprocedureandcertainproceduresthatarecompletelywithinit,oritisglobaltotheentireMaplesession.RuleMapledetermineswhetheravariableislocalorglobal,fromtheinsideproceduretotheoutsideprocedure.Thenameofthevariableissearchedforamong:1.Parametersoftheinnerprocedure2.Localdeclarationsandglobaldeclarationsoftheinnerprocedure3.Parametersoftheoutsideprocedure4.Localandglobaldeclarationsoftheoutsideprocedure5.Implicitlydeclaredlocalvariablesofanysurroundingprocedure(s)Iffound,thatspecißesthebindingofthevariable.If,usingtheaboverule,Maplecannotdeterminewhetheravariableisglobalorlocal,thefollowingdefaultdecisionsaremade.¯Ifavariableappearsontheleftsideofanexplicitassignmentorasthecontrollingvariableofaforloop,Mapleregardsthevariableaslocal.¯Otherwise,Mapleregardsthevariableasglobaltothewholesession.Inparticular,Mapleassumesbydefaultthatthevariablesyoupassasargumentstootherprocedures,whichmaysettheirvalues,areglobal. 8¯Chapter1:Procedures,Variables,andExtendingMapleTheQuick-SortAlgorithmSortingafewnumbersisquickusinganymethod,butsortinglargeamountsofdatacanbeverytimeconsuming;thus,ßndingeácientmeth-odsisimportant.Thefollowingquick-sortalgorithmisaclassicalgorithm.Thekeytounderstandingthisalgorithmistounderstandtheoperationofpartition-ing.Thisinvolveschoosinganyonenumberfromthearraythatyouareabouttosort.Then,yourepositionthenumbersinthearraythatarelessthanthenumberthatyouchosetooneendofthearrayandrepositionnumbersthataregreatertotheotherend.Lastly,youinsertthechosennumberbetweenthesetwogroups.Attheendofthepartitioning,youhavenotyetentirelysortedthearray,becausethenumberslessthanorgreaterthantheoneyouchosemaystillbeintheiroriginalorder.Thisproceduredividesthearrayintotwosmallerarrayswhichareeasiertosortthantheoriginallargerone.Thepartitioningoperationhasthusmadetheworkofsortingmucheas-ier.Youcanbringthearrayonestepcloserinthesortingprocessbypartitioningeachofthetwosmallerarrays.Thisoperationproducesfoursmallerarrays.Yousorttheentirearraybyrepeatedlypartitioningthesmallerarrays.ExampleThepartitionprocedureusesanarraytostorethelistbecauseyoucanchangetheelementsofanarraydirectly.Thus,youcansortthearrayinplaceandnotwasteanyspacegeneratingextracopies.Thequicksortprocedureiseasiertounderstandifyoulookattheprocedurepartitioninisolationßrst.Thisprocedureacceptsanarrayofnumbersandtwointegers.Thetwointegersareelementnumbersofthearray,indicatingtheportionofthearraytopartition.Whileyoucouldpossiblychooseanyofthenumbersinthearraytopartitionaround,thisprocedurechoosesthelastelementofthesectionofthearrayforthatpurpose,namelyA[n].TheintentionalomissionofglobalandlocalstatementsshowswhichvariablesMaplerecognizesaslocalandwhichareglobalbydefault.Itisrecommended,however,thatyounotmakethisomissioninyourprocedures.>partition:=proc(A::array(1,numeric),>m::posint,n::posint)>i:=m;>j:=n;>x:=A[j];>whileiifA[i]>xthen 1.1NestedProcedures¯9>A[j]:=A[i];>j:=j-1;>A[i]:=A[j];>else>i:=i+1;>endif;>enddo;>A[j]:=x;>eval(A);>endproc:Warning,`i`isimplicitlydeclaredlocaltoprocedure`partition`Warning,`j`isimplicitlydeclaredlocaltoprocedure`partition`Warning,`x`isimplicitlydeclaredlocaltoprocedure`partition`Mapledeclaresi,j,andxlocalbecausethepartitionprocedurecon-tainsexplicitassignmentstothosevariables.ThepartitionprocedurealsoassignsexplicitlytoA,butAisaparameter,notalocalvariable.Becauseyoudonotassigntothenameeval,Maplemakesittheglobalnamewhichreferstotheevalcommand.Afterpartitioningthearrayainthefollowing,alltheelementslessthan3precede3buttheyareinnoparticularorder;similarly,theelementslargerthan3comeafter3.>a:=array([2,4,1,5,3]);a:=[2;4;1;5;3]>partition(a,1,5);[2;1;3;5;4]Thepartitionproceduremodißesitsßrstargument,changinga.>eval(a);[2;1;3;5;4]Theßnalstepinassemblingthequicksortprocedureistoinsertthepartitionprocedurewithinanouterprocedure.Theouterproce-dureßrstdeßnesthepartitionsubprocedure,thenpartitionsthearray.Ingeneral,avoidinsertingoneprocedureinanother.However,youwill 10¯Chapter1:Procedures,Variables,andExtendingMapleencountersituationsinfollowingsectionsofthischapterinwhichitisnec-essarytonestprocedures.Sincethenextstepistopartitioneachofthetwosubarraysbycallingquicksortrecursively,partitionmustreturnthelocationoftheelementwhichdividesthepartition.ExampleThisexampleillustratestheroleofnestedprocedures.Theouterprocedure,quicksort,containstheinnerprocedure,partition.>quicksort:=proc(A::array(1,numeric),>m::integer,n::integer)>localpartition,p;>>partition:=proc(m,n)>i:=m;>j:=n;>x:=A[j];>whileiifA[i]>xthen>A[j]:=A[i];>j:=j-1;>A[i]:=A[j];>else>i:=i+1;>endif;>enddo;>A[j]:=x;>p:=j;>endproc:>>ifm=nthereisnothingtodo>p:=partition(m,n);>quicksort(A,m,p-1);>quicksort(A,p+1,n);>endif;>>eval(A);>endproc:Warning,`i`isimplicitlydeclaredlocaltoprocedure`partition`Warning,`j`isimplicitlydeclaredlocaltoprocedure`partition`Warning,`x`isimplicitlydeclaredlocaltoprocedure`partition`>a:=array([2,4,1,5,3]);a:=[2;4;1;5;3] 1.1NestedProcedures¯11>quicksort(a,1,5);[1;2;3;4;5]>eval(a);[1;2;3;4;5]MapledeterminesthattheAandpvariablesinthepartitionsub-procedurearedeßnedbytheparameterandlocalvariable(respectively)fromtheouterquicksortprocedureandeverythingworksasplanned.ThevariableAcanbepassedasaparametertothepartitionsubproce-dure(asinthestand-alonepartitionprocedure).However,Adoesnotneedtobepassedbecause,byusingMaplescopingrules,itisavailabletotheinnerprocedure.CreatingaUniformRandomNumberGeneratorIfyouwanttouseMapletosimulatephysicalexperiments,youlikelyneedarandomnumbergenerator.Theuniformdistributionisparticu-larlysimple:anyrealnumberinagivenrangeisequallylikely.Thus,auniformrandomnumbergeneratorisaprocedurethatreturnsaran-domàoating-pointnumberwithinacertainrange.Thissectiondevelopstheprocedure,uniform,whichcreatesuniformrandomnumbergenera-tors.Therandcommandgeneratesaprocedurewhichreturnsrandomin-tegers.Forexample,rand(4..7)generatesaprocedurethatreturnsran-domintegersbetween4and7,inclusive.>f:=rand(4..7):>seq(f(),i=1..20);5;6;5;7;4;6;5;4;5;5;7;7;5;4;6;5;4;5;7;5Theuniformprocedureissimilartorandbutreturnsàoating-pointnumbersratherthanintegers.Youcanuserandtogeneraterandomàoating-pointnumbersbetween4and7bymultiplyinganddividingby10^Digits.>f:=rand(4*10^Digits..7*10^Digits)/10^Digits:>f(); 12¯Chapter1:Procedures,Variables,andExtendingMaple122107060112000000000Theprocedurefreturnsfractionsratherthanàoating-pointnumberssoyoumustcomposeitwithevalf;thatis,useevalf(f()).Alterna-tively,youcanperformthisoperationbyusingtheMaplecompositionoperator,@.>(evalf@f)();6:648630719Thefollowinguniformprocedureusesevalftoevaluatetheconstantsintherangespecißcation,r,toàoating-pointnumbers,themapcommandtomultiplybothendpointsoftherangeby10^Digits,androundtoroundtheresultstointegers.>uniform:=proc(r::constant..constant)>localintrange,f;>intrange:=map(x->round(x*10^Digits),evalf(r));>f:=rand(intrange);>(evalf@eval(f))/10^Digits;>endproc:Youcannowgeneraterandomàoating-pointnumbersbetween4and7.>U:=uniform(4..7):>seq(U(),i=1..20);4:559076346;4:939267370;5:542851096;4:260060897;4:976009937;5:598293374;4:547350944;5:647078832;5:133877918;5:249590037;4:120953928;6:836344299;5:374608653;4:586266491;5:481365622;5:384244382;5:190575456;5:207535837;5:553710879;4:163815544Theuniformprocedurehasaseriousàaw:uniformusesthecurrentvalueofDigitstoconstructintrange;thus,UdependsonthevalueofDigitswhenuniformcreatesit.Ontheotherhand,theevalfcommandwithinUusesthevalueofDigitsthatiscurrentwhenyouinvokeU.Thesetwovaluesarenotalwaysidentical. 1.1NestedProcedures¯13>U:=uniform(cos(2)..sin(1)):>Digits:=15:>seq(U(),i=1..8);0:828316845400000;0:328875163100000;0:790988967100000;0:624953401700000;0:362773633800000;0:679519822000000;0:0465278542000000;0:291055180800000TheproperdesignchoicehereisthatUshoulddependonlyonthevalueofDigitswhenyouinvokeU.Thefollowingversionofuniformaccomplishesthisbyplacingtheentirecomputationinsidetheprocedurethatuniformreturns.>uniform:=proc(r::constant..constant)>>proc()>localintrange,f;>intrange:=map(x->round(x*10^Digits),>evalf(r));>f:=rand(intrange);>evalf(f()/10^Digits);>endproc;>endproc:Therwithintheinnerprocisnotdeclaredaslocalorglobal,soitbecomesthesamerastheparametertotheouterproc.TheprocedurethatuniformgeneratesisnowindependentofthevalueofDigitsatthetimeyouinvokeuniform.>U:=uniform(cos(2)..sin(1)):>Digits:=15:>seq(U(),i=1..8);0:476383408581006;0:554836962987261;0:147655743361511;0:273247304736175;0:148172828708797;0:258115633420094;0:558246581434993;0:518084711267009Note:Theinterfacevariabledisplayprecisioncontrolsthenumberofdecimalplacestobedisplayed.Thedefaultvalueis1,representingfullprecisionasdeterminedbytheDigitsenvironmentvariable.Thissim-plißesdisplaywithoutintroducinground-oÞerror.Formoreinformation,referto?interface. 14¯Chapter1:Procedures,Variables,andExtendingMapleSummaryThissectionintroduced:¯RulesMapleusestodistinguishglobalandlocalvariables¯Principalimplicationsoftheserules¯Toolsavailableforwritingnestedprocedures1.2ProceduresThatReturnProceduresSomeofthestandardMaplecommandsreturnprocedures.Forexample,randreturnsaprocedurewhichinturnproducesrandomlychoseninte-gersfromaspecißedrange.Thedsolvefunctionwiththetype=numericoptionreturnsaprocedurewhichsuppliesanumericestimateoftheso-lutiontoadiÞerentialequation.Youcanwriteproceduresthatreturnprocedures.Thissectiondis-cusseshowvaluesarepassedfromtheouterproceduretotheinnerpro-cedure.ConveyingValuesThefollowingexampledemonstrateshowlocatingtherootsofafunctionbyusingNewton'smethodcanbeimplementedinaprocedure.CreatingaNewtonIterationUseNewton'smethodtoßndtherootsofafunction.1.Chooseapointonthex-axisthatyouthinkmightbeclosetoaroot.2.Findtheslopeofthecurveatthepointyouchose.3.Drawthetangenttothecurveatthatpointandobservewherethetangentintersectsthex-axis.Formostfunctions,thissecondpointisclosertotherealrootthanyourinitialguess.Toßndtheroot,usethenewpointasanewguessandkeepdrawingtangentsandßndingnewpoints. 1.2ProceduresThatReturnProcedures¯1521.510.5x0x1012345678x–0.5–1Toßndanumericalsolutiontotheequationf(x)=0,guessanap-proximatesolution,x0,andthengenerateasequenceofapproximationsusing:1.Newton'smethod2.Thefollowingformulationofthepreviousprocessf(xk)xk+1=xk0f(xk)Youcanimplementthisalgorithmonacomputerinanumberofways.Example1Thefollowingproceduretakesafunctionandcreatesanewprocedure,whichtakesaninitialguessand,forthatparticularfunction,generatesthenextguess.Thenewproceduredoesnotworkforotherfunctions.Toßndtherootsofanewfunction,useMakeIterationtogenerateanewguess-generatingprocedure.Theunapplycommandturnsanexpressionintoaprocedure.>MakeIteration:=proc(expr::algebraic,x::name)>localiteration;>iteration:=x-expr/diff(expr,x);>unapply(iteration,x);>endproc:TheprocedurereturnedbytheMakeIterationproceduremapsthenamextotheexpressionassignedtotheiteration.pTesttheprocedureontheexpressionx2x.>expr:=x-2*sqrt(x); 16¯Chapter1:Procedures,Variables,andExtendingMaplepexpr:=x2x>Newton:=MakeIteration(expr,x);px2xNewton:=x!x11pxNewtonreturnsthesolution,x=4afterafewiterations.>x0:=2.0;x0:=2:0>to4dox0:=Newton(x0);enddo;x0:=4:828427124x0:=4:032533198x0:=4:000065353x0:=4:000000000Example2TheMakeIterationprocedurerequiresitsßrstargumenttobeanal-gebraicexpression.YoucanalsowriteaversionofMakeIterationthatworksonfunctions.SincethefollowingMakeIterationprocedurerecog-nizestheparameterfasaprocedure,youmustusetheevalcommandtoevaluateitfully.>MakeIteration:=proc(f::procedure)>(x->x)-eval(f)/D(eval(f));>endproc:>g:=x->x-cos(x);g:=x!xcos(x)>SirIsaac:=MakeIteration(g);x!xcos(x)SirIsaac:=(x!x)x!1+sin(x) 1.2ProceduresThatReturnProcedures¯17NotethatSirIsaacisindependentofthenameg.Thus,youcanchangegwithoutbreakingSirIsaac.Youcanßndagoodapproximatesolutiontoxcos(x)=0inafewiterations.>x0:=1.0;x0:=1:0>to4dox0:=SirIsaac(x0)enddo;x0:=0:7503638679x0:=0:7391128909x0:=0:7390851334x0:=0:7390851332AShiftOperatorConsidertheproblemofwritingaprocedurethattakesafunction,f,asinputandreturnsafunction,g,suchthatg(x)=f(x+1).Youcanwritesuchaprocedureinthefollowingmanner.>shift:=(f::procedure)->(x->f(x+1)):Tryperformingashiftonsin(x).>shift(sin);x!sin(x+1)Maplelexicalscopingrulesdeclarethefwithintheinnerproceduretobethesamefastheparameterwithintheouterprocedure.Therefore,theshiftcommandworksaswritten.Thepreviousexampleofshiftworkswithunivariatefunctionsbutitdoesnotworkwithfunctionsoftwoormorevariables.>h:=(x,y)->x*y;h:=(x;y)!xy>hh:=shift(h); 18¯Chapter1:Procedures,Variables,andExtendingMaplehh:=x!h(x+1)>hh(x,y);Error,(inh)husesa2ndargument,y,whichismissingMultivariateFunctionsTomodifyshifttoworkwithmultivariatefunctions,rewriteittoaccepttheadditionalparameters.Inaprocedure,argsisthesequenceofactualparameters,andargs[2..-1]isthesequenceofactualparametersexcepttheßrstone.Formoreinformationontheselectionoperation([]),refertochapter4oftheIntroductoryProgrammingGuide.Itfollowsthattheprocedurex->f(x+1,args[2..-1])passesallitsargumentsexcepttheßrstdirectlytof.>shift:=(f::procedure)->(x->f(x+1,args[2..-1])):>hh:=shift(h);hh:=x!h(x+1;args2::1)>hh(x,y);(x+1)yThefunctionhhdependsonh;ifyouchangeh,youimplicitlychangehh;>h:=(x,y,z)->y*z^2/x;yz2h:=(x;y;z)!x>hh(x,y,z);yz2x+1 1.3LocalVariablesandInvokingProcedures¯191.3LocalVariablesandInvokingProceduresLocalvariablesarelocaltoaprocedureandtoaninvocationofthatprocedure.Callingaprocedurecreatesandusesnewlocalvariableseachtime.Ifyouinvokethesameproceduretwice,thelocalvariablesitusesthesecondtimearedistinctfromthoseitusedtheßrsttime.Localvariablesdonotnecessarilydisappearwhentheprocedureexits.Youcanwriteprocedureswhichreturnalocalvariable,eitherexplicitlyorimplicitly,totheinteractivesession,whereitcanexistindeßnitely.Thesevariablesarecalledescapedlocalvariables.Thisconceptcanbeconfusing,particularlysincetheycanhavethesamenameasglobalvariables,orlocalvariableswhichanotherprocedureoradiÞerentcalltothesameprocedurecreated.Youcancreatemanydistinctvariableswiththesamename.Example1Thefollowingprocedurecreatesanewlocalvariable,a,andthenreturnsthisnewvariable.>make_a:=proc()>locala;>a;>endproc;make_a:=proc()locala;aendprocByusinglocalvariables,youcanproducedisplaysthatMaplewouldotherwisesimplify.Forexample,inMaple,asetcontainsuniqueelements.Thefollowingdemonstratesthateachvariableathatmake_areturnsisunique.>test:={a,a,a};test:=fag>test:=testunion{make_a()};test:=fa;ag>test:=testunion{'make_a'()$5};test:=fa;a;a;a;a;a;ag 20¯Chapter1:Procedures,Variables,andExtendingMapleThisdemonstratesthatMapleidentitiesconsistofmorethannames.Important:Independentofthenumberofvariablesyoucreatewiththesamename,whenyoutypeanameinaninteractivesession,Mapleinterpretsthatnametobeaglobalvariable.Youcaneasilyßndtheglobalaintheprevioussettest.>seq(evalb(i=a),i=test);true;false;false;false;false;false;falseExample2YoucandisplayexpressionsthatMaplewouldordinarilysimplifyau-tomatically.Forexample,Mapleautomaticallysimplißestheexpressiona+ato2a.Itisdiáculttodisplaytheequationa+a=2a.Todisplaysuchanequation,usetheproceduremake_afromExample1.>a+make_a()=2*a;a+a=2aWhenyoutypeanameinaninteractivesession,theMapleprograminterpretsitastheglobalvariable.Whilethispreventsyoufromusingtheassignmentstatementtodirectlyassignavaluetoanescapedlocalvariable,itdoesnotpreventyoufromusingtheassigncommand.YoumustwriteaMapleexpressionwhichextractsthevariable.Forexample,inthepreviousequation,youcanextractthelocalvariableabyremovingtheglobalafromtheleftsideoftheequation.>eqn:=%;eqn:=a+a=2a>another_a:=remove(x->evalb(x=a),lhs(eqn));another_a:=aYoucanthenassigntheglobalnameatothisextractedvariableandverifytheequation. 1.3LocalVariablesandInvokingProcedures¯21>assign(another_a=a);>eqn;2a=2a>evalb(%);trueAssumeFacilityForcomplicatedexpressions,youmustusetheassumecommandtoextractthedesiredvariable.Youmayhaveencounteredthissituationbeforewithoutrealizingit,whenyouwereusingtheassumefacilitytoremoveanassumption.Theassumefacilityattachesvariousdeßnitionstothevariableyouspecify,withoneresultbeingthatthenamesubsequentlyappearsasalocalnamewithanappendedtilde.Norelationshipexistsbetweenthelocalvariablebwithanassumption,whichisdisplayedasb~,andtheglobalvariablenamecontainingatildeb~.>assume(b>0);>x:=b+1;x:=b~+1>subs(`b~`=c,x);b~+1Whenyouclearthedeßnitionofthenamedvariable,theassociationbetweenthenameandthelocalnamewiththetildeislost,butexpressionscreatedwiththelocalnamestillcontainit.>b:=evaln(b);b:=b>x;b~+1Toreusetheexpression,youmusteitherperformasubstitutionbeforeremovingtheassumptionorperformsomemanipulationsoftheexpres-sionssimilartothoseusedfortheequationeqn. 22¯Chapter1:Procedures,Variables,andExtendingMapleProcedureasaReturnedObjectAnimportantuseforreturninglocalobjectsariseswhenthereturnedobjectisaprocedure.Whenyouwriteaprocedure,whichreturnsapro-cedure,youwilloftenßnditusefultohavetheprocedurecreateavariablethatholdsinformationpertinentonlytothereturnedprocedure.Thisal-lowsdiÞerentprocedures(ordiÞerentinvocationsofthesameprocedure)topassinformationamongthemselves.ThefollowingexamplesillustratehowdiÞerentprocedurespassinformation.Example3CreatingtheCartesianProductofaSequenceofSetsWhenyoupassasequenceofsetstotheprocedure,itconstructsanewprocedure.ThenewprocedurereturnsthenexttermintheCartesianproducteachtimeyouinvokeit.Localvariablesfromtheouterprocedureareusedtokeeptrackofwhichtermtoreturnnext.TheCartesianproductofasequenceofsetsisthesetofalllistsinwhichtheithentryisanelementoftheithset.Thus,theCartesianproductoff«;¬;•gandfx;ygisf«;¬;•g¢fx;yg=f[«;x];[¬;x];[•;x];[«;y];[¬;y];[•;y]g:ThenumberofelementsintheCartesianproductofasequenceofsetsgrowsveryrapidlyasthenumberofsetsorsizeofthesetsincreases.ItthereforerequiresalargeamountofmemorytostorealltheelementsoftheCartesianproduct.SolutionYoumustwriteaprocedurethatreturnsanewelementoftheCartesianproducteachtimeyoucallit.Bycallingsuchaprocedurere-peatedly,youcanprocesseveryelementintheCartesianproductwithoutstoringallitselementsatonce.ThefollowingprocedurereturnsthenextelementoftheCartesianproductofthelistofsetss.Itusesanarray,c,ofcounterstodeterminethenextelement.Forexample,c[1]=3andc[2]=1correspondtothethirdelementoftheßrstsetandtheßrstelementofthesecondset.>s:=[{alpha,beta,gamma},{x,y}];s:=[f•;«;¬g;fx;yg]>c:=array(1..2,[3,1]);c:=[3;1] 1.3LocalVariablesandInvokingProcedures¯23>[seq(s[j][c[j]],j=1..2)];[¬;x]Beforeyoucalltheelementprocedureyoumustinitializeallthecoun-tersto1,excepttheßrstone,whichmustbe0.>c:=array([0,1]);c:=[0;1]Infollowingprocedureelement,nops(s)isthenumberofsetsandnops(s[i])isthenumberofelementsintheithset.Whenyouhaveseenalltheelements,theprocedurere-initializesthearrayofcountersandreturnsFAIL.Therefore,youcanrepeatedlytracetheCartesianproductbycallingelement.>element:=proc(s::list(set),c::array(1,nonnegint))>locali,j;>foritonops(s)do>c[i]:=c[i]+1;>ifc[i]<=nops(s[i])then>return[seq(s[j][c[j]],j=1..nops(s))];>endif;>c[i]:=1;>enddo;>c[1]:=0;>FAIL;>endproc:>element(s,c);element(s,c);element(s,c);[•;x][«;x][¬;x]>element(s,c);element(s,c);element(s,c);[•;y][«;y][¬;y] 24¯Chapter1:Procedures,Variables,andExtendingMaple>element(s,c);FAIL>element(s,c);[•;x]Example4InsteadofwritinganewprocedureforeachCartesianproductyoustudy,youcanwriteaprocedure,CartesianProduct,thatreturnssuchapro-cedure.CartesianProductcreatesalist,s,ofitsarguments,whichmustbesets,andtheninitializesthearray,c,ofcountersanddeßnesthesub-procedureelement.Finally,theelementsubprocedureisinvokedinsideaprocstructure.>CartesianProduct:=proc()>locals,c,element;>s:=[args];>ifnottype(s,list(set))then>error"expectedasequenceofsets,butreceived",>args;>endif;>c:=array([0,1$(nops(s)-1)]);>>element:=proc(s::list(set),c::array(1,nonnegint))>locali,j;>foritonops(s)do>c[i]:=c[i]+1;>ifc[i]<=nops(s[i])then>return[seq(s[j][c[j]],j=1..nops(s))];>endif;>c[i]:=1;>enddo;>c[1]:=0;>FAIL;>endproc;>>proc()>element(s,c);>endproc;>endproc:Again,youcanßndallsixelementsoff«;¬;•g¢fx;yg.>f:=CartesianProduct({alpha,beta,gamma},{x,y}); 1.3LocalVariablesandInvokingProcedures¯25f:=proc()element(s;c)endproc>to7dof()enddo;[•;x][«;x][¬;x][•;y][«;y][¬;y]FAILYoucanuseCartesianProducttostudyseveralproductssimultane-ously.>g:=CartesianProduct({x,y},{N,Z,R},>{56,23,68,92});g:=proc()element(s;c)endprocThefollowingaretheßrstfewelementsoffx;yg¢fN;Z;Rg¢f56;23;68;92g.>to5dog()enddo;[x;N;23][y;N;23][x;Z;23][y;Z;23][x;R;23]ThevariablessinfandgarelocalvariablestoCartesianProduct,sotheyarenotsharedbydiÞerentinvocationsofCartesianProduct.Similarly,thevariablecinfandgisnotshared.YoucanseethatthetwoarraysofcountersarediÞerentbyinvokingfandgafewmoretimes. 26¯Chapter1:Procedures,Variables,andExtendingMaple>to5dof(),g()enddo;[•;x];[y;R;23][«;x];[x;N;56][¬;x];[y;N;56][•;y];[x;Z;56][«;y];[y;Z;56]TheelementprocedureingisalsolocaltoCartesianProduct.There-fore,youcanchangethevalueoftheglobalvariableelementwithoutbreakingg.>element:=45;element:=45>g();[x;R;56]SummaryThepreviousexamplesdemonstratethatlocalvariablescanescapetheboundsoftheprocedureswhichcreatethem,andthatescapedvariablesallowyoutowriteprocedureswhichcreatespecializedproce-dures.Exercises1.TheprocedurethatCartesianProductgeneratesdoesnotworkifoneofthesetsisempty.>f:=CartesianProduct({},{x,y});f:=proc()element(s;c)endproc>f();Error,(inelement)invalidsubscriptselector 1.4InteractiveInput¯27Improvethetype-checkinginCartesianProductsothatitgeneratesaninformativeerrormessageineachsuchcase.2.Apartitionofapositiveinteger,n,isalistofpositiveintegerswhosesumisn.Thesameintegercanappearseveraltimesinthepartitionbuttheorderoftheintegersinthepartitionisirrelevant.Thus,thefollowingareallthepartitionsof5:[1;1;1;1;1];[1;1;1;2];[1;1;3];[1;2;2];[1;4];[2;3];[5]:Writeaprocedurethatgeneratesaprocedurethatreturnsanewpartitionofneachtimeyoucallit.1.4InteractiveInputNormallyyoupassinputtoMapleproceduresasparameters.Sometimes,however,youneedaproceduretorequestinputdirectlyfromtheuser.Forexample,youcanwriteaprocedurethattestsstudentsonsometopicbygeneratingrandomproblemsandverifyingthestudents'answers.Theinputcanbethevalueofaparameter,ortheanswertoaquestionsuchaswhetheraparameterispositive.ThetwocommandsinMapleforreadinginputfromtheterminalarethereadlinecommandandthereadstatcommand.ReadingStringsfromtheTerminalThereadlinecommandreadsonelineoftextfromaßleorthekeyboard.Usethereadlinecommandasfollows.readline(filename)Ifßlenameisthespecialnameterminal,thenreadlinereadsalineoftextfromthekeyboard.Thereadlinecommandreturnsthetextasastring.>s:=readline(terminal);Maplesofts:=ÕMaplesoftÔ 28¯Chapter1:Procedures,Variables,andExtendingMapleExample1Thefollowingapplicationpromptstheuserforananswertoaquestion.>DetermineSign:=proc(a::algebraic)locals;>printf("Isthesignof%apositive?Answeryesorno:",a);>s:=readline(terminal);>evalb(s="yes"ors="y");>endproc:>DetermineSign(u-1);Isthesignofu-1positive?Answeryesorno:ytrueInformation:Formoredetailsonthereadlinecommand,seeRead-ingTextLinesfromaFileonpage197.ReadingExpressionsfromtheTerminalYoucanwriteproceduresthatinterpretuserinputasaMapleexpressionratherthanastring.Thereadstatcommandreadsoneexpressionfromthekeyboard.readstat(prompt)Thepromptisanoptionalstring.>readstat("Enterdegree:");Enterdegree:n-1;n1Theuserinputforareadstatcommandmusthaveaterminatingsemi-colonorcolon,oranerrorisraised.AdvantagesUnlikethereadlinecommand,whichonlyreadsoneline,thereadstatallowsyoutobreakalargeexpressionacrossmultiplelines.Anotheradvantageofusingthereadstatcommandisthatifthereisanerrorintheinput,thereadstatcommandautomaticallyrepeatsthepromptforuserinput. 1.4InteractiveInput¯29>readstat("Enteranumber:");Enteranumber:5^^8;syntaxerror,`^`unexpected:5^^8;^Enteranumber:5^8;390625Example2Thefollowingisanapplicationofthereadstatcommandthatimple-mentsaninterfacetothelimitcommand.Theprocedure,giventhefunctionf(x),assumesxisthevariableifonlyonevariableispresent.Otherwise,theuserisaskedforthevariableandthelimitpoint.>GetLimitInput:=proc(f::algebraic)>localx,a,K;>#chooseallvariablesinf>K:=select(type,indets(f),name);>>ifnops(K)=1then>x:=K[1];>else>x:=readstat("Inputlimitvariable:");>whilenottype(x,name)do>printf("Avariableisrequired:received%a ",x);>x:=readstat("Pleasere-inputlimitvariable:");>enddo;>endif;>a:=readstat("Inputlimitpoint:");>x=a;>endproc:Theexpressionsin(x)=xdependsonlyononevariable,soGetLimitInputdoesnotpromptforalimitvariable.>GetLimitInput(sin(x)/x);Inputlimitpoint:0;x=0 30¯Chapter1:Procedures,Variables,andExtendingMapleInthefollowingoutput,theuserßrsttriestousethenumber1asthelimitvariable.Because1isnotaname,GetLimitInputrequestsanotherlimitvariable.>GetLimitInput(exp(u*x));Inputlimitvariable:1;Avariableisrequired:received1Pleasere-inputlimitvariable:x;Inputlimitpoint:infinity;x=1Information:Youcanspecifyanumberofoptionstoreadstat.Formoreinformation,seeReadingMapleStatementsonpage204.ConvertingStringstoExpressionsForgreatercontrolofhowandwhenMapleevaluatesuserinputtoapro-cedure,usethereadlinecommandinsteadofreadstat.Thereadlinecommandreadstheinputasastring,andtheparsecommandconvertsthestringtoanexpression.Thestringmustrepresentacompleteexpres-sion.>s:="a*x^2+1";s:=Õa*x^2+1Ô>y:=parse(s);y:=ax2+1Whenyouparsethestringsyougetanexpression.Inthiscase,yougetasum.>type(s,string),type(y,`+`);true;true 1.5ExtendingMaple¯31Theparsecommanddoesnotevaluatetheexpressionitreturns.Youmustuseevaltoevaluatetheexpressionexplicitly.Inthefollowingout-put,thevariableaisnotevalutedtoitsvalue,2,untilyouexplicitlyusetheevalcommand.>a:=2;a:=2>z:=parse(s);z:=ax2+1>eval(z);2x2+1Information:Formoredetailsabouttheparsecommand,seeParsingMapleExpressionsandStatementsonpage218.SummaryThetechniquesinthissectionareverysimple,butyoucanusethemtocreateusefulapplicationssuchasMapletutorials,proceduresthatteststudents,orinteractivelessons.1.5ExtendingMapleAlthoughitmaybeusefultowritecustomprocedurestoperformnewtasks,sometimesextendingtheabilitiesofMaplecommandsismostben-eßcial.Thissectionfamiliarizesyouwith:¯Deßningcustomtypesandoperators¯ModifyinghowMapledisplaysexpressions¯Extendingcommandssuchassimplifyandexpand.DeßningNewTypesIfyouareusingacomplicatedstructuredtype,itisrecommendedthatyouassignthestructuredtypetoavariableoftheform`type/name`. 32¯Chapter1:Procedures,Variables,andExtendingMapleWritingthestructureoncereducestheriskoferrors.Whenyouhavedeßnedthevariable`type/name`,youcanusenameasatype.>`type/Variables`:={name,list(name),set(name)}:>type(x,Variables);true>type({x[1],x[2]},Variables);trueIfthestructuredtypemechanismisnotpowerfulenough,youcandeßneanewtypebyassigningaproceduretoavariableoftheform`type/name`.Whenyoutestwhetheranexpressionisoftypename,Mapleinvokestheprocedure`type/name`ontheexpressionifsuchaprocedureexists.Theprocedureshouldreturntrueorfalse.Thefol-lowing`type/permutation`proceduredeterminesifpisapermutationoftheßrstnpositiveintegers.Thatis,pshouldcontainexactlyonecopyofeachintegerfrom1throughn.>`type/permutation`:=proc(p)>locali;>type(p,list)and{op(p)}={seq(i,i=1..nops(p))};>endproc:>type([1,5,2,3],permutation);false>type([1,4,2,3],permutation);trueThetype-testingprocedurecanacceptmorethanoneparameter.Whenyoutestifanexpression,expr,hastypename(parameters),thenMapleinvokes`type/name`(expr,parameters)ifsuchaprocedureexists.Thefollowing`type/LINEAR`procedurede-terminesiffisapolynomialinVofdegree1. 1.5ExtendingMaple¯33>`type/LINEAR`:=proc(f,V::name)>type(f,polynom(anything,V))anddegree(f,V)=1;>endproc:>type(a*x+b,LINEAR(x));true>type(x^2,LINEAR(x));false>type(a,LINEAR(x));falseExercises1.Modifythe`type/LINEAR`proceduresothatyoucanuseittotestifanexpressionislinearinasetofvariables.Forexample,x+ay+1islinearinbothxandy,butxy+a+1isnot.2.DeßnethetypePOLYNOM(X)whichtestsifanalgebraicexpressionisapolynomialinXwhereXisaname,alistofnames,orasetofnames.NeutralOperatorsTheMaplesoftwarerecognizesmanyoperators,forexample+,*,^,and,not,andunion.TheseoperatorshavespecialmeaningtoMaple.Theoperatorscanrepresent:¯Algebraicoperations,suchasadditionormultiplication¯Logicaloperations¯OperationsperformedonsetsMaplealsohasaspecialclassofoperators,theneutraloperators,onwhichitdoesnotimposeanymeaning.Instead,Mapleallowsyoutodeßnethemeaningofanyneutraloperator.Thenameofaneutraloperatorbeginswiththeampersandcharacter(&).>7&^8&^9; 34¯Chapter1:Procedures,Variables,andExtendingMaple(7&^8)&^9>evalb(7&^8=8&^7);false>evalb((7&^8)&^9=7&^(8&^9));falseInternally,Maplerepresentsneutraloperatorsasprocedurecalls.Thus,7&^8isaconvenientwayofwriting&^(7,8).>&^(7,8);7&^8Mapleusestheinßxnotation,inwhichtheoperatorisplacedbetweentheoperands,onlyiftheneutraloperatorhasexactlytwoarguments.>&^(4),&^(5,6),&^(7,8,9);&^(4);5&^6;&^(7;8;9)Information:Formoreinformationonnamingconventionsforneutraloperators,refertochapter3oftheIntroductoryProgrammingGuide.Example1Youcandeßnetheactionsofaneutraloperatorbyassigningaproce-duretoitsname.ThefollowingexampleimplementstheHamiltoniansbyassigninganeutraloperatortoaprocedurethatmultipliestwoHamilto-nians.MathematicalPremiseTheHamiltoniansorQuaternionsextendthecomplexnumbersinthesamewaythecomplexnumbersextendtherealnumbers.EachHamiltonianhastheforma+bi+cj+dkwherea,b,c,anddarerealnumbers.Thespecialsymbolsi,j,andksatisfythefollowingmultiplicationrules:i2=1,j2=1,k2=1,ij=k,ji=k,ik=j,ki=j,jk=i,andkj=i. 1.5ExtendingMaple¯35Thefollowing`&^`procedureusesI,J,andKasthethreespecialsymbols.However,IisimplementedasthecompleximaginaryunitinMaple.Therefore,youshouldassignanotherlettertorepresenttheimag-inaryunitbyusingtheinterfacefunction.Formoreinformation,referto?interface.>interface(imaginaryunit=j);Youcanmultiplymanytypesofexpressionsbyusing`&^`,makingitconvenienttodeßneanewtype,Hamiltonian,byassigningastructuredtypetothename`type/Hamiltonian`.>`type/Hamiltonian`:={`+`,`*`,name,realcons,>specfunc(anything,`&^`)};type=Hamiltonian:=f£;+;realcons;name;specfunc(anything;&^)gThe`&^`proceduremultipliesthetwoHamiltonians,xandy.Ifeitherxoryisarealnumberorvariable,thentheirproductistheusualproductdenotedby*inMaple.Ifxoryisasum,`&^`mapstheproductontothesum;thatis,`&^`appliesthedistributivelaws:x(u+v)=xu+xvand(u+v)x=ux+vx.Ifxoryisaproduct,`&^`extractsanyrealfactors.Youmusttakespecialcaretoavoidinßniterecursionwhenxoryisaproductthatdoesnotcontainrealfactors.Ifnoneofthemultiplicationrulesapply,`&^`returnstheproductunevaluated.>`&^`:=proc(x::Hamiltonian,y::Hamiltonian)>localReal,unReal,isReal;>isReal:=z->evalb(is(z,real)=true);>>ifisReal(x)orisReal(y)then>x*y;>>eliftype(x,`+`)then>#xisasum,u+v,sox&^y=u&^y+v&^y.>map(`&^`,x,y);>>eliftype(y,`+`)then>#yisasum,u+v,sox&^y=x&^u+x&^v.>map2(`&^`,x,y);>>eliftype(x,`*`)then>#Pickouttherealfactorsofx.>Real,unReal:=selectremove(isReal,x);>#Nowx&^y=Real*(unReal&^y)>ifReal=1then>iftype(y,`*`)then 36¯Chapter1:Procedures,Variables,andExtendingMaple>Real,unReal:=selectremove(isReal,x);>Real*'`&^`'(x,unReal);>else>'`&^`'(x,y);>endif;>else>Real*`&^`(unReal,y);>endif;>>eliftype(y,`*`)then>#Similartothex-casebuteasiersince>#xcannotbeaproducthere.>Real,unReal:=selectremove(isReal,y);>ifReal=1then>'`&^`'(x,y);>else>Real*`&^`(x,unReal);>endif;>>else>'`&^`'(x,y);>endif;>endproc:YoucanplaceallthespecialmultiplicationrulesforthesymbolsI,J,andKintheremembertableof`&^`.Information:Formoreinformationonremembertables,refertochap-ter6oftheIntroductoryProgrammingGuide.>`&^`(I,I):=-1:`&^`(J,J):=-1:`&^`(K,K):=-1:>`&^`(I,J):=K:`&^`(J,I):=-K:>`&^`(I,K):=-J:`&^`(K,I):=J:>`&^`(J,K):=I:`&^`(K,J):=-I:Since`&^`isaneutraloperator,youcanwriteproductsofHamilto-niansusing&^asthemultiplicationsymbol.>(1+2*I+3*J+4*K)&^(5+3*I-7*J);20+41I+20J3K>(5+3*I-7*J)&^(1+2*I+3*J+4*K);2015I4J+43K>56&^I; 1.5ExtendingMaple¯3756IInthefollowingexample,aisanunknownHamiltonianuntilyouentertheassumptionthataisanunknownrealnumber.>a&^J;a&^J>assume(a,real);>a&^J;a~JExercise1.TheinverseofageneralHamiltonian,a+bi+cj+dk,is(abicjdk)=(a2+b2+c2+d2).Youcandemonstratethisfactbyassumingthata,b,c,anddarerealanddeßneageneralHamiltonian,h.>assume(a,real);assume(b,real);>assume(c,real);assume(d,real);>h:=a+b*I+c*J+d*K;h:=a~+b~I+c~J+d~KBytheformulaabove,thefollowingshouldbetheinverseofh.>hinv:=(a-b*I-c*J-d*K)/(a^2+b^2+c^2+d^2);a~b~Ic~Jd~Khinv:=a~2+b~2+c~2+d~2Checkthath&^hinvandhinv&^hsimplifyto1.>h&^hinv; 38¯Chapter1:Procedures,Variables,andExtendingMaplea~(a~b~Ic~Jd~K)%1b~(Ia~+b~c~K+d~J)+%1c~(Ja~+b~K+c~d~I)+%1d~(Ka~b~J+c~I+d~)+%1%1:=a~2+b~2+c~2+d~2>simplify(%);1>hinv&^h;a~(a~b~Ic~Jd~K)%1a~b~I+b~2+b~c~Kb~d~J+%1a~c~Jb~c~K+c~2+c~d~I+%1a~d~K+b~d~Jc~d~I+d~2+%1%1:=a~2+b~2+c~2+d~2>simplify(%);1Writeaprocedure,`&/`,thatcomputestheinverseofaHamiltonian.Itisrecommendedthatyouimplementthefollowingrules.&/(&/x)=x;&/(x&^y)=(&/y)&^(&/x);x&^(&/x)=1=(&/x)&^x: 1.5ExtendingMaple¯39ExtendingCommandsIfyouintroducecustomdatastructures,therearenomanipulationrulesforthem.Inmostcases,youwritespecial-purposeproceduresthatmanip-ulatenewdatastructures.However,sometimesextendingthecapabilitiesofoneormoreoftheMaplebuilt-incommandsiseasierthandevelop-ingnewdatastructuresandspecial-purposeprocedures.YoucanextendseveralMaplecommands,amongthemexpand,simplify,diff,series,andevalf.ExtendingtheDiffCommandYoucanrepresentapolynomialanun+an1un1+¡¡¡+a1u+a0byusingthedatastructurePOLYNOM(u,a_0,a_1,...,a_n)YoucanthenextendthediffcommandsothatyoucandiÞerentiatepolynomialsrepresentedinthatway.Ifyouwriteaprocedurewithanameoftheform`diff/F`thendiffinvokesitonanyunevaluatedcallstoF.Specißcally,ifyouusedifftodiÞerentiateF(arguments)withrespecttox,thendiffinvokes`diff/F`asfollows.`diff/F`(arguments,x)ThefollowingprocedurediÞerentiatesapolynomialinuwithconstantcoeácientswithrespecttox.>`diff/POLYNOM`:=proc(u)>locali,s,x;>x:=args[-1];>s:=seq(i*args[i+2],i=1..nargs-3);>'POLYNOM'(u,s)*diff(u,x);>endproc:>diff(POLYNOM(x,1,1,1,1,1,1,1,1,1,1),x);POLYNOM(x;1;2;3;4;5;6;7;8;9)>diff(POLYNOM(x*y,34,12,876,11,76),x);POLYNOM(xy;12;1752;33;304)y 40¯Chapter1:Procedures,Variables,andExtendingMapleExtendingthesimplifyCommandTheimplementationoftheHamil-toniansinthissection1.5doesnotincludetheassociativeruleformultipli-cationofHamiltonians,thatis(xy)z=x(yz).Sometimes,usingassocia-tivitysimplißesaresult.RecallthatIhereisnotthecompleximaginaryunit,butrather,oneofthespecialsymbolsI,J,andKthatarepartofthedeßnitionoftheHamiltonians.>x&^I&^J;(x&^I)&^J>x&^(I&^J);x&^KYoucanextendthesimplifycommandsothatitappliestheas-sociativelawtounevaluatedproductsofHamiltonians.Ifyouwriteaprocedurewithanameoftheform`simplify/F`,thensimplifyin-vokesitonanyunevaluatedfunctioncallstoF.Thus,youmustwriteaprocedure`simplify/&^`thatappliestheassociativelawtoHamiltoni-ans.Thefollowingprocedureusesthetypematchcommandtodetermineifitsargumentisoftheform(a&^b)&^cand,ifso,itselectsthea,b,andc.>s:=x&^y&^z;s:=(x&^y)&^z>typematch(s,'`&^`'('`&^`'(a::anything,b::anything),>c::anything));true>a,b,c;x;y;z 1.5ExtendingMaple¯41TheuserinfoCommandYoucangivetheuserdetailsaboutproceduresimplißcationsusingtheuserinfocommand.The`simplify/&^`pro-cedureprintsaninformativemessageifyousetinfolevel[simplify]orinfolevel[all]togreaterthanorequaltoleast2.>`simplify/&^`:=proc(x)>locala,b,c;>iftypematch(x,>'`&^`'('`&^`'(a::anything,b::anything),>c::anything))then>userinfo(2,simplify,"applyingtheassociativelaw");>a&^(b&^c);>else>x;>endif;>endproc:ApplyingtheassociativelawsimplißessomeproductsofHamiltoni-ans.>x&^I&^J&^K;((x&^I)&^J)&^K>simplify(%);xIfyousetinfolevel[simplify]toasuácientlylargevalue,Mapleprintsinformationonthemethodsusedbysimplifywhileattemptingtosimplifytheexpression.>infolevel[simplify]:=5;infolevelsimplify:=5>w&^x&^y&^z;((w&^x)&^y)&^z>simplify(%);simplify/&^:"applyingtheassociativelaw"simplify/&^:"applyingtheassociativelaw" 42¯Chapter1:Procedures,Variables,andExtendingMaplew&^((x&^y)&^z)Information:Fordetailsonhowtoextendthesecommands,referto?expand,?series,and?evalf.Forinformationonextendingtheevalfcommand,seealso4.4ExtendingtheevalfCommand.1.6ConclusionProcedureswhichreturnproceduresandlocalvariablesarefundamentaltoadvancedprogramming.InteractiveinputandextendingMaplearealsoimportanttopicsinadvancedprogramming. 2ProgrammingwithModulesProceduresallowyoutoassociateasequenceofcommandswithasinglecommand.Similarly,modulesallowyoutoassociaterelatedproceduresanddata.ModulesThischapterdescribesMaplemodules.ModulesareatypeofMapleex-pression(likenumbers,equations,andprocedures),thatenableyoutowritegenericalgorithms,createpackages,orusePascal-stylerecordsinprograms.Theuseofmodulessatißesfourimportantsoftwareengineeringconcepts.¯Encapsulation¯Packages¯ObjectModeling¯GenericProgrammingEncapsulationguaranteesthatanabstractionisusedonlyaccordingtoitsspecißedinterface.YoucanwritesignißcantsoftwaresystemsthataretransportableandreusableandthatoÞerclean,well-deßneduserinter-faces.ThismakescodeeasiertomaintainandunderstandÜimportantpropertiesforlargesoftwaresystems.PackagesareavehicleforbundlingMapleproceduresrelatedtoaprob-lemdomain.MuchofthefunctionalityofthestandardMaplelibraryresidesinpackages.43 44¯Chapter2:ProgrammingwithModulesObjectsareeasilyrepresentedusingmodules.Insoftwareengineeringorobject-orientedprogramming,anobjectisdeßnedassomethingthathasbothstateandbehavior.Youcomputewithobjectsbysendingthemmessages,towhichtheyrespondbyperformingservices.GenericProgramsacceptobjectsthatpossessspecißcpropertiesorbe-haviors.Theunderlyingrepresentationoftheobjectistransparenttogenericprograms.ExamplesForbetterunderstanding,itishelpfultoexamineasmallmodule.Example1:SimpleModuleWhenMapleevaluatestherightsideoftheassignmenttoTempGenerator,itcreatesamoduleusingthemoduledeßnitionthatbeginswithmodule()...andendswithendmodule.>TempGenerator:=module()>description"generatorfortemporarysymbols";>exportgentemp;>localcount;>>count:=0;>gentemp:=proc()>count:=1+count;>`tools/gensym`(T||count)>endproc;>endmodule;TempGenerator:=module()localcount;exportgentemp;descriptionÕgeneratorfortemporarysymbolsÔ;endmoduleExampleSummaryThemoduledeßnitionresemblesaproceduredeß-nition.ThemaindiÞerencesaretheuseofthekeywordmoduleinsteadofproc(andthecorrespondingterminator)andtheexportdeclarationfollowingthedescriptionstring.Example2:ProcedureInthefollowingexample,thepreviousmoduleiswrittenusingonlyprocedures.>TempGeneratorProc:=proc()>description"generatorfortemporarysymbols";>localcount,gentemp;>count:=0; ¯45>gentemp:=proc()>count:=1+count;>`tools/gensym`(T||count)>endproc;>eval(gentemp,1)>endproc:YoucanassigntheprocedurereturnedbyTempGeneratorProc,andthenuseittogeneratetemporarysymbols.>f:=TempGeneratorProc();f:=proc()count:=1+count;`tools=gensym`(Tjjcount)endproc>f();T1>f();T2ModuleVersusProcedureThemoduleTempGeneratorandtheprocedureTempGeneratorProcaresimilar.Intheprocedureversion,thelocalvariablegentempisassignedapro-cedurethatreferencesanotherlocalvariablecount;thevalueofgentempisreturnedbytheproceduretoitscaller.Themoduleversionofthegeneratorbehavessimilarly.ItsstructurediÞers:itsgentempvariableisdeclaredasanexport,notalocal,andthereisnoexplicitreturn.Inbothversionsofthegenerator,thevariablescountandgentemparelocalvariables.ThesignißcantdiÞerencehereisthat,inthemoduleversion,oneofthoselocalvariablesisexported.Thismeansthatitisavailableoutsidethescopeofthestructureinwhichitwascreated.Specialsyntaxisusedaccessexportedlocalvariables.Forexample,tocalltheexportedvariablegentempofthemodule,enter>TempGenerator:-gentemp();T1 46¯Chapter2:ProgrammingwithModulesusingthememberselectionoperator:-.Amoduledeßnitionreturnsadatastructure(amodule)thatcontainsallofitsexportedlocalvariables.AccessingModuleExportsTheusestatementallowsyoutoaccessmoduleexports.>useTempGeneratorin>gentemp();>gentemp();>gentemp();>enduse;T2T3T4Withinthebodyofausestatement,theexportedlocalvariablesofthemodulethatappearsaftertheusekeywordcanbeaccesseddirectly,withoutusingthememberselectionoperator:-.InThisChapterThischapterprovidesmanyexamplemodules.Someexamplesareverysimple,designedtoillustrateaspecißcpoint.Othersaremoresubstantial.ManyofthenontrivialexamplesareavailableasMaplesourcecodeinthesamplesdirectoryoftheMapleinstallation.YoucanloadthemintotheprivateMaplelibraryandexperimentwiththem.Youcanmodify,extend,andimprovethesecodesamples,andusethemincustomprograms.Thefollowingtopicsarecoveredinthischapter.¯SyntaxandSemantics¯UsingModulesasRecordsorStructures¯UsingModulesToWriteMaplePackages¯TheuseStatement¯ModelingObjects¯InterfacesandImplementations 2.1SyntaxandSemantics¯472.1SyntaxandSemanticsThesyntaxofmoduledeßnitionsisverysimilartothatofprocedures,giveninchapter6oftheIntroductoryProgrammingGuide.Hereisanexampleofasimplemoduledeßnition.>module()>exporte1;>locala,b;>>a:=2;>b:=3;>e1:=x->a^x/b^x;>endmodule:Evaluatingthisexpressionresultsinamodulewithoneexport,e1,andtwolocalvariables,aandb.Atemplateforamoduledeßnitionlookslike:module()localL;exportE;globalG;optionsO;descriptionD;BendmoduleThesimplestvalidmoduledeßnitionis>module()end;module()endmoduleThismoduledeßnitiondoesnothave:exportedvariables,locals,ref-erences,globalvariables,orabodyofstatements.Themoduletowhichthisevaluatesisnotveryuseful.TheModuleDeßnitionEverymoduledeßnitionbeginswiththekeywordmodule,followedbyanemptypairofparentheses.Followingthatisanoptionaldeclarationsectionandthemodulebody.Thekeywordcombinationendmodule(orjustend)terminatesamoduledeßnition. 48¯Chapter2:ProgrammingwithModulesTheModuleBodyThebodyofamoduledeßnitionconsistsofthefollowing.¯ZeroormoreMaplestatements.Thebodyisexecutedwhenthemod-uledeßnitionisevaluated,producingamodule.¯Anumberofassignmentstatementsthatgivevaluestotheexportednamesofthemodule.Thebodyofamoduledeßnitioncanalsocontain:¯Assignmentstolocalvariables,andperformanceofarbitrarycompu-tations.¯Areturnstatement,butcannotcontainabreakornextstatementoutsidealoop.Executingareturnstatementterminatestheexecu-tionofthebodyofthemoduledeßnition.ModuleParametersModuledeßnitionsbeginwiththeMaplekeywordmodule,followedbyan(empty)pairofparentheses.Thisissimilartotheparenthesesthatfollowtheprockeywordinaproceduredeßnition.Unlikeprocedures,however,moduledeßnitionsdonothaveexplicitparametersbecausemodulesarenotcalled(orinvoked)witharguments.ImplicitParametersEverymoduledeßnitionhasanimplicitparametercalledthismodule.Withinthebodyofamoduledeßnition,thisspecialnameevaluatestothemoduleinwhichitoccurs.Thisallowsyoutorefertoamodulewithinitsowndeßnition(beforetheresultofevaluatingithasbeenassignedtoaname).Allproceduredeßnitionscanreferencetheimplicitparametersproc-name,args,andnargs.Moduledeßnitionscannotreferencetheseim-plicitparameters.Additionally,thediÞerencebetweenthismoduleandprocnameisthatprocnameevaluatestoaname,whilethismoduleevaluatestothemoduleexpressionitself.Thisisbecausetheinvocationphaseofevaluatingamoduledeßnitionispartofitsnormalevaluation,anditoccursimmediately.Procedures,ontheotherhand,arenotinvokeduntilcalledwitharguments.Normally,atleastonenameforaprocedureisknownbythetimeitiscalled;thisisnotthecaseformodules.NamedModulesAnoptionalsymbolmayappearafterthemodulekeywordinamod-uledeßnition.Modulescreatedwiththisvariantonthesyntaxarecalled 2.1SyntaxandSemantics¯49namedmodules.Semantically,namedmodulesarenearlyidenticaltonormalmodules,buttheexportedmembersofnamedmodulesareprinteddiÞerently,allowingthemodulefromwhichitwasexportedtobeidenti-ßedvisually.>NormalModule:=module()exporte;end;NormalModule:=module()exporte;endmodule>NormalModule:-e;eHere,thesymbol(thenameofthemodule)afterthemodulekeywordisNamedModule.>moduleNamedModule()exporte;endmodule;moduleNamedModule()exporte;endmodule>NamedModule:-e;NamedModule:eWhenthedeßnitionofanamedmoduleisevaluated,thename(whichappearsimmediatelyafterthemodulekeyword)isassignedthemoduleasitsvalue,andthenameisprotected.Therefore,anamedmodulecan,ordinarily,becreatedonlyonce.Forexample,anattempttoexecutethesamenamedmoduledeßnitionyieldsanerror.>moduleNamedModule()exporte;endmodule;Error,(inNamedModule)attemptingtoassignto`NamedModule`whichisprotectedExecutingthenormalmoduledeßnitionagaincreatesanewin-stanceofthemodule,butdoesnotresultinanerror.(ItsimplyreassignsthevariableNormalModuletothenewmoduleinstance.)>NormalModule:=module()exporte;end;NormalModule:=module()exporte;endmodule 50¯Chapter2:ProgrammingwithModulesImportantDonotassignanamedmoduletoanothervariable.>SomeName:=eval(NamedModule);SomeName:=moduleNamedModule()exporte;endmodule>SomeName:-e;NamedModule:eExportsofnamedmodulesareprintedusingthedistinguishednamethatwasgiventothemodulewhenitwascreated,regardlessofwhetherithasbeenassignedtoanothername.WhetheramodulehasanamealsoaÞectsthereportingoferrorsthatoccurduringitsevaluation.Whenthesecondattempttoevaluatethenamedmoduledeßnitionabovefailed,theerrormessagereportedthelocationoftheerrorbyname.Bycontrast,whenanerroroccursduringtheevaluationofanormalmoduledeßnition,thenameunknownisusedinstead.>NormalModule:=module()exporte;error"oops";end;Error,(inunknown)oopsThisdiÞersfromprocedureerrorreporting.Maplecannotreportthenameofanormalmodule(thatis,thenameofthevariabletowhichthemoduleisassigned),becausetheevaluationoftherightsideofanassignmentoccursbeforetheassignmenttothenametakesplace.Sotheerroroccursbeforeanyassociationbetweenavariableandthemodulehasoccurred.DeclarationsThedeclarationssectionofthemodulemustappearimmediatelyaftertheparentheses.Allstatementsinthedeclarationssectionareoptional,butatmostoneofeachkindmayappear.Mostmoduledeclarationsarethesameasthoseforprocedures.DescriptionStringsProvideabriefdescriptionoutliningthepurposeandfunctionofanymoduleyouwrite.Itisvaluabletootheruserswhoreadyourcode.Includeanoverviewafterthedescriptionkeyword,justasyouwouldinaproceduredeßnition. 2.1SyntaxandSemantics¯51>Hello:=module()>description"myfirstmodule";>exportsay;>say:=proc()>print("HELLOWORLD")>endproc;>endmodule:Whenthemoduleisprinted,itsdescriptionstringisdisplayed.>eval(Hello);module()exportsay;descriptionÕmyßrstmoduleÔ;endmoduleTheexportdeclarationisexplainedlaterinthischapter.GlobalVariablesGlobalvariablesreferencedwithinamoduledeßnitionshouldbedeclaredwiththeglobaldeclaration.Followingthekeywordglobalisasequenceofoneormoresymbols.Thesesymbolsareboundtotheirglobalinstances.Incertaincasesyoumustdeclareanameasaglobalvariabletopreventimplicitscopingrulesfrommakingitlocal.>Hello:=module()>exportsay;>globalmessage;>say:=proc()>message:="HELLOWORLD!">endproc;>endmodule:>message;message>Hello:-say();ÕHELLOWORLD!Ô>message;ÕHELLOWORLD!Ô 52¯Chapter2:ProgrammingwithModulesLocalVariablesYoucanrefertovariablesthatarelocaltothemoduledeßnitionbyusingthelocaldeclaration.Itsformatisthesameasforprocedures.HereisavariantonthepreviousHellomodulewhichusesalocalvariable.>Hello:=module()>localloc;>exportsay;>loc:="HELLOWORLD!";>say:=proc()>print(loc)>endproc;>endmodule:Localvariablesarenotvisibleoutsidethedeßnitionofthemoduleinwhichtheyoccur.Theyareprivatetothemodule,andareexactlyanalogoustolocalvariablesofprocedures.Alocalvariableinamodule(orprocedure)isadistinctobjectfromaglobalvariablewiththesamename.Localvariablesarenormallyshort-livedvariables;thenormallifetimeofalocalvariableistheexecutiontimeofthebodyofcode(amoduleorprocedurebody)towhichitislocal.(Localvariablesmaypersistonceexecutionofthescopeinwhichtheyoc-curhascompleted,buttheyarenormallyinaccessableandwilleventuallyberecycledbytheMapleautomaticstoragemanagementsystem.)ExportedLocalVariablesProceduresandmodulesbothsupportlocalvariables.Onlymodulessup-portexportedlocalvariables,oftenreferredtosimplyasexports.Moduleexportsaredeclaredusingtheexportdeclaration.Itbeginswiththekeywordexport,afterwhichfollowsa(nonempty)sequenceofsymbols.Anameisneverexportedimplicitly;exportsmustbedeclared.Theresultofevaluatingamoduledeßnitionisamodule.Youcanviewamoduleasacollectionofitsexports,whicharealsoreferredtoasmembersofthemodule.Thesearesimplynamesthatcan(butneednot)beassignedvalues.Youcanestablishinitialvaluesfortheexportsbyassigningtotheminthebodyofthemoduledeßnition.Thewordexportisshortforexportedlocalvariable.Inmostrespects,amoduleexportisalocalvariable(suchasthosedeclaredviathelocaldeclaration.)ThecrucialdiÞerenceisthatyoucanaccesstheexportedlocalvariablesofamoduleafterithasbeencreated.Toaccessanexportofamodule,usethe:-memberselectionopera-tor.Itsgeneralsyntaxis: 2.1SyntaxandSemantics¯53modexpr:-membernameHere,modexprmustbeanexpressionthatevaluatestoamodule,andmembernamemustbethenameofanexportofthemoduletowhichmodexprevaluates.Anythingelsesignalsanexception.Youcannotac-cesslocalvariablesofaninstantiatedmodulebyusingthissyntax.Localvariablesofaprocedurearecreatedwhentheprocedureiscalled(orinvoked).Normally,thelocalspersistonlyduringtheexecutionofthestatementsthatformthebodyoftheprocedure.Sometimes,however,localvariablespersistbeyondtheprocedureactivationthatinstantiatedthem.Forexample:>gen:=proc()>locals,p;>s:=2;>p:=x->s*x;>p>endproc:>g:=gen();g:=p>g(3);6Thelocalvariablesofgenpersistsaftergenhasreturned.Itiscap-turedintheclosureoftheprocedurep,whosenameisreturnedbygen.Thus,bothlocalvariablespandsofgenescape,butindiÞerentways.Thelocalnamepisaccessiblebecauseitistheassignedvalueoftheglobalvariableg.However,thereisnowaytorefertosoncegenhasreturned.NoMaplesyntaxexistsforthatpurpose.Thememberselectionoperator:-providesasyntaxforreferencingcertainlocalvariablesofmodulesÛthosedeclaredasexports.ThemostrecentHelloexamplehasoneexport,namedsay.Inthiscase,sayisassignedaprocedure.Tocallit,enter>Hello:-say();ÕHELLOWORLD!ÔThefollowingexpressionraisesanexception,becausethenamenoSuchModuleisnotassignedamoduleexpression. 54¯Chapter2:ProgrammingwithModules>noSuchModule:-e;Error,`noSuchModule`doesnotevaluatetoamoduleHere,amoduleexpressionisassignedtothenamem,andthememberselectionexpressionm:-eevaluatestothevalueoftheexportedvariableeofm.>m:=module()exporte;e:=2endmodule:>m:-e;2SincemdoesnotexportavariablenamednoSuchExport,thefollowingexpressionraisesanexception.>m:-noSuchExport;Error,moduledoesnotexport`noSuchExport`ImportantThefollowingmoduleexportsanunassignedname.Thisillustratestheimportanceofdistinguishingmoduleexportsfromglobalvariables.>m:=module()exporte;end:Referencestotheexportednameeinmevaluatetothenamee.>m:-e;eNote,however,thatthisisalocalnamee,nottheglobalinstanceofthename.>evalb(e=m:-e);falseTheßrsteinthepreviousexpressionreferstotheglobale,whiletheexpressionm:-eevaluatestotheethatislocaltothemodulem.Thisdistinctionbetweenaglobalandexportofthesamenameisuseful.Forexample,youcancreateamodulewithanexportsin.AssigningavaluetotheexportsindoesnotaÞecttheprotectedglobalnamesin. 2.1SyntaxandSemantics¯55TheexportsProcedureYoucandeterminethenamesoftheexportsofamodulebyusingtheexportsprocedure.>exports(Hello);say>exports(NormalModule);eThisreturnstheglobalinstancesoftheexportnames.>exports(m);e>evalb(%=e);trueYoucanalsoobtainthelocalinstancesofthosenamesbypassingtheoptioninstance.>exports(m,'instance');e>evalb(%=e);false>evalb(%%=m:-e);trueForthisreason,youcannothavethesamenamedeclaredbothasalocalandanexport.>module()exporte;locale;end;Error,exportandlocal`e`havethesamename 56¯Chapter2:ProgrammingwithModules(Thedeclaredexportsandlocalsactuallyformapartitionofthenamesthatarelocaltoamodule.)ThememberProcedureYouhavealreadyseenthebuilt-inprocedurememberthatisusedtotestformembershipinasetorlist.>member(4,{1,2,3});falseThisprocedurecanbeusedformembershiptestsinmodulesaswell.>member(say,Hello);true>member(cry,Hello);falseTheßrstargumentisa(global)namewhosemembershipistobetested,andthesecondargumentisamodule.Itreturnsthevaluetrueifthemodulehasanexportwhosenameisthesameastheßrstargument.Theprocedurememberalsohasathreeargumentformthatcanbeusedwithliststodeterminethe(ßrst)positionatwhichanitemoccurs.>member(b,[a,b,c],'pos');trueThenameposisnowassignedthevalue2becauseboccursatthesecondpositionofthelist[a,b,c].>pos;2Whenusedwithmodules,thethirdargumentisassignedthelocalinstanceofthenamewhosemembershipisbeingtested,providedthatthereturnvalueistrue.>member(say,Hello,'which'); 2.1SyntaxandSemantics¯57true>which;say>eval(which);proc()print(loc)endprocIfthereturnvaluefrommemberisfalse,thenthenameremainsunassigned(ormaintainsitspreviouslyassignedvalue).>unassign('which'):>member(cry,Hello,'which');false>eval(which);whichModuleOptionsAswithprocedures,amoduledeßnitionmaycontainoptions.Theop-tionsavailableformodulesarediÞerentfromthoseforprocedures.Onlytheoptionstrace,and`Copyright...`arecommontoproceduresandmodules.Thefollowingfouroptionshaveapredeßnedmeaningformod-ules:load,unload,package,andrecord.TheloadandunloadOptionsThemoduleinitializationoptionisload=pnamewherepnameisthenameofaprocedureinthedeclaredexportsorlocalsofthemodule.Ifthisoptionispresent,thenthepro-cedureiscalledwhenthemoduleisreadfromtheMaplerepositoryinwhichitisfound.Theunload=pnameoptionspecißesthenameofalocalorexportedprocedureofthemodulethatiscalledwhenthemoduleisdestroyed.Amoduleisdestroyedeitherwhenitisnolongeraccessibleandisgarbagecollected,orwhenMapleexits.Thereisasituationthatcanarisewhereinamoduleisnolongeraccessible,andhencesubjecttogarbagecollectionbeforetheunload=procedureisexecuted,butbecomesaccessibleagainduringtheexecution 58¯Chapter2:ProgrammingwithModulesofthatprocedure.Inthatcase,themoduleisnotgarbagecollected.WheniteventuallyisgarbagecollectedorMapleexits,theunload=procedureisnotexecutedagain.Theload=andunload=proceduresarecalledwithnoarguments.ThepackageOptionModuleswiththeoptionpackagerepresentMaplepackages.Theexportsofamodulecreatedwiththepackageoptionareautomaticallyprotected.TherecordOptionTherecordoptionisusedtoidentifyrecords.RecordsareproducedbytheRecordconstructorandarerepresentedusingmodules.ImplicitScopingRulesThebindingsofnamesthatappearwithinamoduledeßnitionaredeter-minedwhenthemoduledeßnitionissimplißed.Moduledeßnitionsaresubjecttothesameimplicitscopingrulesthatproceduredeßnitionsare.Undernocircumstancesisanameeverimplicitlydeterminedtobeex-portedbyamodule;implicitlyscopednamescanresolveonlytolocalsorglobals.LexicalScopingRulesModuledeßnitions,alongwithproceduredeßnitions,obeystandardlex-icalscopingrules.Modulesmaybenested,inthesensethatamodulemayhaveanyofitsexportsassignedtoamodulewhosedeßnitionoccurswithinthebodyoftheoutermodule.Hereisasimpleexampleofasubmodule.>m:=module()>exports;>s:=module()>exporte;>e:=proc()>print("HELLOWORLD!")>endproc;>endmodule>endmodule:Theglobalnamemisassignedamodulethatexportsthenames.Withinthebodyofm,theexportsisassignedamodulethatexportsthenamee.Assuch,sisasubmoduleofm.TheShapespackage,describedlater,illustratesanontrivialuseofsubmodules.Modulesandprocedurescanbemutuallynestedtoanarbitrarydepth.Therulesforthevisibilityoflocalvariables(includingexportedlocalsof 2.1SyntaxandSemantics¯59modules)andprocedureparametersarethesameastherulesfornestedprocedures.ParameterizedModulesModulesdonottakeexplicitparameters.Youcanwriteagenericmodulethatcouldbespecializedbyprovidingoneormoreparameters.Forexample,hereisamoduleforarithmeticmodulo6.>z6:=module()>exportadd,mul;>add:=(a,b)->a+bmod6;>mul:=(a,b)->a*bmod6;>endmodule:>z6:-add(5,4);3>z6:-mul(2,3);0Youcanwriteagenericmoduleforarithmeticmoduloanypositiveintegern,andthenspecializeitforanyintegerthatyouneed.Thisispossibleasaresultofthestandardlexicalscopingrules.Youmustwriteaconstructorprocedureforthemodulethatacceptsthevalueofnasanargument.Hereisagenericversionofthez6example.>MakeZn:=proc(n::posint)>module()>exportadd,mul;>add:=(a,b)->a+bmodn;>mul:=(a,b)->a*bmodn;>endmodule>endproc:Togenerateamodulethatdoesarithmeticmodulo7,calltheconstructorMakeZnwiththenumber7asitsargument.>z7:=MakeZn(7);z7:=module()exportadd;mul;endmodule>z7:-add(3,4);0 60¯Chapter2:ProgrammingwithModulesModulesandTypesTwoMapletypesareassociatedwithmodules.First,thenamemoduleisatypename.Naturally,anexpressionisoftypemoduleonlyifitisamodule.Whenusedasatypename,thenamemodulemustbeenclosedinnamequotes(`).>type(module()end,'`module`');true>type(LinearAlgebra,'`module`');trueSecondly,atypecalledmoduledefinitionidentißesexpressionsthataremoduledeßnitions.Inthepreviousexample,themoduledeßnition>module()end:wasevaluatedbeforebeingpassedtotype,sotheexpressionthatwastestedwasnotthedeßnition,butthemoduletowhichitevaluates.Youmustuseunevaluationquotes(')todelaytheevaluationofamoduledeßnition.>type('module()end','moduledefinition');trueOtherimportanttypetestssatisßedbymodulesarethetypesatomicandlast_name_eval.>type(module()end,'atomic');trueTheproceduremaphasnoeÞectonmodules;theypassthroughun-changed.>map(print,module()exporta,b,c;end);module()exporta;b;c;endmoduleModulesalsofollowlastnameevaluationrules.Formoreinformationonlastnameevaluationrules,referto?last_name_eval. 2.1SyntaxandSemantics¯61>m:=module()end:>m;m>type(m,'last_name_eval');trueAlthoughtypemoduleisasurfacetype,itactsalsoasastructuredtype.Parameterspassedasargumentstotheunevaluatednamemodulearetakentobethenamesofexports.Forexample,themodule>m:=module()exporta,b;end:hasthestructuredmoduletype`module`(a,b):>type(m,'`module`(a,b)');trueItalsohastypetype`module`(a)>type(m,'`module`(a)');truebecauseanymodulethatexportssymbolsaandbisamodulethatexportsthesymbola.Example:ASymbolicDiÞerentiatorThissectionillustratesthevariousmoduleconceptsthroughasymbolicdiÞerentiatorexample.SinceMapleprovidesabuilt-indiÞerentiatordiff,theexamplesymbolicdiÞerentiatorisnameddifferentiate.Its(ßnal)implementationisinthemoduleDiffImpl(laterinthischapter),whichholdsallthelocalstatefortheprogram.Muchofthecodeforthedif-ferentiatorisdesignedtoimplementeitherastandardrule(suchastherulethatthederivativeofasumisthesumofthederivativesofthesum-mands),orspecialcaserulesformathematicalfunctionssuchassinandexp.TheexamplediÞerentiatorhandlesonlyrealvaluedfunctionsofasinglerealvariable. 62¯Chapter2:ProgrammingwithModulesThefollowingexampleshowsseveralstepsinthedevelopmentofthemodule,fromaverysimpleßrsttrytotheßnal,fullyfunctionalprogram.TheßnalformofthediÞerentiatorisagoodillustrationofaverycommonMapledesignpattern.Thispatternariseswhenyouhaveasingletop-levelroutinethatdispatchesanumberofsubroutinestohandlespecialcasesusingspecialpurposealgorithms.TheFirstAttemptThisinitialexamplepresentsthediÞerentiatorasanordinaryprocedure,notamodule.>differentiate:=proc(expr,var)>locala,b;>>iftype(expr,'constant')then>0>elifexpr=varthen>1>eliftype(expr,'`+`')then>map(procname,args)>eliftype(expr,'`^`')then>a,b:=op(expr);>ifa=varandnothas(b,var)then>b*a^(b-1)>else>'procname(args)'>endif>eliftype(expr,'`*`')then>a,b:=op(1,expr),subsop(1=1,expr);>procname(a,var)*b+a*procname(b,var)>else>'procname(args)'>endif>endproc:Trivialcasesarehandledßrst:Thederivativeofaconstantexpressionisequalto0,andthederivativeofthevariablewithrespecttowhichwearediÞerentiatingisequalto1.Theadditivityofthederivativeoperatorisexpressedbymappingtheprocedureoversums,usingthecommand>map(procname,args);Thisiscommonlyusedtomapaprocedureoveritsßrstargument,passingalongalltheremainingarguments.OnlythesimplecaseofpowersofthediÞerentiationvariableishandledsofar,providedalsothatthepowerisindependentofthediÞerentiationvariable.Theproductruleforderivativesisexpressedbysplittingexpressionsoftypeproductintotwopieces:¯theßrstfactorintheproduct,and¯theproductofalltheremainingfactors. 2.1SyntaxandSemantics¯63Thisisachievedbythedoubleassignmentof>a,b:=op(1,expr),subsop(1=1,expr);sotheinputexpressionexprisexpressedasexpr=a*b.Thestan-dardtechniqueofreturningunevaluatedisusedsothatcomputationcanproceedsymbolicallyonexpressionsthattheprocedureisunabletodif-ferentiate.Thisßrstexampleissimple,butitisalreadyabletohandlepolyno-mialswithnumericcoeácients.>differentiate(2-x+x^2+3*x^9,x);1+2x+27x8However,itfailsonexpressionscontainingcallstostandardmathe-maticalfunctions.>differentiate(sin(x),x);diÞerentiate(sin(x);x)Itisalsounabletodealsuccessfullywithsymboliccoeácients.>differentiate(a*x^2+b*x+c,x);diÞerentiate(a;x)x2+2ax+diÞerentiate(b;x)x+b+diÞerentiate(c;x)AddingMissingFunctionalityToaddthemissingfunctionality,addacaseforexpressionsoftypefunction.>differentiate:=proc(expr,var)>locala,b;>>ifnothas(expr,var)then>0>elifexpr=varthen>1>eliftype(expr,'`+`')then>map(procname,args)>eliftype(expr,'`^`')then>a,b:=op(expr);>ifnothas(b,var)then>b*a^(b-1)*procname(a,var)>else>'procname(args)' 64¯Chapter2:ProgrammingwithModules>endif>eliftype(expr,'`*`')then>a,b:=op(1,expr),subsop(1=1,expr);>procname(a,var)*b+a*procname(b,var)>eliftype(expr,'function')andnops(expr)=1then>#functionsofasinglevariable;chainrule>b:=op(0,expr);#thenameofthefunction>a:=op(1,expr);#theargument>ifb='sin'then>cos(a)*procname(a,var)>elifb='cos'then>-sin(a)*procname(a,var)>elifb='exp'then>exp(a)*procname(a,var)>elifb='ln'then>(1/a)*procname(a,var)>else>'procname(args)'>endif>else>'procname(args)'>endif>endproc:Thisusesthechainruletocomputethederivativesofcallstoknownfunctions.>differentiate(sin(x)+cos(exp(x)),x);cos(x)sin(ex)ex>differentiate(sin(x^2)+cos(x^2),x);2cos(x2)x2sin(x2)x>differentiate(sin(x)^2+cos(x)^3,x);2sin(x)cos(x)3cos(x)2sin(x)Atthesametime,thishasalsoimprovedthehandlingofexpressionsindependentofthevariableofdiÞerentiation.>differentiate(a*x^2+b*x+c,x);2ax+b 2.1SyntaxandSemantics¯65ThisiseÞectedbyusingtheexpressionhas(expr,var)insteadoftheweakertesttype(expr,'constant').Thepowerrulenowhandlesmorethanjustpowersofvar.>differentiate(sin(x)^2,x);2sin(x)cos(x)However,addingnewfunctionstothediÞerentiatoristediousanderrorprone,andthejobofhandlingthechainrulemustberepeatedforeachfunctionrecognizedbyit.IntroducingaFunctionTableManyfunctions(thatyouneedtoadd)andtherulesusedfortheirdiÞerentiationcanbestoredinatableasfollows:>differentiate:=proc(expr,var)>locala,b,functab;>>functab:=table();>functab['sin']:='cos';>functab['cos']:=x->-sin(x);>functab['exp']:=exp;>functab['ln']:=x->1/x;>>ifnothas(expr,var)then>0>elifexpr=varthen>1>eliftype(expr,'`+`')then>map(procname,args)>eliftype(expr,'`^`')then>a,b:=op(expr);>ifa=varandnothas(b,var)then>b*a^(b-1)*procname(a,var)>else>'procname(args)'>endif>eliftype(expr,'`*`')then>a,b:=op(1,expr),subsop(1=1,expr);>procname(a,var)*b+a*procname(b,var)>eliftype(expr,'function')andnops(expr)=1then>#functionsofasinglevariable;chainrule>b:=op(0,expr);#thenameofthefunction>a:=op(1,expr);#theargument>ifassigned(functab[b])then>#Thisisa``known''function>functab[b](a)*procname(a,var)>else>#Thisfunctionisnotknown;returnunevaluated>'procname(args)' 66¯Chapter2:ProgrammingwithModules>endif>else>'procname(args)'>endif>endproc:Thisnotonlysimplißesthecodeusedforthefunctioncase,butalsomakesitveryeasytoaddnewfunctions.DrawbacksUnfortunately,thisimplementationhasseriousdrawbacks.¯Itisnotextensible.Theknownfunctionsarehardcodedaspartoftheproceduredeßnitionfordifferentiate.Newfunctionscannotbeaddedwithouteditingthissourcecode.¯Asecondproblemrelatestoperformance.Acompleteimplementationwouldrequireatableofdozensorhundredsoffunctions.Thatlargeta-blewouldneedtobecreatedandinitializedeachtimedifferentiateisinvoked.EncapsulationandExtensibilityOnewaytoßxbothproblemsistomakethetableoffunctionsaglobalvariable.However,usingglobalvari-ablescanbedangerous,becausetheypollutetheusernamespaceandaresubjecttounwantedinspectionandtampering.SolutionAbettersolutionistoputthedifferentiateprocedure,alongwithitstableoffunctions,intoamodule.Thetableisthenini-tializedonlyonceÛwhenthemoduleiscreatedÛandcanbesavedtoaMaplerepositorywiththerestofthemodulebyusingasavelibcall.Bymakingthetablealocalvariableofthemodule,youpreventusersfrommodifyingthetableorotherwiseinspectingitinunwantedways.ThisdoesnotpreventyoufrommakingthediÞerentiatoruser-extensible,however.YoucanaddanaccessprocedureaddFuncthatallowsuserstoaddrulesfordiÞerentiatingnewfunctions.Forexample,youcanusethecall>addFunc('cos',x->-sin(x));toaddthederivativeofthesinfunction.TheexportaddFuncoftheDiffImplmoduleisaprocedurethatrequirestwoarguments.TheßrstisthenameofafunctionwhosederivativeistobemadeknowntothediÞerentiator.ThesecondisaMapleprocedureofoneargumentthatexpressesthederivativeofthefunctionbeingadded. 2.1SyntaxandSemantics¯67Withthisstrategyinmind,youcancreateamoduleDiffImpl,withprincipalexportdifferentiate.Atthesametime,youcanalsomakethebasicdiÞerentiationrulesextensible.HereisthecompletesourcecodeforthediÞerentiatorwiththeseim-provements.>DiffImpl:=module()>description"asymbolicdifferentiator";>localfunctab,ruletab,diffPower;>exportdifferentiate,addFunc,addRule,rule;>>addFunc:=proc(fname::symbol,impl)>functab[fname]:=impl>endproc;>>addRule:=proc(T,impl)>iftype(T,'{set,list}')then>map(procname,args)>eliftype(T,'And(name,type)')then>ruletab[T]:=impl>else>error"expectingatypename,butgot%1",T>endif>endproc;>>rule:=proc(T)>iftype(T,'And(name,type)')then>ifassigned(ruletab[T])then>eval(ruletab[T],1)>else>error"noruleforexpressionsoftype%1",T>endif>else>error"expectingatypesymbol,butgot%1",T>endif>endproc;>>differentiate:=proc(expr,var)>locala,b,e;>ifnothas(expr,var)then>0>elifexpr=varthen>1>eliftype(expr,'function')andnops(expr)=1then>e:=op(0,expr);>a:=op(expr);>ifassigned(functab[e])then>functab[e](a)*procname(a,var)>else>'procname(args)'>endif>else>b:=whattype(expr); 68¯Chapter2:ProgrammingwithModules>ifassigned(ruletab[b])then>ruletab[b](expr,var)>else>'procname(args)'>endif>endif>endproc;>>addRule('{list,set,tabular}',>()->map(differentiate,args));>addRule('`+`',>()->map(differentiate,args));>addRule('`*`',>(expr,var)->>op(1,expr)*differentiate(subsop(1=1,expr),var)>+differentiate(op(1,expr),var)*subsop(1=1,expr));>diffPower:=proc(expr,var)>localb,e;>Assert(type(expr,'`^`'));>b,e:=op(expr);>ifhas(e,var)then>expr*(differentiate(e,var)*ln(b)>+e*differentiate(b,var)/b)>else#simplerformula>e*b^(e-1)*differentiate(b,var)>endif;>endproc;>addRule('`^`',eval(diffPower));>>addFunc('sin',cos);>addFunc('cos',x->-sin(x));>addFunc('exp',exp);>addFunc('ln',x->1/x);>#...etc.>>endmodule:>differentiate:=DiffImpl:-differentiate:Togivethesetofrulesfornonfunctionalexpressionssimilarextensibility,youcanstorethoserulesinatable.Thetableisindexedbytheprimary(orbasic)typenamefortheexpressiontype,asgivenbytheMapleprocedurewhattype.>whattype(a+2);+>whattype(a/b);£ 2.1SyntaxandSemantics¯69>whattype(a^sqrt(2));^>whattype([f(x),g(x)]);listAruleisexpressedbyaprocedureoftwoarguments,exprandvar,inwhichexpristheexpressiontobediÞerentiated,andvaristhevariableofdiÞerentiation.Forinstance,tomakethediÞerentiatorhandleitemssuchassetsandlistsbydiÞerentiatingtheirindividualcomponents,addtherule>addRule('{list,set,tabular}',()->map(differentiate,>args));TheßrstversionofthediÞerentiatordealtwithsumsbymappingitselfoverthesumexpression.Inthenewscheme,thisisexpressedbythestatement>addRule('`+`',()->map(differentiate,args));inthemodulebody.Theadvantageofusingthisschemeisthat,notonlycantheauthorofthediÞerentiatorextendthesystem,butsocanusersofthesystem.HavinginstantiatedthemoduleDiffImpl,anyusercanaddrulesornewfunctions,simplybyissuingappropriatecallstoaddRuleandaddFunc.ThediÞerentiatorcannothandletheproceduretan.>differentiate(tan(x)/exp(x),x);tan(x)diÞerentiate(tan(x);x)+exexYoumustaddittothedatabaseofknownfunctions.>DiffImpl:-addFunc('tan',x->1+tan(x)^2);x!1+tan(x)2>differentiate(tan(x)/exp(x),x); 70¯Chapter2:ProgrammingwithModulestan(x)1+tan(x)2+exexSimilarly,thereisnotyetanyruleforhandlingequationsandotherrelations.>differentiate(y(x)=sin(x^2)-cos(x^3),x);diÞerentiate(y(x)=sin(x2)cos(x3);x)>DiffImpl:-addRule('{`=`,`<`,`<=`}',>()->map(differentiate,args));f()!map(diÞerentiate;args)g>differentiate(y(x)=sin(x^2)-cos(x^3),x);diÞerentiate(y(x);x)=2cos(x2)x+3sin(x3)x2TheExtensionMechanismisModuleAwareDonotconfusetheex-tensionmechanismpreviouslyproposedforthediÞerentiatorwiththeextensionmechanismusedbythebuilt-inMaplecommanddiff.Thediffcommandusesatraditionalstringconcatenationmechanismforaddingknowledgeofthederivativesoffunctions,andallitsrulesarebuilt-in,sotheycannotbeextended.Forinstance,toaddanewfunc-tionFtotheMaplebuilt-indiffcommand,youcandeßneaprocedure`diff/F`thatcomputesthederivativeofF.Bycontrast,theextensionmechanismusedinthedifferentiateexampleismoduleaware.Toaddknowledgeofthederivativeofsometop-levelfunctionF,youcanissueacommand,suchas>DiffImpl:-addFunc('F',x->sin(x)+cos(x));x!sin(x)+cos(x)ThederivativeofF(x)issin(x)+cos(x).)Deßneamodulewithsomespecialfunctions,oneofwhichisalsocalledF. 2.1SyntaxandSemantics¯71>SpecFuncs:=module()>exportF;#etc.>#definitionofF()andothers>endmodule:YoucannowaddthisnewFtotheknownfunctions.>DiffImpl:-addFunc(SpecFuncs:-F,x->exp(2*x));x!e(2x)>differentiate(F(x),x);sin(x)+cos(x)>useSpecFuncsin>differentiate(F(x),x);>enduse;e(2x)Withthetraditionalmechanism,thisdoesnotwork.>`diff/`||F:=x->sin(x)+cos(x);diÞ=F:=x!sin(x)+cos(x)>diff(F(x),x);sin(x)+cos(x)>useSpecFuncsin>`diff/`||F:=x->exp(2*x);>diff(F(x),x);>enduse;diÞ=F:=x!e(2x)e(2x)ThedeßnitionfortheglobalFhasbeenlost.>diff(F(2*x),x);e(4x) 72¯Chapter2:ProgrammingwithModules(YoucanuseadiÞerentargumenttodifftoavoidrecallingthean-swerfromitsremembertable.)Thetraditionalmechanismfailsbecauseitreliesontheexternalrepresentationofnames,andnotupontheirbindings,soeachattempttodeßneanextensiontodiffinfactaddsadeßnitionforthederivativeofallfunctionswhosenamesarespelled"F".Note:Acommentedversionofthedifferentiatemoduleisavailableinthesamples/AdvPGdirectoryoftheMapleinstallation.Theimplemen-tationshowninthetexthasbeensomewhatsimplißed.2.2RecordsThesimplestwaytousemodulesisasPascal-stylerecords(orstructures,asinCandC++).Arecordisadatastructurethathassomenumberofnamedslotsorßelds.InMaple,theseslotscanbeassignedarbitraryvalues.AlthoughtheunderlyingdatastructureofaMaplerecordiscur-rentlyamodule,recordsandmodulesrepresentdistinctabstractions.Arecordissimplyanaggregatedatastructureinwhichthemembershaveßxednames.Modulesprovideadditionalfacilitiessuchascomputationatinitializationandaccesscontrol.InstantiatingRecordsTocreatearecord,usetheRecordconstructor.Inthesimplestform,ittakestheslotnamesasarguments.>rec:=Record('a','b','c');rec:=module()exporta;b;c;optionrecord;endmoduleThenamerecisnowassignedarecordwithslotsnameda,b,andc.Thesearetheslotnamesfortherecordrec.Youcanaccessandassigntheseslotsbyusingtheexpressionsrec:-a,rec:-b,andrec:-c.>rec:-a:=2;a:=2>rec:-a;2 2.2Records¯73Ifnotassigned,therecordslotevaluatestothelocalinstanceoftheslotname.>rec:-b;b>evalb(%=b);falseThisisusefulbecausetheentirerecordcanbepassedasanaggregatedatastructure.Therecordconstructoracceptsinitializersforrecordslots.Thatis,youcanspecifyaninitialvalueforanyslotinaneworinanunassignedrecordbypassinganequationwiththeslotnameontheleftsideandtheinitialvalueontheright.>r:=Record('a'=2,'b'=sqrt(3));r:=module()exporta;b;optionrecord;endmodule>r:-b;p3Inaddition,youcanattachtypeassertionstorecordslots.Tointro-duceatypeassertion,usea`::`structurewiththeslotnamespecißedastheßrstoperand.Typeassertionscanbeusedincombinationwithinitializers.Anincompatibleinitializervaluetriggersanassertionfailurewhentheassertlevelkerneloptionissetto2.Formoreinformation,referto?kernelopts.>kernelopts('assertlevel'=2):>Record(a::integer=2.3,b=2);Error,(inassign/internal)assertionfailedinassignment,expectedinteger,got2.3>r:=Record('a'::integer=2,'b'::numeric); 74¯Chapter2:ProgrammingwithModulesr:=module()exporta::integer;b::numeric;optionrecord;endmodule>r:-b:="astring";Error,assertionfailedinassignment,expectednumeric,gotastringIftheinitializerforarecordslotisaprocedure,youcanusethereservednameselftorefertotherecordyouareconstructing.Thisallowsrecordstobeself-referential.Forexample,youcanwriteacomplexnumberconstructorasfollows.>MyComplex:=(r,i)->>Record('re'=r,'im'=i,'abs'=(()->sqrt(>self:-re^2+self:-im^2))):>c:=MyComplex(2,3):>c:-re,c:-im,c:-abs();p2;3;13Combinedwithprototype-basedinheritance,describedonpage76,thisfacilitymakestheRecordconstructorapowerfultoolforobject-orientedprogramming.RecordTypesExpressionscreatedwiththeRecordconstructorareoftyperecord.>type(rec,'record');trueThisisastructuredtypethatworksthesamewayasthe`module`type,butrecognizesrecordsspecißcally.>r:=Record(a=2,b="foo"):>type(r,'record(a::integer,b::string)');true 2.2Records¯75Note:Inarecordtype,theslottypesareusedtotestagainstthevaluesassignedtotheslots(ifany),andarenotrelatedtotypeassertionsontheslotnames(ifany).>r:=Record(a::integer=2,b::{symbol,string}="foo"):>type(r,'record(a::numeric,b::string)');trueUsingRecordstoRepresentQuaternionsRecordsareusefulforim-plementingsimpleaggregatedatastructuresforwhichnamedaccesstoslotsiswanted.Forexample,fourrealnumberscanbecombinedtoformaquaternion,andyoucanrepresentthisusingarecordstructure,asfol-lows.>MakeQuaternion:=proc(a,b,c,d)>Record('re'=a,'i'=b,'j'=c,'k'=d)>endproc:>z:=MakeQuaternion(2,3,2,sqrt(5));z:=module()exportre;i;j;k;optionrecord;endmodulepInthisexample,zrepresentsthequaternion2+3i+2j+5k(wherei,j,andkarethenonrealquaternionbasisunits).Thequaternionrecordscannowbemanipulatedassinglequantities.Thefollowingprocedureac-ceptsaquaternionrecordasitssoleargumentandcomputestheEuclideanlengthofthequaternionthattherecordrepresents.>qnorm:=proc(q)>usere=q:-re,i=q:-i,j=q:-j,k=q:-kin>sqrt(re*re+i*i+j*j+k*k)>enduse>endproc:>qnorm(z);p22AMapletypeforquaternionscanbeintroducedasastructuredrecordtype. 76¯Chapter2:ProgrammingwithModules>TypeTools:-AddType('quaternion','record(re,i,j,k)');>type(z,'quaternion');trueObjectInheritanceTheRecordconstructorsupportsasimpleformofprototype-basedinheritance.Anobjectsystembasedonprototypesdoesnotinvolveclasses;instead,itusesasimpler,moredirectformofobject-basedinheritance.Newobjectsarecreatedfromexistingobjects(calledprototypes)bycloning,thatis,copyingandaugmentingthedataandbehavioroftheprototype.TheRecordconstructorsupportsprototype-basedinheritancebyac-ceptinganindexargument,whichistheprototypeforthenewobjectrecord.>p:=Record(a=2,b=3);#createaprototypep:=module()exporta;b;optionrecord;endmodule>p:-a,p:-b;2;3>r:=Record[p](c=4);r:=module()exporta;b;c;optionrecord;endmodule>r:-a,r:-b,r:-c;2;3;4Inthisexample,therecordpistheprototype,andthesecondrecordrinheritstheslotsaandb,andtheirvalues,fromtheprototypep.Italsoaugmentstheslotsobtainedfrompwithanewslotc.Theprototypepisnotchanged.>r:-a:=9;a:=9 2.2Records¯77>p:-a;2Behavior,aswellasdata,canbecopiedfromaprototype.Tocopybe-havior,useaconstructorprocedureforboththeprototypeanditsclones.>BaseComplex:=proc(r,i)>Record('re'=r,'im'=i)>endproc:>NewComplex:=proc(r,i)>Record[BaseComplex(r,i)]('abs'=>(()->sqrt(self:-re^2+self:-im^2)))>endproc:>c:=NewComplex(2,3):>c:-re,c:-im,c:-abs();p2;3;13Anobjectcreatedfromaprototypecanserveasaprototypeforan-otherobject.>NewerComplex:=proc(r,i)>Record[NewComplex(r,i)]('arg'=>(()->arctan(self:-im,self:-re)))>endproc:>c2:=NewerComplex(2,3):>c2:-re,c2:-im,c2:-abs(),c2:-arg();p32;3;13;arctan()2Note:Prototypesaresupertypesoftheirclones.>subtype('record(re,im,abs)','record(re,im)');trueForexample,NewComplexcreatesobjectsofatypethatisasubtypeoftheobjectscreatedbyBaseComplex. 78¯Chapter2:ProgrammingwithModules2.3PackagesModulesareidealforwritingMaplepackages.Theyprovidefacilitiesforlargesoftwareprojectsthatarebetterthantableandprocedurebasedmethods.WhatIsaPackageApackageisacollectionofproceduresandotherdata,thatcanbetreatedasawhole.Packagestypicallygatheranumberofproceduresthatenableyoutoperformcomputationsinsomewell-deßnedproblemdomain.Pack-agesmaycontaindataotherthanprocedures,andmayevencontainotherpackages(subpackages).PackagesintheStandardLibraryAnumberofpackagesareshippedwiththestandardMaplelibrary.Forexample,thegroup,numtheory,codegen,andLinearAlgebrapackagesareallprovidedwithMaple,alongwithseveraldozenothers.Thegrouppackageprovidesproceduresthatallowyoutocomputewithgroupsthathaveaßniterepresentationintermsofpermutations,orofgeneratorsanddeßningrelations.TheLinearAlgebrapackagehasalargenumberofproceduresavailableforcomputationallinearalgebra.Table-BasedPackagesManypackagesareimplementedastables.Theessentialideaunderlyingthisimplementationschemeisthatthenameofapackageroutineisusedastheindexintoatableofprocedures.Thetableitselfistheconcreterepresentationofthepackage.UseModulesforNewPackagesModulesarethenewimplementa-tionvehicleforpackages.Amodulerepresentsapackagebyitsexportednames.TheexportednamescanbeassignedarbitraryMapleexpressions,typicallyprocedures,andthesenamesformthepackage.PackageExportsSomeofthedatainapackageisnormallymadeacces-sibletotheuserasanexportofthepackage.Forpackagesimplementedasmodules,thepackageexportsarethesameastheexportsoftheunder-lyingmodule.Forpackagesimplementedastables,thepackageexportsarethenamesusedtoindextheunderlyingtable.Accessingtheexportsofapackageisafundamentaloperationthatissupportedbyallpackages.IfPisaMaplepackage,andeisoneamongitsexports,youcanaccessebyusingthefullyqualißedreferenceP[e].IfPisamodule,thenyoucanalsousethesyntaxP:-e.Thesemethodsofaccessingtheexportsofamodulearenormallyusedwhenprogrammingwithapackage. 2.3Packages¯79Notethat:-isaleft-associativeoperator.IfSisasubmoduleofamoduleP,andthenameeisexportedbyS,thenthenotationP:-S:-eisparsedas(P:-S):-e,andsoitreferstotheinstanceofelocaltoS.Thisfactisimportanttoreferencemembersofsubpackages.Forexample,>m:=Matrix(2,2,[[1-x,2-x],[3-x,4-x]],>'datatype'='polynom(integer)');´µ1x2xm:=3x4x>LinearAlgebra:-LA_Main:-Norm(m,1,conjugate=false);max(jx1j+jx3j;jx2j+jx4j)callstheprocedureNorminthesubpackageLA_MainoftheLinearAlgebrapackage.Youcanuseindexednotationforthis.>LinearAlgebra[LA_Main][Norm](m,1,conjugate=false);max(jx1j+jx3j;jx2j+jx4j)UsingPackagesInteractivelyForinteractiveuse,itisinconvenienttoenterfully-qualißedreferencestoalltheexportsofapackage.Toeasethisburden,theMapleprocedurewithisprovidedfortheinteractivemanagementofpackagenamespaces.Usingwith,youcangloballyimposetheexportednamesofapackage.Thisallowsyoutoaccessthepackageexports,withouttypingthepackagepreßx,bymakingthenamesoftheexportsvisibleatthetop-leveloftheMaplesession.Forexample,tousethenumtheorypackage,youcanissuethecommand>with(numtheory);Warning,theprotectednameorderhasbeenredefinedandunprotected 80¯Chapter2:ProgrammingwithModules[GIgcd;bigomega;cfrac;cfracpol;cyclotomic;divisors;factorEQ;factorset;fermat;imagunit;index;integral_basis;invcfrac;invphi;issqrfree;jacobi;kronecker;µ;legendre;mcombine;mersenne;migcdex;minkowski;mipolys;mlog;mobius;mroot;msqrt;nearestp;nthconver;nthdenom;nthnumer;nthpow;order;pdexpand;¾;¹;pprimroot;primroot;quadres;rootsunity;safeprime;»;sq2factor;sum2sqr;¼;thue]TheeÞectofthiscommandistomakethenamesexportedbythenumtheorypackage(alistofwhichisreturnedbythecalltowith)avail-abletemporarilyastop-levelMaplecommands.>cfrac((1+x)^k,x,5,'subdiagonal','simregular');1kx11(k+1)x1+21(k1)x161(k+2)x1+61+:::WritingMaplePackagesbyUsingModulesThissectiondescribeshowtowriteMaplepackagesbyusingmodules.Thefollowingsubsectionspresentseveralexamplesthatillustratehowtodothis.TheLinkedListPackageTheßrstexamplepackageisasmallpackagecalledLinkedList.Thisexampleillustratesthebasicstructureofapackageimplementedbyusingmodules.BackgroundLinkedlistsareabasicdatastructureusedinprogramsformanydiÞerentpurposes.Therearemanykindsoflinkedlists,withvariationsonthebasicideaintendedtoaddressperformanceandfunc-tionalityissues.Theexamplepackageshowninthissubsectionprovidesafewoperationsonthesimplestpossibleformoflinkedlists.Thelinksinalinkedlistareformedfromaverysimpledatastructuredcalledapair.Apairisessentiallyacontainerwithspaceforexactlytwoelements.Pairscanbemodeledbyßxedlengthrecordswithtwoslots. 2.3Packages¯81Whenusedtoimplementlinkedlists,theßrstslotholdsthedataforthelistentry,andthesecondslotstoresapointertothenextpairinthelist.TheLinkedListpackageimplementsanabstractdatadeßnitionforthepairdatastructure,andaddssomehigherleveloperationsonpairstoeÞectthelistabstraction.AlinkedlistiseÞectivelyrepresentedbyitsßrstpair.Thepairabstractdatastructureisverysimple.Itconsistsofacon-structorpair,andtwoaccessorscalledheadandtailthatsatisfythealgebraicspecißcationp=pair(head(p);tail(p))foreachpairp.Inaddition,thereisadistinguishedpairnil,satisfyingthisalgebraicrelation,thatisunequaltoanyotherpair,andsatisßeshead(nil)=nil;tail(nil)=nil:NotethatlinkedlistsarequitediÞerentfromtheMaplebuilt-inliststructures,whicharereallyimmutablearrays.Linkedlistsarebestsuitedforapplicationsinwhichyouwanttoincrementallybuildupthelistfromitsmembers.1PackageImplementationTheLinkedListpackageisimplementedasamodulecontainingtheprimitiveoperationsonpairs,andhigherleveloperationsthatimplementthelistabstraction.>macro(_PAIR=``):#forniceprinting>LinkedList:=module()>description"routinesforsimplelinkedlists";>export>nil,>nullp,>pair,>head,>tail,>list,>length,>member,>reverse,>append,>map;>local>setup,>cleanup,1Lispprogrammerswillrecognizethepair,head,andtailoperationsasthemoretraditionaloperationsknownasÕconsÔ,ÕcarÔandÕcdrÔ. 82¯Chapter2:ProgrammingwithModules>map1,>reverse1,>_PAIR;>option>package,>load=setup,>unload=cleanup;>>setup:=proc()>global`type/Pair`,`type/LinkedList`;>`type/Pair`:='{_PAIR(anything,anything),>identical(nil)}';>`type/LinkedList`:=proc(expr)>ifexpr=nilthen>true>eliftype(expr,Pair)then>type(tail(expr),'LinkedList')>else>false>endif>endproc;>userinfo(1,'LinkedList',>"newtypes`Pair'and`LinkedList'defined");>NULL>endproc;>>cleanup:=proc()>global`type/Pair`,`type/LinkedList`;>userinfo(1,'LinkedList',>"cleaningupglobaltypes");>`type/Pair`:=evaln(`type/Pair`);>`type/LinkedList`:=evaln(`type/LinkedList`);>NULL>endproc;>>pair:=(a,b)>->setattribute('_PAIR'(a,b),'inert');>head:=(c::Pair)>->`if`(c=nil,nil,op(1,c));>tail:=(c::Pair)>->`if`(c=nil,nil,op(2,c));>nullp:=(pair)>->evalb(pair=nil);>>list:=proc()>locala,L;>L:=nil;>forainargsdo>L:=pair(a,L)>enddo>endproc;>>length:=proc(lst)>ifnullp(lst)then 2.3Packages¯83>0>else>1+length(tail(lst))>endif>endproc;>>member:=proc(item,lst)>ifnullp(lst)then>false>elifitem=head(lst)then>true>else>procname(item,tail(lst))>endif>endproc;>>map:=proc(p,lst)>ifnullp(lst)then>nil>else>pair(p(head(lst)),>procname(p,tail(lst)))>endif>endproc;>>append:=proc(lst1,lst2)>ifnullp(lst1)then>lst2>else>pair(head(lst1),>procname(tail(lst1),lst2))>endif>endproc;>>reverse1:=proc(sofar,todo)>ifnullp(todo)then>sofar>else>procname(pair(head(todo),sofar),>tail(todo))>endif>endproc;>>reverse:=lst->reverse1(nil,lst);>>setup();>>endmodule:Normally,apackagedeßnitionlikethiswouldbeenteredintoaMaplesourceßleusingatexteditor,orinaworksheetusingtheMaplegraphicaluserinterface.Ineithercase,thedeßnitionwouldthenbefollowedbyacalltothesavelibprocedureusingthenameofthemoduleasitssole 84¯Chapter2:ProgrammingwithModulesargument:>savelib('LinkedList');Evaluatingthesavelibcallsavesthemoduletotheßrstrepositoryfoundintheglobalvariablelibname,ortherepositorynamedwiththeglobalvariablesavelibname,ifitisdeßned.(Atleastoneofthesemustbedeßned.)ImportantAlwaysensurethatthestandardMaplelibraryiswrite-protectedtoavoidsavingexpressionsinit.Ifyouaccidentallysavesome-thingtothestandardMaplelibrary,youmayneedtorestoretheoriginalfromthemediaonwhichyouobtainedtheMaplesoftware.Thepackageexportsarelistedastheexportsofthemodule.Afewlocalvariablesareusedtoimplementthepackage.Thelocalproceduresmap1andreverse1arepartofthepackageimplementationthatisnotavailabletousersofthepackage.Theyarevisibleonlywithinthemoduledeßnition.Thisallowsthepackageauthortomakeimprovementstothepackagewithoutdisturbinganycodethatusesit.Ifthelocalproceduresreverse1andmap1wereexported(thus,availabletousers),itwouldbediácultfortheauthortoreplacetheseroutineswithoutbreakingexistingcodethatreliesuponthem.Thepackageincludestwospecial(local)procedures,setupandcleanup.Theseareexecuted,respectively,whenthemoduleisßrstreadfromarepository,andwhenthepackageiseithergarbagecollectedorwhenMapleisabouttoexit.UsingthePackageThepackageexportscanalwaysbeaccessedbyusingthelongformoftheirnames.>LinkedList:-pair(a,b);(a;b)Forconsistencywiththeoldertable-basedpackageimplementations,anindexednotationcanalsobeused.>LinkedList['pair'](a,b);(a;b) 2.3Packages¯85Thisformrequiresthattheindex(inthiscase,thesymbolpair)beprotectedfromevaluation,andthenotationdoesnotextendtopackageswithnestedsubpackages.Toaccessthepackageexportsinteractively,usethewithcommand.>with(LinkedList);Warning,theprotectednameslength,mapandmemberhavebeenredefinedandunprotected[append;head;length;list;map;member;nil;nullp;pair;reverse;tail]Notethat,sincesomeofthepackageexportsshadowglobalprocedureswiththesamename,thewithcommandissueswarnings.Thesewarningsarenormal.TheyremindyouthatthesenamesnowrefertoexpressionsdiÞerentfromtheexpressionstowhichtheyreferredpreviously.OncetheexportsofthepackageLinkedListhavebeenbound,youcancallthemasyouwouldglobalMapleroutineswiththosenames.Notethatyoucanstillaccesstheglobalversionofmember,forexample,byusingthesyntax:-member.>useLinkedListin>member(a,%%);>:-member(a,[a,b,c,d])>enduse;truetrueThisisoneoftheprincipaladvantagesofusingmodulesandbinding,ratherthanassignment,toimplementpackages.Listsareeitherbuiltincrementallyusingthepairexportofthepack-age,orbycallingthelistexport.>L:=nil:>forifrom1to10do>L:=pair(i,L)>enddo; 86¯Chapter2:ProgrammingwithModulesL:=(1;nil)L:=(2;(1;nil))L:=(3;(2;(1;nil)))L:=(4;(3;(2;(1;nil))))L:=(5;(4;(3;(2;(1;nil)))))L:=(6;(5;(4;(3;(2;(1;nil))))))L:=(7;(6;(5;(4;(3;(2;(1;nil)))))))L:=(8;(7;(6;(5;(4;(3;(2;(1;nil))))))))L:=(9;(8;(7;(6;(5;(4;(3;(2;(1;nil)))))))))L:=(10;(9;(8;(7;(6;(5;(4;(3;(2;(1;nil))))))))))>length(L);10>member(3,L);true>member(100,L);false>reverse(L);(1;(2;(3;(4;(5;(6;(7;(8;(9;(10;nil))))))))))>map(x->x^2,L);(100;(81;(64;(49;(36;(25;(16;(9;(4;(1;nil))))))))))>member(100,%);true 2.3Packages¯87>L2:=list(a,b,c,d);L2:=(d;(c;(b;(a;nil))))>map(sin,L2);(sin(d);(sin(c);(sin(b);(sin(a);nil))))>eval(L2,{a=1,b=2,c=3,d=4});(4;(3;(2;(1;nil))))>map(evalf[10],%);(4:;(3:;(2:;(1:;nil))))CodeCoverageProßlingPackageThefollowingexampleisapackagecalledcoverage.Itinstrumentsproce-duresandmodulesforcoverageproßling,thatis,turnsonstatement-leveltracing.Itservesasanexampleofasmallpackage,andillustrateswaysinwhichmodulescanbemanipulated.2DesignYoucanwriteteststhatexerciseeachpartoftheprogramtoensurethattheprogram:¯Workscorrectly¯Continuestoworkwhenit,orotherprogramsonwhichitdepends,changeovertime.Itisimportanttobeabletodeterminewhethereachstatementinaprocedureisexecutedbysometestcase.ThetraceprocoptionoftheMaplecommanddebugoptsprovidesthatcapability.Ittakesthenamepofaprocedure,usingthesyntax2TheMapleCodeToolspackageprovidestoolsforproßlingcodeandtestingcodecoverage.Formoreinformation,referto?CodeTools. 88¯Chapter2:ProgrammingwithModulesdebugopts('traceproc'=p);andinstrumentstheprocedureassignedtopforcoverageproßling.Hereisanexample.>p:=proc(x)>ifx<0then>2*x>else>1+2*x>endif>endproc:>debugopts('traceproc'=p):Oncetheprocedurehasbeeninstrumented,eachtimeitisexecuted,proßlinginformationatthestatementlevelisstored.Toviewtheproßlinginformation,usetheprocedureshowstat.>p(2);5>showstat(p);p:=proc(x)|CallsSecondsWords|PROC|10.00012|1|10.00012|ifx<0then2|00.0000|2*xelse3|10.0000|1+2*xendifendprocThedisplayshowsthatonlyonebranchoftheifstatementthatformsthebodyofpwastakensofar.Thisisbecauseonlyanon-negativeargu-menthasbeensuppliedasanargumenttop.Togetcompletecoverage,anegativeargumentmustalsobesupplied.>p(-1);2>showstat(p); 2.3Packages¯89p:=proc(x)|CallsSecondsWords|PROC|20.00024|1|20.00024|ifx<0then2|10.0000|2*xelse3|10.0000|1+2*xendifendprocThedisplayshowsthateachstatementinthebodyofphasbeenreached.Todisplaytheproßlinginformation,usethedebugoptscommandwiththetraceproctable=procedure_nameequationargument.>debugopts(traceproctable=p);2320246202476741005100Thepackageillustratedinthissectionhelpsextendthisfunctionalitytomodules,andactsasaninterfacetothedebugoptswiththetraceprocoption.Thecoveragepackagehastwoexports:profileandcovered.Twoprivateprocedures,rprofileandtraced,areusedassubroutines.Theyarestoredinlocalvariablesoftheunderlyingmoduleofthepackage.ThePackageSourceHereisthesourcecodeforthepackage.>coverage:=module()>description"apackageofutilitiesfor">"codecoverageprofiling";>optionpackage;>exportprofile,covered;>localrprofile,traced,userprocs;>>#Instrumentaprocedureormodule>#forcoverageprofiling.Returnthe>#numberofproceduresinstrumented.>profile:=proc()>localarg;>add(rprofile(arg),arg=[args])>endproc; 90¯Chapter2:ProgrammingwithModules>>rprofile:=proc(s::name)>locale;>iftype(s,'procedure')then>debugopts('traceproc'=s);>1>eliftype(s,'`module`')then>add(procname(e),>e=select(type,>[exports(s,'instance')],>'{`module`,procedure}'))>else>error"onlyproceduresandmodulescanbeprofiled">endif>endproc;>>#Subroutinetorecognizenon-builtinprocedures>userprocs:=proc(s)>type('s',procedure)andnot(type('s',builtin))>endproc;>>#Subroutinetorecognizeprofiledprocedures>traced:=proc(s)>debugopts('istraceproced'='s')>endproc;>>#Determinewhichprocedureshave>#coverageinformation.>covered:=proc()>localS;>S:=[anames()];>S:=select(userprocs,S);>S:=select(traced,S);>ifnargs>0andargs[1]='nonzero'then>S:=select(s->evalb(s[1,1]<>0),S)>elifnargs>0then>error"optionalargumentisthenamenonzero">endif;>map(parse,map(convert,S,'string'))>endproc;>endmodule:HowthePackageWorksTheexportprofileisaninterfacetothepackage'sprincipalfacility:instrumentingproceduresandmodulesforcoverageproßling.Itreturnsthenumberofproceduresinstrumented,andcallstheprivatesubroutinerprofiletodomostofthework.1.Theprocedurerprofileacceptsanamesasanargument.Ifsisthenameofaprocedure,rprofilesimplycallsdebugoptstoinstrumenttheprocedureassignedtothatname.Otherwise,ifsisthenameofamodule,rprofileselectsanyexportsofthemodulethatare 2.3Packages¯91proceduresormodulesandcallsitselfrecursivelytoinstrumentthem.Iftheparametersisassignedavalueofanyothertype,thenanexceptionisraised.2.Theexpression[exports(s,'instance')]evaluatestoalistofalltheexportedvariablesofthemodulethatareassignedtos.Itisimportanttopasstheinstanceoptiontoexports,becausewhenthosenamesarepassedtorprofileinarecursivecall,rprofilemusttestthetypeoftheirassignedvalues.Thislistcontainsallthemoduleexports,sothosethatareoftypeprocedure,oroftypemodule,areselectedbyusingacalltoselect.TherecursioniseÞectedinthecalltoadd,whichsumsthereturnvaluesofalltherecursivecallstorprofile.3.Theexportedprocedurecoveredisusedtodeterminewhichproce-dureshavebeeninstrumentedandcalled,withproßlinginformationstored.Onepossibledesignwouldstorethisinformationinaprivatetableinthecoveragepackage.Withthisdesign,coveredcouldsim-plyquerythatinternaltableforthenamesoftheproceduresthathavebeeninstrumentedandthathaveproßlinginformationstored.However,ausermayhaveinstrumentedtheproceduremanuallybycallingdebugoptsdirectly,orhistoricalproßlingdatamayhavebeenreadfromaMaplerepository.Therefore,adesignthatqueriesthesystemdirectly,withoutregardtohowaprocedurewasinitiallyin-strumented,isbestused.TheprocedurecoveredqueriesMapleforallthenamescurrentlyas-signedvaluesusingtheMaplecommandanames(ÕassignednamesÔ).Namescorrespondingtoproßleduserproceduresareselectedusingthesubroutinesuserprocsandtraced.Ifthenonzerooptionispassedtocovered,thenonlythosewhichhaveactuallybeencalledarechosen.Theßnalstatement>map(parse,map(convert,S,'string'))ßrstconvertsthenamestostrings,andthencallsparseoneachstringtoconvertittotheprocedureforwhichproßlingdataisstored.UsingthePackageAswithallpackages,youcanaccessthecoveragepackageinteractivelybyusingthewithcommand.>with(coverage);Warning,theprotectednameprofilehasbeenredefinedandunprotected 92¯Chapter2:ProgrammingwithModules[covered;proßle]Alistofthepackageexportsisreturned.Alternatively,thepackageex-portscanalwaysbeaccessedbyusingthelongformscoverage:-profileandcoverage:-covered.Supposethatyouwanttotesttheprocedurecopy(chosenbecauseitisshort).Thisprocedureproducesanewcopyofatable,array,orrtable.Nowthatthecoveragepackagehasbeengloballyimposedbyusingwith,simplycall>profile(copy);1Thereturnvalueof1indicatesthat,asexpected,oneprocedurewasinstrumented.Next,callcopywithafewarguments(outputsuppressed):>copy(table()):>copy(array(1..3)):Usingcovered,copyhasitsproßlinginformationstored.>covered('nonzero');[p;copy]Fromtheoutputofshowstat,>showstat(copy);copy:=proc(A)|CallsSecondsWords|PROC|20.000664|1|20.00050|iftype(A,rtable)then2|00.0000|returnrtable(rtable_indfns(A),rtable_dims(A),A,rtable_options(A),readonly=false)eliftype(A,{array,table})then3|20.00024|iftype(A,name)then4|00.0000|returnmap(proc()argsendproc,eval(A))else5|20.000590|returnmap(proc()argsendproc,A)endifelse6|00.0000|returnAendif 2.3Packages¯93endprocitappearsthatthertablecase(statement2)hasnotbeencalled.Addatestforthertablecase.>copy(rtable()):>showstat(copy);copy:=proc(A)|CallsSecondsWords|PROC|30.000832|1|30.00062|iftype(A,rtable)then2|10.000156|returnrtable(rtable_indfns(A),rtable_dims(A),A,rtable_options(A),readonly=false)eliftype(A,{array,table})then3|20.00024|iftype(A,name)then4|00.0000|returnmap(proc()argsendproc,eval(A))else5|20.000590|returnmap(proc()argsendproc,A)endifelse6|00.0000|returnAendifendprocStatement4hasnotbeencalled.Thisstatementcanbereachedbyassigninganarrayortabletoanameandbycallingcopywiththatnameasargument.>t:=table():>copy(t):>showstat(copy);copy:=proc(A)|CallsSecondsWords|PROC|40.0001185|1|40.00096|iftype(A,rtable)then2|10.000156|returnrtable(rtable_indfns(A),rtable_dims(A),A,rtable_options(A),readonly=false)eliftype(A,{array,table})then3|30.00028|iftype(A,name)then4|10.000315|returnmap(proc()argsendproc,eval(A))else5|20.000590|returnmap(proc()argsendproc,A)endifelse 94¯Chapter2:ProgrammingwithModules6|00.0000|returnAendifendprocTheonlycasethathasnotbeencalledistheoneinwhichtheargumenttocopyissomethingotherthananrtable,array,ortable.>copy(2):>showstat(copy);copy:=proc(A)|CallsSecondsWords|PROC|50.0001221|1|50.000122|iftype(A,rtable)then2|10.000156|returnrtable(rtable_indfns(A),rtable_dims(A),A,rtable_options(A),readonly=false)eliftype(A,{array,table})then3|30.00028|iftype(A,name)then4|10.000315|returnmap(proc()argsendproc,eval(A))else5|20.000590|returnmap(proc()argsendproc,A)endifelse6|10.00010|returnAendifendprocTheßnaloutputshowsthateverystatementhasbeenreachedbythetestcases.ThisfunctionalityisveryusefulforinteractivelydevelopingunittestsforMapleprograms.Note:Thesourcepresentedhereforthecoveragepackagehasbeensimplißedforpresentationinprintedform.Thefullsourcecodeisavailableinthesamples/AdvPGdirectoryoftheMapleinstallation.TheShapesPackageModulespermittheconstructionofpackageswithhierarchicalstructure.Thiscannotbedonewithtable-basedimplementationsofpackages.Thissectionpresents:¯Howtoorganizethesourcecodefora(potentially)largepackagethathasanontrivialsubstructure.¯AdescriptionoftheShapespackage,includingdetailsofitsdesignandimplementation 2.3Packages¯95¯Hintsrelatedtosourcecodeorganization.Themathematicalfunctionalityofthispackageistrivial.Itprovidesthemeanstocomputeareasandcircumferencesofvariousplanarßgures,whicharecalledshapes.Note:Onlyportionsofthesourcecodeforthispackageareshownhere.Thefullycommentedsourcecodecanbefoundinthesamples/AdvPG/shapesdirectoryoftheMapleinstallation.SourceCodeOrganizationTheShapespackageisorganizedintosev-eralsourceßles:shapes.mplpoint.mplsegment.mplcircle.mplsquare.mpltriangle.mplToavoidplatform-specißcdiÞerences,aàatdirectorystructureisused.(Allthesourceßlesresideinthesamedirectoryorfolder.) 96¯Chapter2:ProgrammingwithModulesShapesPackageshapes.mplpoint.mplsegment.mplcircle.mplsquare.mpltriangle.mplTodeßnethemodulethatimplementsthispackage,usetheMaplepre-processortoincludetheremainingsourceßlesattheappropriatepointinthemastersourceßleshapes.mpl.Anumberof$includedirectivesareincludedinshapes.mpl,suchas$include"point.mpl"$include"segment.mpl"...Splittingalargeprojectintoanumberofsourceßlesmakesiteasiertomanage,andallowsseveraldeveloperstoworkonaprojectsimultane-ously.Thesourceßleisdividedintoshape-specißcfunctionality.Mostofthefunctionalityforpoints,forinstance,isimplementedbysourcecodestoredintheßlepoint.mpl.PackageArchitectureTheShapespackageisstructuredasamodulewithanumberofexportedprocedures.Individualsubmodulesprovideshape-specißcfunctionalityforeachshapetypesupportedbythepackage. 2.3Packages¯97Eachoftheseshape-specißcsubmodulesisstoredinitsownsourceßle;theseßlesareincludedintothemainpackagesourceßle,shapes.mpl.ThepackagemoduleShapeshasasubmodule,alsocalledShapes.ThesubmoduleShapes:-Shapescontainsonesubmoduleforeachshapesupported.Thissubmodulehierarchyisillustratedinthefollowingdia-gram.ShapesShapespointtrianglesquaresegmentcircleShapesPackageSubmoduleStructureTheresultofpreprocessingthemainßleshapes.mplproducesamodulewhosesourcehasthefollowinggeneraloutline.Shapes:=module()exportmake,area,circumference;localShapes,circum_table;Shapes:=module()exportpoint,segment,circle,square,triangle;point:=module()...end;segment:=module()...end;.....endmodule;make:=proc()...end;area:=proc()...end;circum_table:=table();...circumference:=proc()...end;endmodule: 98¯Chapter2:ProgrammingwithModulesThePackageAPITheShapespackageexportsthefollowingroutines:1.make2.area3.circumferenceThemakeProcedureTheexportedproceduremakeisaconstructorforshapes.Itisusedtocreateashapeexpressionfromtheinputdata.Forexample,pointsareconstructedfromtheirxandycoordinates.>org:=make('point',0,0);org:=make(point;0;0)Acircleisconstructedfromitscenterandradius.>circ:=make('circle',org,2);circ:=make(circle;make(point;0;0);2)Ineachcase,thenameoftheshapeispassedastheßrstargument,tospecifytomakethekindofshapetoreturn.TheareaProcedureTocomputetheareaofashape,calltheexportedprocedureareawiththeshapeasitsargument.>area(circ);area(make(circle;make(point;0;0);2))ThecircumferenceProcedureTheexportedprocedurecircumferencecomputesthecircumferenceofagivenshape.>circumference(circ);circumference(make(circle;make(point;0;0);2)) 2.3Packages¯99ShapeRepresentationShapesarerepresentedasunevaluatedfunctioncalls.Theargumentstothecallaretheinstance-specißcdatafortheshape.Forexample,apointwithcoordinates(2;3)isrepresentedbytheunevaluatedfunctioncallPOINT(2,3).Someinstancedataareshapesthemselves.Forexample,asegmentisrepresented,usingitsendpoints,asanunevaluatedfunctioncalloftheformSEGMENT(start_point,end_point).Thestartandendpointsofthesegmentcanbeobtainedbycallstothepointconstructor.ProcedureDispatchTheShapespackageillustratesthreetypesofpro-ceduredispatching:1.Dispatchingonsubmoduleexports2.Conditionaldispatching3.Table-baseddispatchingDispatchingonSubmoduleExportsTheproceduremake,whichisex-portedfromtheShapespackage,usesthesubmoduleShapes:-Shapesforproceduredispatching.Totestwhetheramethodforagivenshapeisavailable,thepro-ceduremaketestswhetherthereisasubmodulebythatnameintheShapes:-Shapessubmodule.Ifnosuchsubmoduleisfound,anexcep-tionisraised.Otherwise,theexportmakefromthesubmoduleispassedtheargumentsthatweregiventothetop-levelShapes:-makeprocedure.Themakesourcecodefollows.>make:=proc(what::symbol)>description"constructorforshapes";>localctor,#theshapeconstructor,>#iffound>theShape;#thesubmoduleforthe>#kindofshaperequested>>ifnotmember(what,Shapes,'theShape')then>error"shape`%1'notavailable",what>endif;>ifmember(':-make',theShape,'ctor')then>ctor(args[2..nargs])>else>error"noconstructorprovidedfor">"shape%1",what>endif>endproc: 100¯Chapter2:ProgrammingwithModulesSummaryTheßrstargumenttomakeisasymbolthatdenotesthekindofshapetoconstruct(point,circle,triangle).ThissymbolisusedasanindexintheShapes:-Shapessubmodule.Theßrststatementusesmembertotestwhetherthesymbolpassedintheparameterwhatisex-portedbythesubmoduleShapes:-Shapes.Ifitisnotfound,anappro-priatediagnosticisissued,andanexceptionraised.Ifmemberreturnsthevaluetrue,thenitsthirdargument,thelocalvariabletheShape,isassignedtheexportfoundinthesubmodule.Forexample,ifwhatisthesymbolcircle,thenthelocalvariabletheShapeisassignedthesubmoduleShapes:-Shapes:-circlethatim-plementsoperationsoncircles.Thesameideaisusedtoselecttheshape-specißcconstructor;itisthevalueassignedtothelocalvariablectoruponatruereturnvaluefromthesecondcalltomember.Anyremainingargumentsareusedasdatatoconstructtheshape.Thesearepassedtothemakeexportinashape-specißcsubmodule,iffound,andarenotcheckedfurtheratthislevel.Thisdesignlocalizestheshapestothecorrespondingsubmodule.ConditionalDispatchingTheprocedureareausesasimpleconditionaldispatchingmechanism.Thetagoftheinputshapeisextractedandisusedindirectcomparisonswithhard-codedvaluestodeterminewhichshape-specißcareasubroutinetocalltoperformtheareacomputation.>area:=proc(shape)>description"computetheareaofashape";>localtag;>>ifnottype(shape,'function')then>error"expectingashapeexpression,">"butgot%1",shape>endif;>>#Extractthe"tag"informationfromtheshape>tag:=op(0,shape);>>#Dispatchonthe"tag"value>iftag=':-POINT'then>Shapes:-point:-area(shape)>eliftag=':-SEGMENT'then>Shapes:-segment:-area(shape)>eliftag=':-CIRCLE'then>Shapes:-circle:-area(shape)>eliftag=':-SQUARE'then>Shapes:-square:-area(shape)>eliftag=':-TRIANGLE'then>Shapes:-triangle:-area(shape)>else>error"notarecognizedshape:%1",tag 2.3Packages¯101>endif>endproc:Table-basedDispatchingThethirddispatchmethodillustratedintheShapespackageistable-based.Thistechniqueisusedbytheexportedprocedurecircumference,whichreferencesthetablecircum_tabletolookuptheappropriateroutinetocall.ThistableisbuiltsimplybyassigningitsentriesinthebodyoftheShapespackage.>circum_table:=table();>circum_table['POINT']:=Shapes:-point:-circumference;>circum_table['SEGMENT']:=Shapes:-segment:-circumference;>circum_table['CIRCLE']:=Shapes:-circle:-circumference;>circum_table['SQUARE']:=Shapes:-square:-circumference;>circum_table['TRIANGLE']:=Shapes:-triangle:-circumference;Thesourcecodefortheprocedurecircumferencefollows.>circumference:=proc(shape)>description"computethecircumferenceofa">"shapeexpression";>ifnottype(shape,'function')then>error"expectingashape,butgot%1",shape>endif;>ifassigned(circum_table[op(0,shape)])then>circum_table[op(0,shape)](shape)>else>error"nocircumferencemethodavailable">"forshape%1.Supportedshapes">"are:%2",tag,>sprintf("%q",op(ALL_SHAPES))>endif>endproc:Minimalcheckingisdonetoensurethattheinputhastherightstruc-ture.Ifanentryisfoundinthetablecircum_tablefortheshapetag(aswiththearearoutine),thenthecorrespondingprocedureiscalledwiththegivenshapeasanargument.(Theshapemustbepassedasanargument,sothattheshape-specißcsubroutinecanextracttheinstancedatafromit.)Otherwise,adiagnosticisissued,andanexceptionraised.Shape-specißcSubmodulesAsalreadynoted,eachshapeisimple-mentedinashape-specißcsubmodule.Thesetofexportsofeachmod-ulevaries,buteachsupportstherequiredexportsmake,area,andcircumferenceinthetop-levelShapesmodule.Particularshapessup-portotheroperations.Onlytwosubmodulesaredescribedhere.Youcanseethesourcefortheothersubmodulesinthesamplesourcecode. 102¯Chapter2:ProgrammingwithModulesThepointSubmoduleThesubmodulethatimplementspointsisfairlysimple.Infact,itmakesnoreferencetoanylexicallyscopedvariablesinitsparentmodules(ShapesandShapes:-Shapes).>point:=module()>description"supportroutinesforpoints";>exportmake,area,circumference,xcoord,ycoord;>optionpackage;>>make:=(x,y)->'POINT'(x,y);>area:=()->0;>circumference:=()->0;>xcoord:=p->op(1,p);>ycoord:=p->op(2,p);>endmodule:Sincetheareaandcircumferenceofapointareboth0,theseproce-duresaretrivialtoimplement.Inadditiontotherequiredexports,thepointsubmodulealsoexportstwoutilityroutines,xcoordandycoord,forretrievingthexandycoordinatesofapoint.Providingthesemakesitpossibleforclientsofthissubmoduletouseitwithoutknowingany-thingabouttheconcreterepresentationofpoints.Thismakesiteasiertochangetherepresentationlater,ifrequired.Withinthissubmodule,thenamesmake,area,andcircumferenceshadowthenameswiththesameexternalrepresentationatthetop-levelShapesmodule.ThecircleSubmoduleThissubmoduleprovidesthecircle-specißcsubroutinesfortheShapespackage.>circle:=module()>exportmake,center,radius,diameter,>area,circumference;>optionpackage;>>make:=proc(cntrPt,radius)>'CIRCLE'(cntrPt,radius)>endproc;>>center:=circ->op(1,circ);>radius:=circ->op(2,circ);>diameter:=circ->2*radius(circ);>circumference:=circ->Pi*diameter(circ);>area:=circ->Pi*radius(circ)^2;>endmodule:Again,afewextraroutinesareprovidedinadditiontothoserequiredatthetop-leveloftheShapespackage.Theexportedprocedureradiusisusedtodeßneotherroutines.Itcanbemadelocaltothissubmodule. 2.4TheuseStatement¯1032.4TheuseStatementTheusestatementisformallyunrelatedtomodules,butisexpresslydesignedtocomplementthemandtomakeprogrammingwithmoduleseasierinsomecircumstances.SyntaxandSemanticsThekeyworduseintroducestheusestatement,whichhasthefollowingsyntaxtemplate:useenvinbodyenduse;Here,envisanexpressionsequenceofbindingequations,eachofwhichiseitheramoduleoranequationwhoseleftsideisasymbol;andbodyisasequenceofMaplestatements.TherightsideofabindingequationcanbeanyMapleexpression.Executingausestatementexecutesthebodyofthestatement.Eachoccurrenceofanamethatappearsontheleftsideofanyofthebindingequationsisreplacedbytherightsideofthecorrespondingequation.Forexample,>usef=sin,g=cosin>f(x)^2+g(x)^2>enduse;sin(x)2+cos(x)2CharacteristicsoftheuseStatementTheusestatementcanbenested.>usef=sinin>useg=cosin>simplify(f(x)^2+g(x)^2)>enduse>enduse;1Whennestedusestatementsareencountered,thenamebindingses-tablishedbytheinnerusestatementtakeprecedenceoverthoseoftheouterone. 104¯Chapter2:ProgrammingwithModules>usea=2,b=3in>usea=3ina+bend>enduse;6Inthisexample,theinnerbindingofthevalue3tothenameatakesprecedence,sothevalueoftheexpressiona+b(andhenceoftheentirestatement)isthenumber6.Theinnerbindingof3toahasaneÞectonlywithinthebodyoftheinnerusestatement.Oncetheexecutionhasexitedtheinnerusestatement,thebindingof2toaisrestored.>usea=2,b=3in>#hereaisboundto2andbto3>usea=3in>#here,bisstillboundto3,butaisboundto3>a+b>enduse;>#bindingofato2isrestored>a+b>enduse;65TheusestatementisuniqueintheMaplelanguagebecauseitisfullyresolvedduringautomaticsimplißcation.Itisnotpossibletoevaluateausestatement.(RecallthatMapleusesamodißedread-eval-printloop,whichactuallyinvolvesthefourstages:parsing(reading),automaticsim-plißcation,evaluation,andprinting.)Toseehowthisworks,consideranexampleinwhichtheusestatementappearsinsideaprocedure.>f:=proc(a,b)>usex=a+b,y=a-bin>x*y>enduse>endproc;f:=proc(a;b)(a+b)£(ab)endprocNotethatthebodyoftheprocedurefcontainsnousestatement.Duringautomaticsimplißcation,theusestatementthatformedthebody 2.4TheuseStatement¯105offwasexpanded,yieldingtheexpressionthatinvolvesonlytheparam-etersaandb.ModulesanduseStatementsAsaspecialcase,amodulemcanappearinthebindingsequenceofausestatement.Themoduleisregardedasanabbreviationforthesequenceofequationsa=m:-a,b=m:-b,...,wherea,b,...aretheexportsofthemodulem.Forexample,>m:=module()exporta,b;a:=2;b:=3;end:>usemina+bend;5Thisisusefulforprogrammingwithpackages.>m:=Matrix(4,4,[[26,0,0,30],>[0,-41,-90,0],>[0,-7,-56,0],>[0,0,0,0]]);2326003060419007m:=6740756050000>useLinearAlgebrain>Determinant(m);>Rank(m);>CharacteristicPolynomial(m,'lambda')>enduse;03µ4+71µ3856µ243316µNotethatanamethatappearsinabindinglistforausestatement,whichisintendedtobeamodule,mustevaluatetoamoduleatthetimetheusestatementissimplißed.Thisisnecessarybecausethesimplißcationoftheusestatementmustbeabletodeterminetheexportsofthemodule.Inparticular,thefollowingattempttopassamoduleasaparametertoaproceduredoesnotwork,andyieldsanerrorduringthesimplißcationoftheprocedure. 106¯Chapter2:ProgrammingwithModules>proc(m,a,b)>usemine(a,b)end>endproc;Error,nobindingswerespecifiedorimpliedThecorrectwaytouseamoduleasaparameteristospecifythenamestobeboundexplicitly,suchasinthisexample:>proc(m,a,b)>usee=m:-eina+bend>endproc;proc(m;a;b)a+bendprocThisisnecessarybecause,untiltheprocedureiscalledwithamoduleexpressionasßrstargument,thereferencetoeisambiguous.Thevariableecouldrefertoamoduleexportortosomethingelse(suchasaglobalname).Toexpandtheusestatement,thismustbeknownatthetimetheprocedureissimplißed.OperatorRebindingAnadditionalfeatureoftheusestatementisthatitallowsmostinßxandpreßxoperatorsintheMaplelanguagetoberebound.Thisisnottheoperatoroverloadingfoundinsomeprogramminglanguages(suchasC++),becausetherebindingoccursduringautomaticsimplißcationinMaple.Ifanoperatornameappearsontheleftsideofabindingequationforausestatement(consequently,ifitisanexportednameofamodulethatisboundviause),thenthecorrespondingoperatorexpressionsinthebodyoftheusestatementaretransformedintofunctioncalls.Forexample:>use`+`=Fina+bend;F(a;b)>m:=module()>export`*`,`+`;>`+`:=(a,b)->a+b-1;>`*`:=(a,b)->a/b;>endmodule:>s*(s+t); 2.4TheuseStatement¯107s(s+t)>usemins*(s+t)end;ss+t1Theoperatorsthatcanbereboundaresummarizedinthefollowingtable.OperatorArityPositionDescriptionArithmeticOperators+binaryinßxaddition*binaryinßxmultiplication.binaryinßxmultiplication^binaryinßxexponentiation-unarypreßxnegation/unarypreßxinversion(reciprocal)LogicalOperatorsandbinaryinßxlogicalandorbinaryinßxlogicalornotunarypreßxlogicalnegationRelationalOperatorsbinaryinßxgreaterthan>=binaryinßxgreaterthanorequal=binaryinßxequality<>binaryinßxnotequalOtherOperators@binaryinßxcomposition@@binaryinßxpowercomposition!unarypostßxfactorialNotethattheoperators-and/aretreatedasunaryoperators(thatrepresentnegationandinversion,respectively).SubtractionisrepresentedinternallyinMaplebycomposingadditionandnegation:a-b=a+(-b).Similarlyfordivision.Therefore,itisnotnecessarytooverridethebinaryinßxoperators-and/.Notealsothatanexpressionsuchasa+b+c+distreatedasthoughitwereparenthesizedas((a+b)+c)+d,sothateach+op-eratorisbinary.Forexample, 108¯Chapter2:ProgrammingwithModules>use`+`=Fin>a+b+c+d;>a+((b+c)+d)>enduse;F(F(F(a;b);c);d)F(a;F(F(b;c);d))2.5ModelingObjectsAprincipleapplicationofmodulesismodelingobjects.Anobjectissome-thingthathasbothstateandbehavior.Manyprogramminglanguagesprovidesupportforprogrammingwithobjects.Someofthesearecalledobject-oriented;popularexamplesincludeSmalltalk,CLOS,JavaTM,andC++.Mapleisnotanobject-orientedprogramminglanguage,butitdoessupportprogrammingwithobjects.InMaple,anobjectcanberepre-sentedbyamodule.Thestateoftheobject(module)isstoredinthelocalandexporteddatavariables.Thebehavioroftheobjectisrepresentedbyproceduresassignedtotheexportedvariables.InMaple,proceduresstandonanequalfootingwithotherexpressionsinthelanguage;thedistinc-tionbetweenstateandbehaviorissomewhatartißcialandexistsonlyasaconvention.Theessentialideabehindprogrammingwithobjectsisthattheob-jectscarrytheirbehaviorwiththem.Clientsofanobjectcanelicitbe-haviorbysendingtheobjectmessages.Objectsrespondtothesemessagesbyperformingsomeprescribedcomputationthatisdeterminedbyboththerecipientofthemessage(theobject)andthemessageitself(whichmaybeparameterizedbyotherarguments).Thisisincontrasttonon-object-orientedapproachestoprogramming,inwhichtheobjectsinasoftwaresystemmerelycontainstaticdataandserveasinputsandout-putsofthealgorithms,whicharerepresentedseparatelyfromtheobjectsbyproceduresorotherroutines.ObjectsandConstructorsObjectsareusuallycreatedbyinvokingaconstructor.Aconstructorisaprocedurethatbuildstheobjectexpressionfromsome(possiblyempty)setofinputs.Mapleusesconstructorsforanumberofitsnativeexpressiontypes.Forexample,theproceduretable 2.5ModelingObjects¯109isaconstructorforMapletables,andseriesisaconstructorforMapleseriesexpressions.Aconstructormustbeusedtocreateobjectsthathavenoinputsyntax(suchasseriesandtables,inMaple),butcanalsobeusedforexpressionsthatdohaveaninputsyntax(theFloatconstructorisanexampleofthelattercase).Therefore,mostuser-deßnedobjectsmustbecreatedbyusingaconstructor.Mostoftheobjectexamplesinthissectionaredeßnedbyspecifyingaconstructorfortheobject.Example:ComplexNumberConstructorAsimpleexampleofanobjectisthefollowingrepresentationofacomplexnumber.>MakeComplex:=proc(real,imag)>ifnargs<>2then>error"realandimaginarypartsarerequired">endif;>module()>description"acomplexnumber";>localreal_part,imag_part;>exportre,im,abs,arg;>>real_part,imag_part:=real,imag;>re:=()->real_part;>im:=()->imag_part;>abs:=()->sqrt(re()^2+im()^2);>arg:=()->arctan(im(),re());>endmodule>endproc:Tocreatethecomplexnumber1+i,usetheconstructor.>z:=MakeComplex(1,1);z:=module()localreal_part;imag_part;exportre;im;abs;arg;descriptionÕacomplexnumberÔ;endmoduleTheprocedureMakeComplexisaconstructorforcomplexnumberob-jects.ThevaluereturnedbytheprocedureistheinstantiationofthemodulewhosedeßnitionappearsinthebodyofMakeComplex.Thelocalstateofthecomplexnumberisrepresentedbythelocalvariablesofthemodule,real_partandimag_part.Thebehaviorisrep-resentedbytheexportedproceduresre,im,abs,andarg. 110¯Chapter2:ProgrammingwithModulesTheexportsofamodulethatrepresentsanobjectaresometimesviewedalsoasmessages.Objectsrespondtothesemessagesbyexhibitingthebehaviorthatthemessageselicit.>z:-re(),z:-im();1;1>z:-abs();p2>z:-arg();1¹4Forinstance,theexpressionz:-abs()isviewedassendingtheabsmessagetothecomplexnumberobjectz.Theobjectrespondsbycom-putingitsabsolutevalue.NotethateachtimetheprocedureMakeComplexisinvoked,anewmoduleiscreatedusingthemoduledeßnitionthatisvisiblewithintheprocedurebody.Thus,complexnumberscreatedbydiÞerentcallstotheconstructoraredistinct,eveniftheargumentsrealandimagarethesame.Whetheraconstructorshouldproducedistinctobjectsforthesameinput(instance)datadependsonthenatureoftheobjectsbeingmodeled.Forcomplexnumberobjects,multiplecallswiththesameinputsshouldproducethesameobject.Thiscanbeachievedbyusingtherememberoptionintheconstructor.Formoreinformation,refertochapter6oftheIntroductoryProgrammingGuide.EÞectofImmutableLocalStatesThepreviousMakeComplexconstruc-torrepresentsthelocalstateofcomplexnumberobjectsbyusingtwolocalvariablesreal_partandimag_part.Formanyobjectconstructors,someorallofthelocalstateoftheobjectisexpectedtobeimmutable.Inthesecases,localvariablesdonotneedtobeallocatedinthemoduletostorethelocalstateoftheobject.Thestatecaninsteadberepresentedbytheparameterstotheconstructor,whicharevisiblewithinthemodulebytheMaplelexicalscopingrules.Usingthisidea,thepreviousconstructorcanbesimplißedasfollows. 2.5ModelingObjects¯111Table2.1PriorityQueueMethodsemptyTestforanemptypriorityqueuetopReturnthehighest-priorityiteminsertInsertaprioritizeditemdeleteRemove(andreturn)thehighestpriorityitem>MakeComplex:=proc(real,imag)>ifnargs<>2then>error"realandimaginarypartsarerequired">endif;>module()>description"acomplexnumber";>exportre,im,abs,arg;>>re:=()->real;>im:=()->imag;>abs:=()->sqrt(real^2+imag^2);>arg:=()->arctan(imag,real);>endmodule>endproc:PriorityQueuesAusefuldatastructurethatcanbeimplementedinanobject-orientedwaywithmodulesisthepriorityqueue.Apriorityqueueisacontainerdatastructurethatadmitsthefollowingoperations:¯Testforanemptypriorityqueue¯Insertaprioritizeditemintoapriorityqueue¯Return(non-destructively)thehighest-priorityiteminthepriorityqueue¯DeletethehighestpriorityitemfromapriorityqueueDesignTable2.1liststhemethodsofanobjectrepresentationofpriorityqueues.ThisrepresentationleadsdirectlytothefollowingMapletype,whichcanbeusedtoidentifypriorityqueues.>`type/PriorityQueue`:='`module`(empty,top,insert,>delete)': 112¯Chapter2:ProgrammingwithModulesConstructorImplementationPriorityqueuescanbeimplementedasMapleobjectsbywritingaconstructorfortheobjects.>PriorityQueue:=proc(priority::procedure)>description"priorityqueueconstructor";>locallargs,lnargs;>>lnargs:=nargs;>iflnargs>1then>largs:=[args[2..-1]]>else>largs:=[]>endif;>>module()>description"apriorityqueue";>exportempty,top,insert,>size,delete,init;>localheap,nitems,>bubbleup,bubbledown;>>nitems:=0;>heap:=table();>>bubbleup:=proc(child::posint)>localparent;>parent:=iquo(child,2);>ifchild>1>andpriority(heap[child])>priority(heap[>parent])then>heap[parent],heap[child]:=heap[child],>heap[parent];>procname(parent)#recurse>endif>endproc;>>bubbledown:=proc(parent::posint)>localchild;>child:=2*parent;>ifchildandpriority(heap[1+child])>priority(>heap[child])then>child:=1+child>endif;>ifchild<=nitems>andpriority(heap[parent])child])then>heap[parent],heap[child]:=heap[child],>heap[parent];>procname(child)#recurse(newparent)>endif>endproc;>>#Initializethepriorityqueue. 2.5ModelingObjects¯113>init:=proc()>heap:=table();>nitems:=0>endproc;>>#Testwhetherthepriorityqueueisempty.>empty:=()->evalb(nitems<1);>>#Returnthenumberofitemsonthepriorityqueue.>size:=()->nitems;>>#Querythehighestpriorityitem.>top:=proc()>ifempty()then>error"priorityqueueisempty">else>heap[1]>endif>endproc;>>#Deletethehighestpriorityitemfromthe>#priorityqueue.>delete:=proc()>localval;>val:=heap[1];#val:=top()>#movebottomtothetop>heap[1]:=heap[nitems];>#allowexpressiontobecollected>heap[nitems]:=evaln(heap[nitems]);>#decrementthebottomofheapcounter>nitems:=nitems-1;>#heapifythearray>bubbledown(1);>#returnthevalue>val>endproc;>>#Insertanitemintothepriorityqueue.>insert:=proc(v)>ifnargs>1then>op(map(procname,[args]))>else>nitems:=1+nitems;>heap[nitems]:=v;>bubbleup(nitems)>endif>endproc;>>#Insertanyintiallyspecifieditems.>iflnargs>1then>insert(op(largs))>endif>endmodule>endproc: 114¯Chapter2:ProgrammingwithModulesTheconstructortakesaMapleprocedurepriorityasitsargument.Foreachexpressionplacedonthequeue,thisprocedurereturnsanumericmeasureofitspriority.Itemsonthequeuearemaintainedinaprioritizedordersothatthehighestpriorityitemsareremovedßrst.Inthissamplecomputationwithapriorityqueue,usetheMaplebuilt-inprocedurelengthasthepriorityofanexpression.Here,therandomlygeneratedexpressionsareallpolynomials.>pq:=PriorityQueue(x->length(x));pq:=module()localheap;nitems;bubbleup;bubbledown;exportempty;top;insert;size;delete;init;descriptionÕapriorityqueueÔ;endmodule>forifrom1to10do>pq:-insert(randpoly(x));>enddo:>whilenotpq:-empty()do>pq:-delete()>enddo;5085x555x437x335x2+97x7299x585x486x3+30x2+80x7253x5+85x4+49x3+78x2+17x59+79x5+56x4+49x3+63x2+57x8886x5+23x484x3+19x250x6250x512x418x3+31x226x8358x590x4+53x3x2+94x61+77x5+66x4+54x35x2+99x62+45x58x493x3+92x2+43x41+x547x491x347x261xPriorityQueueUsagePriorityqueuescanbeusedtoimplementaheap-sortalgorithm.>HeapSort:=proc(L::list(numeric))>localpq,t,count; 2.5ModelingObjects¯115>pq:=PriorityQueue(x->-x,op(L));>t:=array(1..nops(L));>count:=0;>whilenotpq:-empty()do>count:=1+count;>t[count]:=pq:-delete()>enddo;>ASSERT(count=nops(L));>[seq(t[count],count=1..nops(L))]>endproc:>r:=rand(100):>L:=[seq(r(),i=1..20)]:>HeapSort(L);[7;7;15;25;27;27;28;29;42;51;52;55;62;74;82;88;94;97;97;98]Note:ThefullycommentedsourcecodeforthePriorityQueuecon-structorisavailableinthesamples/advPG/PriorityQueuedirectoryoftheMapleinstallation.AnObject-orientedShapesPackageThissectiondemonstratesanobject-orientedapproachtotheShapespackagedescribedinsection2.3.Theearlierrevisionofthepackageusedunevaluatedfunctioncallsastheconcreterepresentationofshapes.ThissectiondemonstrateshowtobuildapackagethatoÞersthesamefunction-ality,butwhichrepresentsshapesasobjects.Eachshapeusesamoduleasitsconcreterepresentation.Thepackageitselfdoesnotexporttheareaandcircumferencefeaturesofthetraditionalstylepackage,be-causethesefeaturesareavailableaspartofeachshapeobject.Instead,thepackageismerelyacollectionofconstructorsforthevariouskindsofshapes.Youcouldusetheobjectrepresentationatalowerlevel,andpresentexactlythesameinterfaceastheßrstShapespackage,butthissectionshowshowtomaketheobject-orientednatureofshapeexpressionsmoreapparenttotheuser.ThepointConstructorPointsaresimpleshapes,sothecorrespondingconstructorissimilarlysimple.>point:=proc(x,y)>module()>exportarea,circumference,xcoord,ycoord;>xcoord:=()->x;>ycoord:=()->y;>area:=()->0;>circumference:=()->0; 116¯Chapter2:ProgrammingwithModules>endmodule>endproc:Themodulereturnedbythisconstructorusesthelexicallyscopedparametersxandy,representingtheabscissaandordinateofthepoint.Thesevaluesarepartofthelocalstate,orinstancedata,ofeachpointconstructed.Thesepointsarecapturedintheclosuresoftheexportedmethods,sothatvariableslocaltothemoduleinwhichtostorethesevaluesarenotnecessary.ThesegmentConstructorSegmentsarerepresentedusingthestartandendpointsofthesegment.Thesearethepointsreturnedbythepointconstructor.>segment:=proc(pt1,pt2)>module()>exportarea,>circumference,>length,>start_point,>end_point;>localmymidpoint;>>start_point:=()->pt1;>end_point:=()->pt2;>area:=()->0;>circumference:=()->0;>length:=proc()>localx,y;>x:=pt1:-xcoord()-pt2:-xcoord();>y:=pt1:-ycoord()-pt2:-ycoord();>sqrt(x^2+y^2)>endproc;>midpoint:=proc()>localx,y;>ifassigned(mymidpoint)then>mymidpoint>else>y:=(pt1:-ycoord()+pt2:-ycoord())/2;>x:=(pt1:-xcoord()+pt2:-xcoord())/2;>point(x,y)>endif>endproc;>endmodule>endproc:Thesegmentobjectsimplementmethodsinadditiontotherequiredareaandcircumferencemethods.Apartfromthetrivialsyntaxmethodsstart_pointandend_point,therearemethodsforcomputingthelengthofasegmentanditsmidpoint. 2.6InterfacesandImplementations¯117ThecircleConstructorCirclesarerepresentedbyusingthecenterandradiusofthecircleasinstancedata.>circle:=proc(ctr,rad)>module()>exportarea,circumference,diameter,>center,centre,radius;>radius:=()->rad;>center:=()->ctr;>centre:=eval(center);#UKspelling>diameter:=()->2*radius();>circumference:=()->Pi*diameter();>area:=()->Pi*rad*rad;>endmodule>endproc:Again,thelexicallyscopedparametersctrandradencodethein-stancedataofthecircleobject.Note:TheremainderoftheobjectorientedversionoftheShapespack-agecanbereadinShapeObj.mplßleinthesamples/AdvPGdirectoryofyourMapleinstallation.2.6InterfacesandImplementationsGenericprogrammingisaprogrammingstyleandasoftwareengineeringmethodologyforsoftwarereuse.Inthissense,manyMaplebuilt-inop-erationsaregeneric.Theadditionoperator+computessumsofintegers,rationalnumbers,complexnumbers,polynomials,specialfunctions,andsoon.Whenusingtheadditionoperator+,itisnotnecessarytostatehowanexpressionisrepresented.(TheautomaticsimplißerrecognizeshowMapleexpressionsarerepresented.)Aswithanydynamicallytypedlanguage,Mapleallowsforagreatdealofgenericprogramming.Mostbuilt-inMapleoperations(includingmanystandardlibraryroutines)arenaturallypolymorphicinthattheyareabletoperformsuccessfullywithalargevarietyofdataformats.GenericProgrammingasGoodSoftwareEngineeringPracticeOnanylargeproject,itisimportanttowritereusablecode;thatis,codethatcanperformawell-deßnedfunctioninawidevarietyofsituations.Genericprogramsdonotrelyonthedetailsofhowtheirinputsarerepresented.Theyareabletoperformtheirfunctiononanyinputsthatsatisfyaspec-ißedsetofconstraints.Normally,theseconstraintsaredescribedinterms 118¯Chapter2:ProgrammingwithModulesofthebehavioroftheinputsratherthanontheirphysicalrepresentationorthestoragelayoutoftheirconcreterepresentation.Thisbehaviorissometimescalledacontract.Genericprogramsrelyonlyontheobjectbehaviorspecißedbythecontract.Theydonotrelyonknowledgeofhowanobjectisimplemented.So,genericsoftwareseparatesinterfacesfromimplementations.DistinctionBetweenLocalandExportedVariablesThebehaviorspec-ißedbythecontractforamoduleincludesanymoduleexports.Whateverisexpressedthroughitslocalvariablesisprivatetothemodule,andisnottobereliedupon,orevenknown,byclientsofthemodule.(Clientaccessis,infact,theonlytechnicaldiÞerencebetweenmodulelocalsandexports.)Beforetheintroductionofthemodulesystem,designbycontractwasenforcedinMapleonlybyconvention.Mapleroutineswhosenameshadtobeenclosedinnamequotes(`)wereconsideredprivate,andnotforclientuse.Butthiswasonlyaconvention.Moreover,itwasnecessarytouseglobalvariablestocommunicateinformationandstateamongtheroutinesthatcomprisedasubsystem(suchassolveorassume).Now,usingmodules,itispossibletodesignsoftwaresystemsthatenforcetheircontractsbyamechanismembeddedintheMaplelanguage.InterfacesThecontractsdiscussedpreviouslyinthissectionarerepresentedformallyinMaplebyaninterface.Aninterfaceisaspecialkindofstructuredtype.Ithastheform`module`(symseq);inwhichsymseqisasequenceofsymbolsoroftypedsymbols(ex-pressionsoftheformsymbol::type).Forexample,aninterfaceforaringcanbewrittenas>`type/ring`:='`module`(`+`,`*`,`-`,zero,one)':whilean(additive)abeliangroupcantaketheform>`type/abgroup`:='`module`(`+`,`-`,zero)':Thesesymbolsaretheonestowhichclientshaveaccessasmoduleexports.Amoduleissaidtosatisfy,ortoimplement,aninterfaceifitisofthetypedeßnedbytheinterface. 2.6InterfacesandImplementations¯119>z5:=module()>description"theintegersmodulo5";>export`+`,`*`,`-`,zero,one;>`+`:=(a,b)->a+bmod5;>`*`:=(a,b)->a*bmod5;>`-`:=s->5-smod5;>zero:=0;>one:=1;>endmodule:>type(z5,'ring');trueAmodulecansatisfymorethanoneinterface.>type(z5,'abgroup');trueInterfacesareanabstractionthatformpartoftheMapletypesystem.Theyprovideaformofconstrainedpolymorphism.NoteveryMapletypeisaninterface;onlythosethathavetheformdescribedare.YoucandeßneaMapletype(that,asithappens,isnotitselfaninterface)todescribeinterfaces.>`type/interface`:='specfunc({symbol,symbol::type},>`module`)':Thisisastructuredtype.Itdescribesexpressionsthatarethemselvesstructuredtypes.Theyhavetheformofanunevaluatedfunctioncallwiththeoperatorsymbol`module`andallargumentsoftypesymbol,oroftypesymbol::type.Inthetwopreviousexamplesinthissection,thetypestype/ringandtype/abgrouparetheinterfaceexpressions,andthenamesringandabgrouparetherespectivenamesofthoseinterfaces.APackageforManipulatingInterfacesInterfacesaresuácientlyim-portantthatitisworthwhiletodevelopapackageformanipulatingthem.Thepackageissmallenoughthatitcanbereproducedhere,infull,butitisalsoavailableinthesamples/AdvPGdirectoryoftheMapleinstallation.>Interface:=module()>description"apackageformanipulatinginterfaces";>global`type/interface`;>exportdefine,#defineaninterface>extend,#extendaninterface>extends,#testforanextension>equivalent,#testequivalence>savelib,#saveaninterface 120¯Chapter2:ProgrammingwithModules>satisfies;#testwhetheramodulesatisfies>#aninterface>localgassign,#assigntoaglobalvariable>totype,#convertfrominterfacenametotype>toset,#convertfrominterfacenametoaset>setup;#install`type/interface`globally>optionpackage,load=setup;>>#Defineaglobaltypeforinterfaces.>#Thisassignmenttakescareofinstallingthetype>#intheMaplesessioninwhichthismoduledefinition>#isevaluated.Calling`setup()'ensuresthatthisalso>#happenswhentheinstantiatedmoduleisreadfroma>#repository.>`type/interface`>:='specfunc({symbol,`::`},`module`)';>>#Ensurethat`type/interface`isdefined.Thisthunkis>#calledwhentheinstantiated`Interface'moduleisread>#fromaMaplerepository.>setup:=proc()>global`type/interface`;>`type/interface`>:='specfunc({symbol,`::`},`module`)';>NULL#quietreturn>endproc;>>#Assigntotheglobalinstanceofaname>gassign:=proc(nom::symbol,val)>optioninline;>eval(subs(_X=nom,>proc()>global_X;>_X:=val>end))()>endproc;>>#Convertaninterfacenametothecorrespondingtype.>totype:=(ifc::symbol)->(`type/`||ifc);>>#Convertaninterfacenametoasetofsymbols.>toset:=(ifc::symbol)->{op((`type/`||ifc))};>>#Installanewinterfaceintothetypesystem.>define:=proc(ifc)>description"defineaninterface";>ifmap(type,{args},'symbol')<>{true}then>error"argumentsmustallbesymbols">endif;>gassign(`type/`||ifc,>'`module`'(args[2..nargs]));>ifc#returntheinterfacename>endproc;> 2.6InterfacesandImplementations¯121>#Implementsubtyping.>extend:=proc(new,old)>description"extendanexistinginteface";>ifmap(type,{args},'symbol')<>{true}then>error"argumentsmustallbesymbols">endif;>ifnottype(totype(old),'interface')then>error"cannotfindaninterfacenamed%1",old>endif;>define(new,op(totype(old)),args[3..nargs])>endproc;>>#Testwhetherifc2isanextensionofifc1.>extends:=proc(ifc1,ifc2)>description"testwhetherthesecondinterface">"extendsthefirst";>localt1,t2;>t1,t2:=op(map(totype,[ifc1,ifc2]));>ifnottype([t1,t2],'[interface,interface]')then>ifnottype(t1,'interface')then>error"argumentsmustbeinterfacenames,">"butgot%1",ifc1>else>error"argumentsmustbeinterfacenames,">"butgot%1",ifc2>endif>endif;>toset(ifc1)subsettoset(ifc2)>endproc;>>#Saveaninterfacetotherepository.>savelib:=proc()>description"saveanamedinterfacetoa">"repository";>localifc;>forifcinmap(totype,[args])do>ifnottype(ifc,'interface')then>error"argumentsmustbeinterfaces,">"butgot%1",ifc>endif;>:-savelib(totype(ifc))>enddo>endproc;>>#Testwhetheramodulesatisfiesaninterface.>#Thisissimplyanalternativetoacall>#to`type()'.>satisfies:=proc(m,ifc)>description"testwhetheramodulesatisfiesaninterface";>ifnottype(totype(ifc),'interface')then>error"secondargumentmustbeaninterfacename,">"butgot%1",ifc>endif;>type(m,ifc) 122¯Chapter2:ProgrammingwithModules>endproc;>>#Testwhethertwointerfacesareequivalent.>#Sinceunevaluatedfunctioncallscompare>#differentlyiftheirargumentsareina>#differentorder,weconvertthemtosetsfirst,>#andthentestforequality.>equivalent:=proc(ifc1,ifc2)>description"testwhethertwointerfaces">"areequivalent";>localt1,t2;>t1,t2:=totype(ifc1),totype(ifc2);>ifnottype(t1,'interface')then>error"expectinganinterfacename,">"butgot%1",ifc1>elifnottype(t2,'interface')then>error"expectinganinterfacename,">"butgot%1",ifc2>endif;>evalb({op(t1)}={op(t2)})>endproc;>endmodule:Thispackageimplementstheinterfaceabstraction.ItallowsyoutomanipulateinterfaceswithouthavingtoworryabouthowtheyßtintotheMapletypesystem.>with(Interface);Warning,theprotectednamesdefineandsavelibhavebeenredefinedandunprotected[deßne;equivalent;extend;extends;satisßes;savelib]>define('abgroup','`+`','`-`','zero');abgroup>type(`type/abgroup`,'interface');true>type(z5,'abgroup');true 2.6InterfacesandImplementations¯123>satisfies(z5,'abgroup');true>extend('ring','abgroup','`*`','one');ring>type(`type/ring`,'interface');true>extends(abgroup,ring);true>satisfies(z5,'ring');true>type(z5,'ring');trueTheload=OptionThispackageprovidesanabstractionoftheinter-faceconceptinMapleandillustratesamodulefeaturenotpreviouslydemonstratedÛtheload=procedure_nameoption.IntheInterfacepack-age,thisoptionisusedinafairlytypicalway.Thedeclarationoptionload=setup;thatappearsinthemoduledeßnitioninstructsMaplethat,whentheinstantiatedmoduleisreadfromarepository,itistocalltheproceduresetup.Theprocedurenamedmustbealocaloranexportedlocalofthemodule.Thelocalproceduresetupinthismodulesimplyensuresthattheglobalvariabletype/interfaceisassignedanappropriatevalue.Thisassignmentisalsomadeinthebodyofthemodulesothattheassignmentisalsoexecutedinthesessioninwhichthemoduleisinstantiated.Thisisdoneforillustrativepurposes.Abetterschemesimplyinvokessetupinthebodyofthemoduledeßnition. 124¯Chapter2:ProgrammingwithModulesGenericGraphAlgorithmsThefollowingexampleusessimplegraphalgorithmstoillustrategenericprogramming.MathematicalDescriptionAdirectedgraphcanbethoughtofasanobjectthatconsistsofasetVofverticesandasetE²V¢Voforderedpairsofvertices,callededges.Graphscanbevisualizedbydiagramslikethefollowing.abedcfThisdiagramrepresentsagraphwithvertexsetV=fa;b;c;d;e;fg,andedgesetE=f(a;b);(a;c);(b;d);(c;f);(f;d);(b;e);(d;e);(c;b);(c;d)g.SoftwareModelsGraphscanberepresentedinavarietyofways.Thechoiceofstoragemechanismdependsontheexpectedapplicationsofthegraph.Threepossibilitiesforrepresentinggraphsinsoftwareare:1.StorethesetVofverticesandthesetEofedgesexplicitly.2.StoretheÕadjacencymatrixÔofthegraph.3.Store,foreachvertexofthegraph,thesetofallitsneighbours.(Theadjacencymatrixisasquarematrixwhoserowsandcolumnsareindexedbytheverticesofthegraph;the(i;j)-entryisequalto1ifthereisanedgefromitoj,andisequalto0otherwise.)Youcanwritesoftwarethatmanipulatesagraphindependentofrepresentation.DesigningaGraphInterfaceTodemonstratehowthiscanbeachieved,considergraphsasobjectsthatimplementthemethodslistedinTable2.2.Then,representtheabstractinterfaceofagraphbyaMapletype.>`type/Graph`:='`module`(vertices,edges,addedge,order,>size)':AnobjectimplementsthegraphinterfaceifitisoftypeGraph. 2.6InterfacesandImplementations¯125Table2.2GraphMethodsverticesReturnsthesetofverticesofthegraphedgesReturnsthesetofedgesofthegraphaddedgeAllowsonetoaddanewedgetoagraphorderReturnsthenumberofverticesofthegraphsizeReturnsthenumberofedgesofthegraphComputingVertexDegreesGenericallyIfanobjectimplementsthisinterface,thenyoucanwritegenericcodebasedonthatinterface.Forexample,youcanwritethefollowingproceduretocomputethein-degreeandout-degreeofavertexofagivengraph.>vdeg:=proc(G::Graph,v)>localvs,vt;>description"computethein-andout-degrees">"ofavertexinagraph";>ifmember(v,G:-vertices())then>vs:=select(e->evalb(v=e:-source()),>G:-edges());>vt:=select(e->evalb(v=e:-target()),>G:-edges());>nops(vs),nops(vt)>else>0,0>endif>endproc:Youcanwritethisprocedureeventhough,atthispoint,youdonotknowthegraphimplementation.Thiscapabilityisveryimportantwhenyouaredesigningalargesoftwaresystem.EdgeObjectRepresentationAssumethatedgesarerepresentedasob-jectsthatimplementtheinterface`module`(source,target).Theinterfaceprovidesmethodsforextractingthesourceandtargetverticesfromanedge.WritingaconstructorEdgeforedgesiseasy.>Edge:=proc(src,targ)>module()>localthe_source,the_target;>exportsource,target,setsource,settarget;>the_source:=src;>the_target:=targ;>source:=()->the_source;>target:=()->the_target;>setsource:=proc(v)>the_source:=v>endproc;>settarget:=proc(v)>the_target:=v 126¯Chapter2:ProgrammingwithModules>endproc;>endmodule>endproc:FirstGraphConstructorAtßrst,youmightchoosetoadoptagraphrepresentationthatissimpletoimplement.Hereisagraphconstructorthatproducesgraphsrepresentedbystoringthevertexandedgesetsexplicitlyaspartofthestateofamodule.>Graph1:=proc()>localvertex_set,edge_set;>description"graphconstructor";>>edge_set:={args};>ifnotandmap(type,edge_set,'[anything,anything]')>then>error"graphmustbespecifiedbyasequenceofedges">endif;>ifnotandmap(edge->evalb(nops(edge)=2),edge_set)>then>error"eachedgemustbespecified">"asa[source,target]pair">endif;>vertex_set:=map(op,edge_set);>edge_set:=map(Edge@op,edge_set);>module()>exportorder,size,>vertices,edges,>addedge;#requiredexports>vertices:=()->vertex_set;>edges:=()->edge_set;>addedge:=proc(src,targ)>edge_set:={Edge(src,targ)}>unionedge_set;>vertex_set:={src,targ}>unionvertex_set;>NULL>endproc;>order:=()->nops(vertices());>size:=()->nops(edges());>endmodule>endproc:Ifyoucreateasmallgraphusingthisconstructor>g1:=Graph1([a,b],[a,c],[b,c]):>type(g1,'Graph');true 2.6InterfacesandImplementations¯127youcanusetheroutinevdegwiththegraphg1,sincegraphsproducedbyGraph1implementtheGraphinterface.>vdeg(g1,a);2;0>vdeg(g1,b);1;1>vdeg(g1,c);0;2Theimportantfeatureoftheprocedurevdegisitsgenericquality.ItcanbeusedwithanyimplementationofgraphsthatimplementstheGraphinterfacepreviouslyspecißed.SecondGraphConstructorHereisanother,diÞerentimplementationoftheGraphinterface.ThegraphisrepresentedbyusingatableNinwhichtheneighborsofeachvertexarestored.>Graph2:=proc()>localvertex_set,edge_set;>description"graphconstructor";>>edge_set:={args};>vertex_set:=map(op,edge_set);>ifnotandmap(type,edge_set,'list')then>error"graphmustbespecifiedbyasequenceofedges">endif;>ifnotandmap(edge->evalb(nops(edge)=2),edge_set)>then>error"eachedgemustbespecified">"asa[source,target]pair">endif;>module()>exportorder,size,>vertices,edges,>addedge;>localN,e,v,n,edge_pairs;>N:=table();>edge_pairs:=()->{seq(>seq([v,n],n=N[v]),>v=map(op,{indices(N)})>)};>vertices:=()->map(op,edge_pairs()); 128¯Chapter2:ProgrammingwithModules>edges:=()->map(Edge@op,edge_pairs());>addedge:=proc(src,targ)>ifassigned(N[src])>andnotmember(targ,N[src])then>N[src]:={op(N[src]),targ}>else>N[src]:={targ};>endif;>NULL>endproc;>order:=()->nops(vertices());>size:=()->nops(edges());>foreinedge_setdo>addedge(op(1,e),op(2,e))>enddo>endmodule>endproc:AgraphreturnedbytheconstructorGraph2alsosatisßestheGraphin-terface.>g2:=Graph2([a,b],[a,c],[b,c]):>type(g2,'Graph');trueTherefore,thegenericprocedurevdegworksequallywellwithit.>vdeg(g2,a);2;0>vdeg(g2,b);1;1>vdeg(g2,c);0;2Note:Thefullsourcecodefortheseproceduresisavailableinthesamples/AdvPG/graphdirectoryoftheMapleinstallation.GenericComputationofAdjacencyMatricesAnotherexampleofagenericprocedureovertheGraphinterfaceisthefollowingroutineforcomputingtheadjacencymatrixofagraph. 2.6InterfacesandImplementations¯129>AdjacencyMatrix:=proc(g::Graph)>locala,#theadjacencymatrix;returned>n,#theorderofthegraphg>V,#thevertexsetofthegraph>E,#theedgesetofthegraph>row,#rowindexformatrix>col,#columnindexformatrix>e;#inductionvariableforloop>>n:=g:-order();>a:=Matrix(n,n,'storage'='sparse');>V:=sort(convert(g:-vertices(),'list'));>E:=g:-edges();>foreinEdo>ifnotmember(e:-source(),V,'row')>ornotmember(e:-target(),V,'col')then>error"inconsistentgraphstructuredetected">endif;>a[row,col]:=1>enddo;>a>endproc:>AdjacencyMatrix(g1);2301140015000>AdjacencyMatrix(g2);2301140015000QuotientFieldsAsanexampleofgenericprogramming,agenericquotientßeld(orßeldoffractions)constructionalgorithmisdiscussed.MathematicalDescriptionGivenanintegraldomainD,itsquotientßeldis(uptoisomorphism)theuniqueßeldk,pairedwithanonzeroringhomomorphism±:D!k,withthepropertythat,foranynonzeroringhomomorphism':D!F,inwhichFisaßeld,thereisauniqueringhomomorphism»forwhichthediagram 130¯Chapter2:ProgrammingwithModuleskshFjDcommutes.Becauseanonzeroringhomomorphismintoaßeldmustbeinjective,thissaysthateveryßeldFthatcontainsDasasubringmustalsocontainanisomorphiccopyofk.Concretely,thequotientßeldofanintegraldomainDcanbethoughtofasthesetofÕreducedfractionsÔn=d,withn;d2D.Aformalcon-structioncanbeproducedbydeßninganequivalencerelationonthesetD¢(Dnf0g),accordingtowhichtwopairs(n1;d1)and(n2;d2)areequivalentonlyif,n1¡d2=n2¡d1:Arepresentativefromeachequivalenceclassischosentorepresenttheßeldelementdeßnedbythatclass.Thisunderstandingguidesthecom-puterrepresentationofthequotientßeld.UnitNormalRepresentativesIfRisacommutativeringwithmulti-plicativeidentity,thenU(R)¢R!R:(u;r)!u¡risanaturalactionofthegroupU(R)ofunitsofRonR.Eachorbitofthisactionhasarepresentativecalledtheunitnormalrepresentativeoftheclass.ConsideraneÞectivemappingR!Rthatselectstheunitnormalrepresentativeofeachclass.Forinstance,fortheringZofintegers,thegroupU(Z)ofunitsisthesetf1;1g,theorbitsarethesetsfn;ngforn2Znf0gtogetherwithf0g,andyoutaketheunitnormalrepresentativetobethepositivememberofeachorbit,and0fortheorbitf0g.(Thus,theunitnormalmappingsimplycomputesthesignandabsolutevalueofaninteger.)Theunitnormalmappingontheringk[T]ofpolynomialsinanindeterminateToveraßeldkis1p(T)!¡p(T);lc(p(T))inwhichlc(p(T))denotestheleadingcoeácientofthepolynomialp(T).(Thegroupofunitsink[T]isthesetk£=knf0g,ofnonzeromembersofk,andeachorbitofk[T]undertheactionofk£containsanuniquemonicpolynomialthatisitsrepresentative.) 2.6InterfacesandImplementations¯131DesigningtheRingInterfacesTheßrststepinrepresentingtheseideasinsoftwareistodeviseaninterfacethatdescribestherings.Supposethattheringsareequippedwiththebasicringoperations,aswellasseveralmethodsthatimplementdesiredcomputations.>`type/Ring`:='`module`(>`+`::procedure,>`*`::procedure,>`-`::procedure,>iszero::procedure,>isone::procedure,>zero,one>)':Thisinterfacecorrespondsnaturallywithaformalmathematicalcharac-terizationoftheringasatuplehS;+;£;0;1ithatsatisßesanumberofproperties,andtowhichsomecomputationalcapabilitieshavebeenadded.GiventhewayoperatoroverridesworkinMaple,unarynegation(-)isadded.(Inamoretightlyintegratedsystem,youspecifythenumberandtypesofargumentstoeachoftheprocedures.)Forthesecomputations,youneedaslightlyricherstructure.>`type/GcdRing`:='`module`(>`+`::procedure,>`*`::procedure,>`-`::procedure,>quo::procedure,>rem::procedure,>gcd::procedure,>unormal::procedure,>iszero::procedure,>isone::procedure,>zero,one>)':ThisinterfaceextendstheRinginterfacedeßnedpreviously.Notethatnothinginthesignatureenforcesanyring-theoreticproperties(suchasbeinganintegraldomain,orhavinguniquefactorization).Itmerelyspec-ißestheadmissibleoperations.Tocomputewithinßniterings(andevenlargeßniteones),youdonotrequireanenumerationoftheelementsofthering.YoucanfocusentirelyontheeÞectivelycomputableoperationsthattheringmustsupport.RepresentingtheringZofIntegersOneofthesimplestexamplesofaringthatsupportsthecomputationsistheringofintegersZinitsnativeMaplerepresentation. 132¯Chapter2:ProgrammingwithModules>MapleIntegers:=module()>description"theringofintegers";>export`+`,`*`,`-`,>gcd,unormal,iszero,>isone,zero,one,rem,quo;>`+`:=(a,b)->a+b;>`*`:=(a,b)->a*b;>`-`:=i->-i;>quo:=(a,b)->:-iquo(a,b);>rem:=(a,b)->:-irem(a,b);>gcd:=(a,b)->:-igcd(a,b);>unormal:=proc(i::integer)>ifi<0then>-1,-i>else>1,i#includes0>endif>endproc;>iszero:=i->evalb(i=0);>isone:=i->evalb(i=1);>zero:=0;>one:=1;>endmodule:Thisisasoftwarerepresentationoftheringofintegers.Theunitnormalmappingisrepresentedbytheexportedprocedureunormal.Itreturnsanexpressionsequenceoflengthtwo,whoseßrstmemberisaunit,andwhosesecondmemberistheunitnormalformofitsargument.Theproductoftheoutputvaluesyieldstheinputringelement.Theothermethodsonlyinvokethecorrespondingbuilt-inMapleoperations.>type(MapleIntegers,'Ring');true>type(MapleIntegers,'GcdRing');trueAnInterfaceforFieldsThequotientßeldconstructorproducesaßeld.AninterfacethatdescribesßeldsdiÞersfromtheoneforintegraldomainsbytheabsenceofagcdmethod(sincetheyaretrivial)andtheadditionofthe(unary)/operatorthatcomputesinverses.Themethodsremandquoarealsonotincludedinthesignatureforßelds,becausetheyaretrivialinaßeld.Twonewmethodsareincluded:¯makeforconstructingßeldelementsfromtheirnumeratorsandde-nominators 2.6InterfacesandImplementations¯133¯embed,thenaturalembeddingoftheintegraldomainDintoitsßeldkoffractions.Additionally,thetwomethodsnumeranddenomallowtheusertoextractthecomponentsofafraction.>`type/Field`:='`module`(>`+`::procedure,>`*`::procedure,>`-`::procedure,>`/`::procedure,>normal::procedure,>iszero::procedure,>isone::procedure,>zero,one,>make::procedure,>embed::procedure,>numer::procedure,>denom::procedure>)':Naturally,theringZofintegersisnotaßeld.>type(MapleIntegers,'Field');falseFieldsproducedbythequotientßeldconstructorsatisfythisinterface.TheQuotientFieldFunctorHereisthegenericconstructorforquotientßelds.>QuotientField:=proc(R::GcdRing)>description"quotientfieldfunctor";>module()>description"aquotientfield";>export`+`,`*`,`-`,`/`,>zero,one,>iszero,isone,>make,>numer,denom,>normal,embed;>make:=proc(n,d)>localu,nd;>ifR:-iszero(d)then>error"divisionbyzero">endif;>u,nd:=R:-unormal(d);>'FRACTION'(u*n,nd)>endproc;>embed:=d->make(d,R:-one);>numer:=f->op(1,f);>denom:=f->op(2,f); 134¯Chapter2:ProgrammingwithModules>zero:=embed(R:-zero);>one:=embed(R:-one);>iszero:=f->evalb(normal(f)=zero);>isone:=f->evalb(normal(f)=one);>normal:=proc(f)>localg,a,b;>g:=R:-gcd(numer(f),denom(f));>ifR:-isone(g)then>f>else>a:=R:-quo(numer(f),g);>b:=R:-quo(denom(f),g);>make(a,b)>endif>endproc;>`-`:=f->normal(R:-`-`(numer(f)),denom(f));>`/`:=f->normal(make(denom(f),numer(f)));>`+`:=proc(a,b)>use`+`=R:-`+`,`*`=R:-`*`in>normal(make(numer(a)*denom(b)>+denom(a)*numer(b),>denom(a)*denom(b)))>enduse>endproc;>`*`:=proc(a,b)>use`*`=R:-`*`in>normal(make(numer(a)*numer(b),>denom(a)*denom(b)))>enduse>endproc;>endmodule>endproc:Note:ThesourcecodeforQuotientField.mplisavailableinthesamples/AdvPGdirectoryofyourMapleinstallation.Mostoftheexportedroutinesarestraightforward.Thefractioncon-structormakeacceptstwomembersoftheringRasargumentsandreturnstheconstructedfraction,whichisrepresentedbyanunevaluatedfunctioncalloftheformFRACTION(numerator,denominator)Theexportedprocedureembedisthecanonicalembedding±oftheinte-graldomainintoitsquotientßeld,describedpreviously.Thismakestheconstructorfunctorial.Thearithmeticoperatorsaresimpleimplementa-tionsofthefamiliarrulesforfractionarithmetic:acad+bc+=bdbd 2.6InterfacesandImplementations¯135acac¢=bdbd°a±1b=ba°±aa=bbAfterapplyingthesesimpleformulae,theresultisnormalizedbyusingacalltothelocalroutinenormal(notthetop-levelroutine:-normal).Thenormalroutinedoesmostoftheinterestingworkintheringgeneratedbythisconstructor.ItusesthemanifestationofthedivisionalgorithmintheringRviatheexportedproceduresquoandgcdtoreduceeachfrac-tiontothelowestterms.Thefractionconstructormakeandthemethodnormalrepresentßeldelementsbythenormalformrepresentativeoftheappropriateequivalenceclass.Themakeroutinepreventsdivisionbyzero,andforcesdenominatorstobeunitnormalrepresentatives.Thenormalroutineensuresthatfractionsarereducedtolowestterms.ThemostimportantpropertyoftheQuotientFieldfunctoristhatitisgeneric.ItreliessolelyontheGcdRinginterface.NoknowledgeoftheconcreterepresentationoftheinputintegraldomainR(otherthanthatitisamodulethatsatisßestherequiredinterface)isusedintheconstruction.Therefore,itworkswithanyimplementationoftheGcdRinginterfacethat:¯Implementsthecorrectsemanticsforitspublicoperations¯Satisßestheabstractconstraintthatitbeasoftwarerepresentationofanintegraldomain.(Thisconstraintisrequiredtoensurethatthearithmeticoperationsarewelldeßned.)ConstructingtheRationalsastheQuotientFieldofZToconstructthequotientringoftheringMapleIntegersdeßnedpreviously,proceedasfollows.>FF:=QuotientField(MapleIntegers);FF:=module()export`+`;`£`;``;`=`;zero;one;iszero;isone;make;numer;denom;normal;embed;descriptionÕaquotientßeldÔ;endmodule>type(FF,'Field'); 136¯Chapter2:ProgrammingwithModulestrue>a:=FF:-make(2,3);a:=FRACTION(2;3)>b:=FF:-make(2,4);b:=FRACTION(2;4)>useFFin>a+b;>a*b;>a/b>enduse;FRACTION(7;6)FRACTION(1;3)FRACTION(4;3)Note:Thisisacomplexrepresentationoftheßeldofrationalnumbers.TheQuotientFieldofthePolynomialRingQ[T]Toillustratethegenericqualityofthisconstructor,constructtheßeldQ[T]ofrationalfunctionsinasingleindeterminateTfromaconcreterepresentationofMaplerationalpolynomials.>MaplePoly:=module()>description"theringofrationalpolynomials";>export`+`,`*`,`-`,>zero,one,>iszero,isone,>gcd,unormal,>quo,rem;>`+`:=(a,b)->expand(a+b);>`*`:=(a,b)->expand(a*b);>`-`:=p->-p;>gcd:=(a,b)->:-gcd(a,b);>unormal:=proc(p)>locallc;>ifiszero(p)then>one,zero>else>uselc=lcoeff(p)in>lc,:-normal(p/lc) 2.6InterfacesandImplementations¯137>enduse>endif>endproc;>iszero:=p->Testzero(p);>isone:=p->Testzero(p-1);>zero:=0;>one:=1;>rem:=(a,b)->:-rem(a,b);>quo:=(a,b)->:-quo(a,b);>endmodule:TheunormalmethodproducestheleadingcoeácientandmonicassociateofagivenpolynomialinQ[T].Theremainingexportssimplycapturebuilt-inMapleoperationsonunivariaterationalpolynomials.>RR:=QuotientField(MaplePoly);RR:=module()export`+`;`£`;``;`=`;zero;one;iszero;isone;make;numer;denom;normal;embed;descriptionÕaquotientßeldÔ;endmodule>type(RR,'Field');trueTomakeprintedfractionsmorereadable,introducethefollowingex-tensiontotheprintcommand.>`print/FRACTION`:=(n,d)->sort(n)/sort(d):Finally,constructafewexamples,andtestthearithmetic.>a:=RR:-make(randpoly('T','degree'=4,'terms'=3),>randpoly('T','degree'=4,'terms'=3));2072T21960T+5432a:=79T3+T2+88>b:=RR:-make(randpoly('T','degree'=4,'terms'=3),>randpoly('T','degree'=4,'terms'=3));2790T3+496T2+5766b:=7733T2T6231 138¯Chapter2:ProgrammingwithModules>useRRin>a+b;>a*b;>a/b>enduse;7781401827(2790T6T51638T4+T34124¾194371514445287333+T2T+)(124311249110676693297T5T4T3+T2T)24849631496248(5780880T5+4440688T416127440T39252880T211301360T+31320912)=(9110676693297T5T4T3+T2T)24849631496248(5780880T41711080T328100520T2+13000680T+16133040)=(251711324193T6+T5T4T3T2)3604512012040AGenericGroupImplementationThissectionillustrateshowtodevelopamoderatelycomplexsoftwaresystembyusingfeaturesoftheMaplemodulesystem.Genericprogram-mingisattheheartofthedesign.Onlyafractionofthecompletesystemfromwhichtheexamplesaretakenisshown.Asystemforcomputingwithßnitegroupscomprisestheexamplesthatfollow.Recallthatagroupisasetofobjectstogetherwithanassociativebinaryoperation,forwhichthereisanuniquetwo-sidedidentityelement,andwithrespecttowhicheachmemberoftheunderlyingsetpossessesanuniqueinverse.Examplesofgroupsinclude:¯Systemsofnumbers,usingaddition¯Closedsetsofinvertiblematrices(allofthesamesize,withacommongroundßeld),usingmultiplication(lineargroups)¯Closedsetsofpermutations(bijectivemappingsonaset),usingcom-position(permutationgroups)¯GroupsofpointsonellipticcurvesOnlyßnitegroupsarediscussed. 2.6InterfacesandImplementations¯139Table2.3AbstractGroupMethodsidReturnsthegroupidentity`.`Performsthebinaryoperationonthegroupmuln-aryversionof`.`invPerformstheunaryinversionoperationpowComputesintegralpowersofgroupelementseqTestswhethertwogroupelementsareequalmemberTestsmembershipinthegroupandinsetsgensReturnsageneratingsetforthegrouporderReturnstheorderofthegroupelementsReturnsanenumerationofthegroup'smembersAnInterfaceforFiniteGroupsFirst,youmustdecidehowtorepresentthegenericgroupinterface.Thisisdeterminedbytheproposeduseofthegroupobjects.Onceagain,thedesigntakesagrouptobearepositoryofdataandcomputationalservicesthatyoucanqueryorinvoke.TheGroupsignatureusedintheexamplesdescribesacomputationalmodelofabstractgroupsthatsupportsthemethodsinTable2.3.>`type/Group`:='`module`(>id,`.`,mul,inv,>eq,member,>gens,>order,elements>)':AcorrespondingconstructorforgroupsiseasilywrittenusingtheRecordconstructorintroducedearlier.Fortheexamplesinthissection,nodefaultmethodsareintroduced.>Group:=proc()>Record(op(`type/Group`));>endproc:Thisconstructordoesverylittleworkonitsown.Itreliesonmorespe-cializedconstructorstoestablishusefulvaluesordefaultsforthemethodsexported.Youcanwritegenericalgorithmsusingthisinterfaceimmediately.Afewsimpleexamplesaretheseroutinesforcomputingconjugatesandcommutatorsofgroupelements.Theconjugateofagroupmemberabyagroupmemberbisb1ab.ThisroutinecomputestheconjugateofanelementabyanelementbinagroupG.>Conjugate:=proc(G,a,b)>description"computetheconjugateofa">"groupelementbyanother"; 140¯Chapter2:ProgrammingwithModules>use`/`=G:-inv,`.`=G:-`.`in>b^(-1).a.b>enduse>endproc:Sincethegroupoperations`.`andinvinagenericgroupremainunas-signed,thefollowingcomputationisdonesymbolically.>Conjugate(Group(),'x','y');(inv(y)):x:ySimilarly,youcancomputethecommutator[a;b]=a(1)b(1)ab,generically,asfollows.>Commutator:=proc(G,a,b)>description"computethecommutatorof">"twogroupelements";>use`/`=G:-inv,mul=G:-mulin>mul(inv(a),inv(b),a,b)>enduse>endproc:Again,thiscomputationisdonesymbolically,sothegroupoperationsreturnunevaluated.>Commutator(Group(),'x','y');mul(inv(x);inv(y);x;y)Theabilitytowritegenericalgorithmsoveragiveninterfaceisim-portantforthemanagementoflargesoftwareprojectsinvolvingmanydevelopers.Onedevelopercanbeassignedthetaskofimplementingpar-ticulargroupconstructorsalongwiththeattendantarithmetic,whilean-otherdevelopercanbegincodinggenericroutines.Thetwodeveloperscanworkindependently,providedeachensuresthattheworkconformstosomeagreed-uponinterfaceandsemantics.PermutationGroupsBeforeattemptingtodevelopanycomplicatedal-gorithms,itishelpfultohaveafewconstructorsforspecißckindsofgroups.Thesecanthenbeusedtovalidategenericalgorithmsinspecißcinstances.Forthisreason,developastraightforwardimplementationofpermutationgroups.PermutationsarerepresentedusingMaplelists.Forexample,thelist[2,1,3]representsthepermutationthatmaps1!2,maps2!1,andleaves3ßxed.(Incyclenotation,thisiswrittenasthetransposition 2.6InterfacesandImplementations¯141(12).)Theconstructortakesapositiveintegerasitsßrstargument,indi-catingthedegreeofthepermutationgroup.Theremainingargumentsareexpectedtobepermutations(representedaslists)ofthestateddegree.Theseareusedtoformthegeneratingsetofthegroupreturnedbytheconstructor.>PermutationGroup:=proc(deg::posint)>description"permutationgroupconstructor";>localG,gens;>gens:={args[2..-1]};>G:=Group();>G:-id:=[$1..deg];>G:-`.`:=proc(a,b)>locali;>[seq(b[i],i=a)]>endproc;>G:-mul:=()->foldl(G:-`.`,G:-id,args);>G:-inv:=proc(g)>locali,a;>a:=array(1..deg);>forifrom1todegdo>a[g[i]]:=i>enddo;>[seq(a[i],i=1..deg)]>endproc;>G:-member:=proc(g,S,pos::name)>ifnargs=1then>type(g,'list(posint)')>and{op(g)}={$1..deg}>else>:-member(args)>endif>endproc;>G:-eq:=(a,b)->evalb(a=b);>G:-gens:=gens;>eval(G,1)>endproc:Forexample,toconstructthegrouph(12);(123)iinthesymmetricgroupS4,usethePermutationGroupconstructorasfollows.>G:=PermutationGroup(4,{[2,1,3,4],[2,3,1,4]});G:=module()exportid;`:`;mul;inv;eq;member;gens;order;elements;optionrecord;endmodule 142¯Chapter2:ProgrammingwithModulesTocomputewithitselements,usethemethodsexportedbythein-stantiatedgroupG.>useGin>inv([2,1,3,4]).[2,3,1,4];>enduse;[3;2;1;4]Itisusefultoprovidemorespecializedpermutationgroupcon-structorsforspecialkindsofgroups.UsingthegeneralconstructorPermutationGroup,andoverridingsomeoftheexportedmethods,youcandeßneseveralofthesespecializedconstructorsasfollows.ThefullsymmetricgroupSnonthenpointsf1;2;3;:::;ngispro-ducedbyspecifyingaparticularsetofgeneratorsforagivendegree(whichmustbespecißedasanargumenttotheconstructor).>Symmetric:=proc(n::posint)>description"symmetricgroupconstructor";>ifn<2then>error"argumentmustbeanintegerlargerthan1">elifn=2then>PermutationGroup(2,[2,1]);>else>PermutationGroup(n,[2,1,$3..n],[$2..n,1]);>endif>endproc:ThisusesthefactthatSnisthetwo-generatorgroupSn=h(12);(123¡¡¡n)i;foranyintegernµ3.Asecondspecialcaseistheclassofdihedralgroups.Thinkoftheseasthegroupsofsymmetriesofregularplanepolygons.Thesymmetrygroupoftheregularn-gonisthedihedralgroupofdegreenandorder2n;itisdenotedbyDn.D6(12)(123456) 2.6InterfacesandImplementations¯143Usethefollowingutilityforreversingtheorderofalist.>lreverse:=proc(L::list)>description"reversealist";>optioninline;>[seq(L[-i],i=1..nops(L))]>endproc:>Dihedral:=proc(n::posint)>description"dihedralgroupconstructor";>locala,b,D;>ifn=2orn=3then>returnSymmetric(n)>endif;>a:=[$2..n,1];>b:=[1,op(lreverse([$2..n]))];>D:=PermutationGroup(n,{a,b});>D:-order:=()->2*n;>eval(D,1)>endproc:Exercises1.UsethefactthatthealternatinggroupAnofdegreen>=3isgen-eratedbythesetf(123);(234);(345);:::;(n2;n1;n)gof3-cyclestowriteaconstructorAlternatingforthisclassofgroups.Dimino'sAlgorithmDimino'salgorithmisusedtocomputeacompleteenumerationoftheelementsofaßnitegroup,givenageneratingsetforthegroup.Supposethatyouaregivenageneratingsetfg1;g2;:::;gngforaßnitegroupG.TheideabehindDimino'salgorithmistoenumerate,successively,theelementsofeachofthesubgroupsGk=hg1;g2;:::;gkiofG,whichformachainhg1i=G1´G2´¡¡¡´Gk´¡¡¡´Gn=G:Theseelementscanbeenumeratedbyformingproductsofthegeneratorsg1;g2;:::;gninallpossibleways,untilalltheelementsofGhavebeenfound.Dimino'salgorithmdoesthisinacarefulway,avoidingunnecessaryproductcomputations.Usethefollowingutilityroutinetodeterminetheentriesassignedtoatable.Itcanbeusedwhenyouarecertainnoentryisanon-NULLex-pressionsequence.Sinceitissuácientlysimple,itisdeßnedwithoptioninline;. 144¯Chapter2:ProgrammingwithModules>Entries:=proc(T)>description"returnasetofsimpletableentries";>optioninline;>map(op,{entries(T)})>endproc:HereisthecodeforDimino'salgorithm.>Dimino:=proc(G::Group)>description"enumeratetheelementsofafinitegroup";>locals,g,ord,elements,i,j,prev_ord,rep_pos,>elt,addElt,gens;>>ifnargs>1then>gens:=args[2]>else>gens:=G:-gens>endif;>>ifnottype(gens,'{set,list}')then>error"nogeneratingsetspecified">endif;>>ifnops(gens)=0then>#trivialgroup>return{G:-id}>endif;>>addElt:=proc(h)>ord:=1+ord;>elements[ord]:=h>endproc;>>elements:=table();>ord:=0;>addElt(G:-id);>>#Handlethefirstcyclicsubgroup>s:=gens[1];>g:=s;>whilenotG:-eq(g,G:-id)do>addElt(g);>g:=G:-`.`(g,s)>enddo;>userinfo(1,'Dimino',"finishedfirstcycle;orderis:",ord);>>forifrom2tonops(gens)do>userinfo(1,'Dimino',"Addinggeneratornumber:",i);>s:=gens[i];>ifnotG:-member(s,Entries(elements))then>prev_ord:=ord;>addElt(s);>forjfrom2toprev_orddo>addElt(G:-`.`(elements[j],s)) 2.6InterfacesandImplementations¯145>enddo;>rep_pos:=1+prev_ord;>do>forsingens[1..i]do>elt:=G:-mul(elements[rep_pos],s);>ifnotG:-member(elt,Entries(elements))then>addElt(elt);>forjfrom2toprev_orddo>addElt(G:-`.`(elements[j],elt))>enddo>endif>enddo;>rep_pos:=rep_pos+prev_ord;>ifrep_pos>ordthen>break>endif>enddo>endif>enddo;>Entries(elements)>endproc:Thecodingofthisalgorithmisgeneric.TheexportedmembersofthegroupobjectGareusedtoeÞectcomputationswithintheprocedure.Evencomparisonsofequalityusetheexporteqinsteadofthebuilt-incomparisonoperator`=`.(Theneedforthisisillustratedbelow.)UsingtheSymmetricconstructorpreviouslydeßned,youcancomputetheelementsofthesymmetricgroupS4,usingDimino'salgorithm,asfollows.>G:=Symmetric(4);G:=module()exportid;`:`;mul;inv;eq;member;gens;order;elements;optionrecord;endmodule>Dimino(G);f[2;1;3;4];[2;3;1;4];[1;2;3;4];[3;2;1;4];[2;3;4;1];[3;2;4;1];[1;3;4;2];[3;1;4;2];[3;4;1;2];[4;3;1;2];[2;4;1;3];[4;2;1;3];[3;4;2;1];[4;3;2;1];[4;1;2;3];[1;4;2;3];[3;1;2;4];[1;3;2;4];[4;1;3;2];[1;4;3;2];[4;2;3;1];[2;4;3;1];[1;2;4;3];[2;1;4;3]g 146¯Chapter2:ProgrammingwithModulesAnticipatinglaterdevelopments,theprocedureDiminohasbeencodedtoacceptasecond,optionalargumentthatspecißesanalternatesetofgeneratorstouse.Thus,youcouldcomputethesamesetusingthesetf(12);(23);:::;(n1;n)goftranspositionsinstead.>Dimino(G,{[2,1,3,4],[1,3,2,4],[1,2,4,3]});f[2;1;3;4];[2;3;1;4];[1;2;3;4];[3;2;1;4];[2;3;4;1];[3;2;4;1];[1;3;4;2];[3;1;4;2];[3;4;1;2];[4;3;1;2];[2;4;1;3];[4;2;1;3];[3;4;2;1];[4;3;2;1];[4;1;2;3];[1;4;2;3];[3;1;2;4];[1;3;2;4];[4;1;3;2];[1;4;3;2];[4;2;3;1];[2;4;3;1];[1;2;4;3];[2;1;4;3]gYoustillneedtopassthegroupobjectGforDiminotoaccessitsoperations.Dimino'salgorithmisausefulfallbackalgorithm,butmanyßnitegroupsofinterestcanbeenumeratedmoreeácientlyusingspecißcknowl-edgeoftheirstructure.Forsmallexamples,theimplementationpresentedheresuáces,butawell-optimizedimplementationthattakesadvantageoffastarithmeticforgroupelementsisrequired.RepresentingSubgroupsAsubsetofagroupthatformsagroupforlargergroups(usingtheoperationsinheritedfromthegroup,byrestric-tion)iscalledasubgroup.Forexample,the3-membersetf(123);(132);(1)gisasubgroupofthefullsymmetricgroupS3ofdegree3(whichhas6members).Therearemanyapproachesforrepresentingofsubgroups.OnewayistorepresentasubgroupHofaknowngroupGbyspecifyingageneratingsetforHandcopyingthecomputationalservicesfromtherepresentationofGtotherepresentationofH.Thus,theMaplerepre-sentationsGandHofGandHwouldbothbeoftypeGroup.ThereisadiÞerentapproachthatisbettersuitedtoimplicitrepre-sentationsofsubgroups.Thisdesigncanbeextendedtoallowimplicitrepresentationsofsubgroupsthatyoudonotneedtocomputewithdi-rectly.Theideaistorepresentasubgroupbyasimplerstructurethatmaintainsalinktoitsparentgroupandanindicationofhowitisdeßnedintermsofitsparentgroup.Thus,asubgroupisrepresentedbyamodulewithanexportparentthatisassignedthegroupinwhichthesubgroupiscontained.Asecondexporthasanamedependinguponthewayinwhichthesubgroupisdeßned.Onewaytodeßneasubgroupintermsofitsparentistospecifyageneratingset.Subgroupsdeßnedinthiswayare 2.6InterfacesandImplementations¯147representedbyamodulehavingtheexportgensoftypeset.Asecondwaytodeßneasubgroupisbyaproperty.Forexample,thecenterofagroupisdeßnedbythepropertythatallitsmemberscommutewitheveryelementofthegroup(or,equivalently,thateachmemberofthesubgroupcommuteswithallthegeneratorsoftheparentgroup).Youcanspecifypropertiesbyusingaprocedurethattestsformembershipinthesubgroup.Thus,subgroupscanbedescribedbyeitherofthefollowinginterfaces.parentParentgrouptestMembershiptest(aprocedure)gensSetofgeneratorsOnlyoneofthemethodstestandgensneedbepresent.AMapleimplementationofthisinterfaceisasfollows.>`type/SubGroup`:='{>`module`(parent::Group,gens::set),>`module`(parent::Group,test::procedure)>}':TheSubGroupconstructormustdispatchonthetypeofitssecondargu-menttodeterminewhichkindofrecordtocreatetomodelthesubgroup.>SubGroup:=proc(G::{Group,SubGroup},how::{set,procedure})>description"subgroupconstructor";>localS;>iftype(how,'procedure')then>S:=Record('parent','test'=eval(how,1))>else>S:=Record('parent','gens'=how)>endif;>S:-parent:=G;>eval(S,1)>endproc:Forexample,thecenterofthesymmetricgroupS3canbedeßnedasfollows.>S3:=Symmetric(3):>Z:=SubGroup(S3,proc(z)>localg;>useS3in>forgingensdo>ifnoteq(mul(inv(g),inv(z),g),z)then>returnfalse>endif>enddo;>enduse;>true>endproc); 148¯Chapter2:ProgrammingwithModulesZ:=module()exportparent;test;optionrecord;endmodule>Z:-test([2,1,3]);false>Z:-test([2,3,1]);false>Z:-test([1,2,3]);trueSimilarly,youcanwriteaconstructorforthecentralizerofanelementinagroup.>Centralizer:=proc(G,g)>SubGroup(G,proc(s)>use`.`=G:-`.`,`=`=G:-eqin>s.g=g.s>enduseendproc)>endproc:GenericInterfacesDimino'salgorithmisrelativelyslow.Formanyclassesofgroups,therearebetteralternativesforenumeratinggroupelements.UseDimino'salgorithmonlyasalastresort.TheadvantageofDimino'salgorithmisthatitworksforanyßnitegroup.Toprovideacleananduniforminterfacetotheenumerationfunctionality,youcandevelopafrontendprocedure,whichhidesthedetails,tochoosethebestavailablealgorithm.>GroupElements:=proc(G)>description"enumeratetheelementsofafinitegroup";>iftype(G,'Group')then>iftype(G:-elements,'set')then>G:-elements>eliftype(G:-elements,'procedure')then>G:-procedure()>else>G:-elements:=Dimino(G) 2.6InterfacesandImplementations¯149>endif>else>'procname'(args)>endif>endproc:Severalelementsofthedesignallowyoutotakeadvantageofstructuralknowledgetoimproveeáciency.Thisroutineßrstcheckswhethertheexportelementsofitsinputgroupisoftypeset.Ifitis,thenitistakentobeastoredenumerationofthegroupelementsandissimplyreturned.Otherwise,iftheexportelementsisaprocedure,thenitistakentobea(perhapsspecialized)routineforcomputingtherequestedenumeration.Finally,Dimino'salgorithmisusedasalastresortifnobetteralternativeisprovided.Asasimpleoptimization,theresultofDimino'salgorithmisstoredasanewvaluefortheelementsexportsothatitneedonlybecomputedonce.ProvidingtheGroupElementsinterfaceshieldstheuserfromneedingtoknowwhattheavailablealternativesareandhowtousethem.Anadditionalbeneßtofthedesignisthatitallowsyoutochangethealgo-rithmselectioncriteriaatanytime(tocorrectsoftwarefaults,ormakefunctionalorperformanceimprovements).Codeusingthisinterfaceneednotbemodißed,providedthattheroutinecontinuestohonoritscontract.EnumeratingElementsinSubgroupsOncetheelementsoftheparentgroupareknown,themembersofthesubgroupcanbecomputedusingacalltothebuilt-inMaplecommandselect.>select(C:-test,Dimino(G));Howbesttoenumeratetheelementsofasubgroupdependsuponhowitisdeßnedandwhatisknownabouttheparentgroup.TheprocedureSubGroupElementsthatfollowstakesasubgroupasargumentandat-temptstoßndtheoptimalwaytocomputetheelementsofthesubgroupfromamongtheavailablemethods.>SubGroupElements:=proc(S)>description"enumeratetheelementsof">"asubgroupofagroup";>localP;>P:=S;>whiletype(P,'SubGroup')do>P:=P:-parent>enddo;>iftype(P,'Group')then>ifmember(:-test,S)then>select(S:-test,GroupElements(P))>else>ASSERT(member(:-gens,S)); 150¯Chapter2:ProgrammingwithModules>Dimino(P,S:-gens)>endif>else>'procname'(args)>endif>endproc:>G:=Symmetric(4);G:=module()exportid;`:`;mul;inv;eq;member;gens;order;elements;optionrecord;endmodule>SubGroupElements(Centralizer(G,[1,3,2,4]));f[1;2;3;4];[4;3;2;1];[1;3;2;4];[4;2;3;1]gWithSubGroupElementsimplemented,itisagoodideatoextendGroupElementstoacceptsubgroupsalso,thusprovidingacommonin-terface.>GroupElements:=proc(G)>description"enumeratetheelementsofa">"grouporsubgroup";>iftype(G,'SubGroup')then>SubGroupElements(G)>eliftype(G,'Group')then>iftype(G:-elements,'set')then>G:-elements>eliftype(G:-elements,'procedure')then>G:-elements()>else>G:-elements:=Dimino(G)>endif>else>'procname'(args)>endif>endproc:ComputingtheOrderofaGroupAsyoucanenumerateallofagroup'selements,itisalwayspossibletodetermineitsorder.(Notethatthisisrarelythebestwaytodothis,however.)Inmanycases,itispossibletoprovidemuchbetterwaystocomputetheorderofagroup.Forinstance,thesymmetricgroupofdegreenhasorderequalton!,soitsorderexportcouldberedeßnedtocomputethisnumberinstead. 2.6InterfacesandImplementations¯151Agenericinterfacetocomputinggrouporders,inthesamespiritasGroupElementscanbewrittenasfollows.>GroupOrder:=proc(G)>description"computetheorderofafinitegroup";>iftype(G,'SubGroup')then>nops(GroupElements(G))>eliftype(G,'Group')then>iftype(G:-order,'posint')then>G:-order>eliftype(G:-elements,'set')then>G:-order:=nops(G:-elements)>eliftype(G:-order,'procedure')then>G:-order()>else>nops(GroupElements(G))>endif>else>'procname'(args)>endif>endproc:AswithGroupElements,thisroutinechecksthepossibleshortcutsthatmightbeavailableforagroup.Itbeginswiththosethatarelikelytoinvolvetheleastcomputationandprogressesthroughmorecostlyalter-natives.OnlyasalastresortdoestheprocedurecallGroupElementstocomputeafullenumerationofthegroupelementsonlytoreturntheirnumber.>G:=Symmetric(4);G:=module()exportid;`:`;mul;inv;eq;member;gens;order;elements;optionrecord;endmodule>C:=Centralizer(G,[1,3,2,4]);C:=module()exportparent;test;optionrecord;endmodule>GroupOrder(G); 152¯Chapter2:ProgrammingwithModules24>GroupOrder(C);4Notethat,whentheargumentGisneitheragroupnorasubgroup,theprocedureGroupElementsreturnsunevaluated.ThisallowsyoutoextendotherMapleoperations,suchasexpand,combineorsimplifytobeeÞec-tiveonalgebraicexpressionsinvolvingunevaluatedcallstoGroupOrder.MatrixGroupsSofar,allthegroupshavebeenpermutationgroupsreturnedbyoneoftheconstructorspreviouslypresented.Youmusttestthecodeonsomeotherkindsofgroups.Agoodsourceforexamplesofßnitegroupsaretheßnitegroupsofexactmatrices.EqualityandMembershipTestsforMatricesBecausedistinctmatri-ceswithequalentriescomparediÞerentlyusingtheMapleequalitycom-parisonoperator`=`,itisnecessarytoimplementaspecializedtestformembershipinaset.Forexample,considerthematrices>A:=Matrix([[1,0],[0,1]]);´µ10A:=01>B:=Matrix([[2,3],[3,4]]);´µ23B:=34>C:=Matrix([[1,0],[0,1]]);´µ10C:=01BothAandChavethesameentries,andrepresentmathematicallyidenticalobjects.However,becausematricesaremutabledatastructures(necessaryforeáciencyinmatrixcomputations),theyaredistinctasMapleobjects.Thus,forinstance: 2.6InterfacesandImplementations¯153>member(A,{B,C});falseTodealwiththispropertyofthesedatastructures,youmustimple-mentagenericversionoftheMaplecommandmember.Thegmemberroutineacceptsargumentslikethoserequiredbythememberroutineinadditiontotheßrstargument,whichspecißesanequalitytest.Thisutilityisusedinthefollowingimplementationofthematrixgroupconstructor.>gmember:=proc(test,g::anything,S::{set,list},pos::name)>description"agenericmembershippredicate";>locali;>iftype(test,'procedure')then>forifrom1tonops(S)do>iftest(g,S[i])then>ifnargs>3then>pos:=i>endif;>returntrue>endif>enddo;>false>eliftest='`=`'then>#usethestandardmembershiptest>:-member(args[2..-1])>else>'procname'(args)>endif>endproc:Thebuilt-inprocedureEqualintheLinearAlgebrapackageprovidesanequalitypredicatethatissuitableforusewithmatrices.>gmember(LinearAlgebra:-Equal,A,{B,C});trueTheMatrixGroupConstructorExceptforthememberexport,mostoftheexportedmethodsformatrixgroupssimplydelegatetotheappropri-ateroutineintheLinearAlgebrapackage.TheMatrixGroupconstructortakesthedegreenofthematrixgroupasitsßrstargumentand,ifgivenmorethanoneargument,takestheremainingonestobematricesthatformasetofgeneratorsforthegroup.>MatrixGroup:=proc(n::posint)>description"matrixgroupconstructor";>localmatgens,G;>useLinearAlgebrain 154¯Chapter2:ProgrammingwithModules>matgens:={args[2..-1]};>G:=Record(>'id'=Matrix(n,n,(i,j)->`if`(i=j,1,0)),>'`.`'=((a,b)->MatrixMatrixMultiply(a,b)),>'mul'=(()->foldl(G:-`.`,G:-id,args)),>'inv'=(m->MatrixInverse(m)),>'gens'=matgens,>'eq'=((a,b)->Equal(a,b)),>'member'=proc(g,S,pos::name)>locali,s;>ifnargs=1then>iftype(g,'Matrix(square)')then>evalb(Determinant(g)<>0)>else>false>endif>else>gmember(G:-eq,args)>endif>endproc,>'order','elements');>>ifnargs=1then>G:-order:=1;>G:-elements:={G:-id}>endif>enduse;>eval(G,1)>endproc:Here,thematrixgroupconstructorisusedtogenerateadihedralmatrixgroupoforder12.>theta:=Pi/3;1²:=¹3>a:=Matrix(2,2,[[0,1],[1,0]]);´µ01a:=10>b:=Matrix(2,2,>[[cos(theta),sin(theta)],>[-sin(theta),cos(theta)]]); 2.6InterfacesandImplementations¯155211p336227b:=451p1322>B:=MatrixGroup(2,a,b);B:=module()exportid;`:`;mul;inv;gens;eq;member;order;elements;optionrecord;endmodule>GroupElements(B);8211p321p13<´µ3´µ3016227106227;45;;45;:101p10111p33222221p13211p3211p333362276227622745;45;45;11p1p11p133322222221p1321p13211p3333´µ6227622762271045;45;45;;11p11p1p1013332222229´µ=0110;DirectProductsToenrichthesupplyofexamplegroupsthatyoucanuse,developaconstructorforthedirectproductof(two)groups.(Ex-tendingtheconstructortohandleanyßnitenumberofgroupsisstraight-forward,butcomplicatestheexpositionunnecessarily.)Directproductsareveryimportantinthestudyofßnitegroupsbecauseallßnitelygen-eratedabeliangroupspossessanuniquefactorizationasadirectproductofcyclicgroups.(Intheabeliantheory,directproductsareoftenreferredtoasdirectsums.) 156¯Chapter2:ProgrammingwithModulesThedirectproductoftwogroupsAandBisthegroupGwhoseelementsareallpairs(a;b),witha2Aandb2B.ThegroupproductinGisdeßnedby(a1;b1)¡(a2;b2)=(a1¡a2;b1¡b2).Theinverseofanelement(a;b)isthepair(a1;b1).Alltheoperationsaredeßnedcomponent-wise.Representtheelements(a;b)ofthedirectproductbytwo-elementlists.HereistheconstructorDirectProduct.>DirectProduct:=proc(A::Group,B::Group)>description"directproductconstructor";>localG,a,b;>iftype(A,'Group')andtype(B,'Group')then>G:=Group();>G:-id:=[A:-id,B:-id];>G:-`.`:=(u,v)->[A:-`.`(u[1],v[1]),>B:-`.`(u[2],v[2])];>G:-mul:=()->foldl(G:-`.`,G:-id,args);>G:-inv:=v->[A:-inv(v[1]),>B:-inv(v[2])];>G:-gens:=[seq(seq([a,b],>a=A:-gens),b=B:-gens)];>G:-eq:=(u,v)->A:-eq(u[1],v[1])>andB:-eq(u[2],v[2]);>G:-order:=()->GroupOrder(A)*GroupOrder(B);>G:-member:=proc(g,S,pos::name)>ifnargs=1then>A:-member(g[1])>andB:-member(g[2])>else>gmember(G:-eq,args)>endif>endproc;>G:-elements:=()->[seq(seq([a,b],>a=GroupElements(A)),b=GroupElements(B))];>eval(G,1)>else>'procname'(args)>endif>endproc:Mostofthegroupmethodsarestraightforward,butusetheknowngroupstructuretoreducethecomplexityofsomecomputationssuchasthosefortheorderandelementsexports.>A:=Symmetric(3):>G:=DirectProduct(A,B):>GroupOrder(G);72>nops(GroupElements(G)); 2.6InterfacesandImplementations¯157Table2.4HomomorphismInterfacedomainDomainofthehomomorphismcodomainCodomainofthehomomorphismgenmapMappingofthegeneratorsofthedomainintothecodomain72HomomorphismsInallalgebraictheories,homomorphismsplayakeyrole.Agrouphomomorphismisamappingfromagrouptoanother(possiblythesame)groupwhichcommuteswiththegroupoperations.Thatis,amap':A!BofgroupsAandBisahomomorphismif'(ab)='(a)'(b),forallaandbinA.AhomomorphismisdetermineduniquelybyitseÞectonageneratingsetforitsdomain,sotodeßneahomomorphism,itisenoughtospecifytheimagesofeachamongasetofgeneratorsforthedomain.UsetheinterfaceinTable2.4forhomomorphisms.Thisleadsdirectlytoasimpleconstructorforhomomorphismobjects.>`type/Homomorphism`:='`module`(domain,codomain,genmap)':>Homomorphism:=proc(A::Group,B::Group,p::procedure)>description"homomorphismconstructor";>Record('domain'=A,'codomain'=B,'genmap'=p)>endproc:Theimageofagrouphomomorphism':A!Bisthesubset'(A)ofBconsistingofallelementsofBhavingtheform'(a),forsomeelementainA.ItisasubgroupofB.Thesevariousdesignchoicesleadtoasimpleformulationforcomputingorrepresentingimagesofhomomorphisms.>HomImage:=proc(hom::Homomorphism)>description"computetheimageofahomomorphism";>SubGroup(hom:-codomain,>map(hom:-genmap,hom:-domain:-gens))>endproc:Asanexamplecomputation,computetheimageofahomomorphismfromthesymmetricgroupS4ontoatwo-elementmatrixgroupgeneratedbythereàection>Matrix([[0,1],[1,0]]);´µ0110First,deßnethegroups. 158¯Chapter2:ProgrammingwithModules>A:=Symmetric(4):>B:=MatrixGroup(2,Matrix([[0,1],[1,0]])):DeßneamappingfromthegeneratorsofAtothegroupBbyinsertingtheimagesofthegeneratorsintoaprocedure'sremembertable.>h([2,1,3,4]):=Matrix([[0,1],[1,0]]):>h([2,3,4,1]):=Matrix([[1,0],[0,1]]):ThisdeßnesaMapleprocedurehthatperformstheindicatedmappingandreturnsunevaluatedforanyotherarguments.>eval(h);proc()optionremember;'procname(args)'endprocUseA,Bandhtoconstructthehomomorphismobject.>hom:=Homomorphism(A,B,h);hom:=module()exportdomain;codomain;genmap;optionrecord;endmodule>type(hom,'Homomorphism');trueUsethemachinerydevelopedearlierinthisexampletocomputetheorderoftheimageofthishomomorphism.>GroupOrder(HomImage(hom));2Thus,thehomomorphismissurjective(asexpected).Youcancom-putetheelementsexplicitly.>GroupElements(B);´µ´µ0110f;g1001>GroupElements(HomImage(hom)); 2.7ExtendedExample:ASearchEngine¯159´µ´µ1001f;g0110Exercises1.Anautomorphism«ofagroupGiscalledinnerifthereisanelementainGforwhich«(g)=a1ga,forallginG.Writeaconstructorforinnerautomorphismsofgroups.SummaryWithgenericprogrammingyouneedonlyimplementcompu-tationinquotientßeldsorgroupsonceÜintheconstructorsandgenericprocedures.ThefunctorQuotientFieldandthevariousgenericgroupconstructorsandproceduresareparameterizedbythecomputationaldo-mainsuponwhichtheircomputedvaluesdepend.Rings,ßelds,groups,andsubgroupsarecollectionsofcomputationalcapabilities,whichyouusetoconstructnewinstanceswithderivedcomputationalcapabilities.Overridingdefaultmethods(whichmaynotbeeácient,butarealwayspresent)withmethodsthattakeadvantageofspecißcstructuralinforma-tionallowsforeácientcomputationwithoutsacrißcinggenerality.Thisleadstoapowerfulparadigmforsoftwarereuse,andistheprincipalmo-tivationunderlyingtheMaplemodulesystem.2.7ExtendedExample:ASearchEngineSearchenginesareusedinavarietyofcontextstolocatedocumentsthatmatchorsatisfyaquery.QueriesconsistofsequencesofsearchtermsÛwordsthataremeanttoprescribethesubjectmatterofmatchingdocuments.ExamplesofsearchenginesincludeWebsearchenginesanddatabaseinterfaces.However,searchenginescanbeadaptedtosearchawidevarietyofstructuredorunstructureddata.Thisexampleillustrateshowasimplesearchengine,basedonthevec-torspacemodel,canbeconstructedusingMaple.VariousMaplepackagesareusedtopre-andpost-processthedatatobesearched,aswellasthequeries,andtheLinearAlgebrapackageisusedtoeÞectthecomputa-tionsnecessarytolocaterelevantdocuments.IntroductiontoSearchingPrototypically,adocumentisaßleofstructuredorunstructuredtext,butthissectiontreatsdocumentsasabstractdataitems.Adocumentcanbe 160¯Chapter2:ProgrammingwithModulesascientißcarticleinLaTeXformat,awebpage,anintegralformula,animage,orasimplestringoftext,asusedhereforillustrativepurposes.Thedocumentisarawpieceofdatathatcanbeidentißedasawhole.EachdocumentisequippedwithadocumentID,thatis,anidentißerthatisusedasahandleforthedocumentdata.ThedocumentIDissmall,whilethedocument(containingdata)maybearbitrarilylarge.Forsearching,documentsareorganizedintocorpora.Acorpusisacollectionofdocumentsthatcanbesearchedcollectivelyusingsearchterms.Aqueryisalistofsearchterms.Asearchtermistypicallya(naturallanguage)wordorphrase.Thepurposeofasearchistoidentify,amongdocumentsinagivencorpus,thosewhichmatchthesearchterms.Thus,searchinputconsistsofacorpustosearch,andoneormoresearchterms.Theoutputisarankedlistofdocumentsthatthesearchcriteriajudgetoberelevanttothesearchterms.Forthisexample,considerthefollowingsimplecorpusofdocuments.Eachdocumentisashortstringoftext,whichservesasboththedocumentIDandthedocumentdata.>doc1:="Themathematician'spatterns,likethepainter's">"orthepoet'smustbebeautiful;theideas,like">"thecolorsorthewordsmustfittogetherina">"harmoniousway.Beautyisthefirsttest:there">"isnopermanentplaceinthisworld">"foruglymathematics.":#Hardy>doc2:="Goddoesarithmetic.":#KarlFriedrichGauss>doc3:="Anyonewhocannotcopewithmathematicsisnot">"fullyhuman.Atbestheisatolerablesubhuman">"whohaslearnedtowearshoes,bathe,andnotmake">"messesinthehouse.":#RobertA.Heinlein>doc4:="Thingsshouldbemadeassimpleaspossible,">"butnosimpler.":>doc5:="Idon'tbelieveinmathematics.":>doc6:="Imaginationismoreimportantthanknowledge.":>doc7:="Themostbeautifulthingwecanexperienceis">"themysterious.Itisthesourceofalltrue">"artandscience.":>doc8:="Commonsenseisthecollectionofprejudices">"acquiredbyageeighteen.":>doc9:="Goddoesnotcareaboutourmathematical">"difficulties.Heintegratesempirically.":#A.EinsteinThecorpusconsistsofthesedocuments.Tofacilitatesearches,thecorpusispreprocessedtoconstructasearchindex.Theindexaidssearchesbymakingiteasytoquicklylocatedocumentsinthecorpusthatarerelevanttooneormoreofthesearchtermsinaquery. 2.7ExtendedExample:ASearchEngine¯161InvertedTermOccurrenceIndexingAninvertedtermoccurrenceindexisasimplesearchindex.Aninvertedtermoccurrenceindexconstructsalistofallthepotentialsearchtermspresentinthecorpusandmaintainsalistofthedocumentsinwhicheachsearchtermoccurs.Constructionofaninvertedtermoccurrenceindexbeginsbyconstructingadocument-termmapping.Forsimpletextstrings,constructalistofdocumenttermsasfollows.>DocumentTerms:=proc(text::string)>StringTools:-Words(text)>endproc:>DocumentTerms(doc1);[ÕTheÔ;Õmathematician'sÔ;ÕpatternsÔ;ÕlikeÔ;ÕtheÔ;Õpainter'sÔ;ÕorÔ;ÕtheÔ;Õpoet'sÔ;ÕmustÔ;ÕbeÔ;ÕbeautifulÔ;ÕtheÔ;ÕideasÔ;ÕlikeÔ;ÕtheÔ;ÕcolorsÔ;ÕorÔ;ÕtheÔ;ÕwordsÔ;ÕmustÔ;ÕßtÔ;ÕtogetherÔ;ÕinÔ;ÕaÔ;ÕharmoniousÔ;ÕwayÔ;ÕBeautyÔ;ÕisÔ;ÕtheÔ;ÕßrstÔ;ÕtestÔ;ÕthereÔ;ÕisÔ;ÕnoÔ;ÕpermanentÔ;ÕplaceÔ;ÕinÔ;ÕthisÔ;ÕworldÔ;ÕforÔ;ÕuglyÔ;ÕmathematicsÔ]Usingthis,constructaninvertedtermoccurrenceindex.>BuildIndex:=proc(corpus::list(string))>localdocterms,corpusterms,index,term,doc;>useStringToolsin>#Constructalltermsinthecorpus>docterms:=table([seq](doc=DocumentTerms(doc),>doc=corpus));>corpusterms:=`union`(seq({op}(docterms[doc]),>doc=corpus));>#Mapeachtermtothedocumentscontainingit>index:=table();>fordocincorpusdo>fortermindocterms[doc]do>ifassigned(index[term])then>index[term]:=index[term]union{doc}>else>index[term]:={doc}>endif>enddo>enddo>enduse;>#Returnthetable>eval(index,1)>endproc:>Index:=BuildIndex([doc||($1..9)]):>nops({indices}(Index)); 162¯Chapter2:ProgrammingwithModules104Searchingissimple,usingthisindex.SearchforthetermsÕmathe-maticalÔandÕbeautyÔ.>Search:=proc(query::list(string))>globalIndex;>localresults,term;>results:={};>forterminquerydo>ifassigned(Index[term])then>results:=resultsunionIndex[term]>endif>enddo;>results>endproc:>Search(["mathematical","beauty"]);fÕGoddoesnotcareaboutourmathematicaldiÞniculties.Heintegratesempirically.Ôg>nops(%);1Thereareseveralproblemswiththisindex.Oneproblemisthattheindexisquitelarge(relativetothesizeofthecorpus).Manywordsthatoccurinthecorpusconveylittleornoinformationaboutthecontentofthedocumentsinwhichtheyoccur.Thiscanleadtoirrelevantresults,especiallyforpoorlychosensearchterms.>nops(Search(["the"]));4Thisproblemcanbesolvedbyremovingunimportanttermsfromtheindex.Thissetofunwantedtermsiscalledastoplist.>STOP_WORDS:={"a","i","an","the","in","to",>"which","that","is","and","we","it","of",>"all","can","does","don't","most","true",>"thing"}:Asecondproblemissynonymyinthecorpus.Thatis,manydistincttermsinthecorpushavethesamemeaninginthecontextofsearching.Forexample,searchingforthetermÕmathematicsÔshouldreturndocuments 2.7ExtendedExample:ASearchEngine¯163thatcontainthetermsÕmathematicalÔ,ÕmathÔandÕmathematicallyÔ,eveniftheexacttermÕmathematicsÔdoesnotoccurinthedocument.Tosolvethisproblem,mapeachtermontoitsstem,orrootterm.ToimplementthesechangesintheDocumentTermsprocedure,usetheStringToolspackage.>DocumentTerms:=proc(text::string)>globalSTOP_WORDS;>localwords;>useStringToolsin>words:=map(LowerCase,Words(text));>words:=remove(type,words,STOP_WORDS);>map(Stem,words)>enduse>endproc:ByusingtheLowerCasefunction,casedistinctionsareremoved,makingtheprocessmoreeácient.Applythesamepreprocessingtosearchterms:converttolowercase,removestoplistwords,andmapwordsontotheirstems.>Search:=proc(query::list(string))>globalIndex;>localresults,term,terms;>useStringToolsin>terms:=map(LowerCase,query);>terms:=remove(type,terms,STOP_WORDS);>terms:=map(Stem,terms)>enduse;>results:={};>fortermintermsdo>ifassigned(Index[term])then>results:=resultsunionIndex[term]>endif>enddo;>results>endproc:BecauseBuildIndexusesDocumentTerms,rebuildtheindex.>Index:=BuildIndex([doc||($1..9)]):>nops({indices}(Index));83Thishassubstantiallyreducedthesizeoftheindex.>Search(["the"]);fg 164¯Chapter2:ProgrammingwithModulesBecausethestopwordÕtheÔhasbeenremovedfromtheindex,itreturnsnomatches.ThisisalsoauserinterfaceenhancementbecausequeriescancontainstopwordswithoutaÞectingtheresults.>Search(["mathematical","beauty"]);fÕThemathematician'spatterns,likethepainter'nsorthepoet'smustbebeautiful;theideas,liketnhecolorsorthewordsmustßttogetherinaharnmoniousway.Beautyistheßrsttest:thereisnonpermanentplaceinthisworldforuglymathemnatics.Ô;ÕAnyonewhocannotcopewithmathemnaticsisnotfullyhuman.Atbestheisatolerablnesubhumanwhohaslearnedtowearshoes,batnhe,andnotmakemessesinthehouse.Ô;ÕIdon'tbelieveinmathematics.Ô;ÕThemostbeanutifulthingwecanexperienceisthemysterious.nItisthesourceofalltrueartandscience.Ô;ÕGonddoesnotcareaboutourmathematicaldiácultnies.Heintegratesempirically.Ôg>nops(%);5Thenewprocessreturnsmanymoredocumentsrelevanttothequery.TheVectorSpaceModelItispossibletomodelthesearchbyusingavectorspacemodeloftheterm-documentindicesforcorpora.Aftercollectingtherelevantsearchtermsforacorpus,representeachdocumentbyavectorinaEuclideanspaceEn,wherenisthenumberofdistincttermsinthecorpus.Eachcoordinateinthisvectorspacerepresentsaterminthecorpus.Firstdetermineanorderingofthecorpusterms.ThenmapeachdocumenttoatermvectorinthisEuclideanspace.Asimplemappingistorepresentadocumentbyatermvectorwhoseithcoordinateisequalto1iftheithtermoccursinthedocument,andisequalto0otherwise.Foreachquery,constructatermvector.Thedotproductofthequerytermvectorwithadocumenttermvectoristhenumberofquerytermsthatappearinthe 2.7ExtendedExample:ASearchEngine¯165document.Adocumentcontainingmorequerytermsmightreasonablybejudgedmorerelevantthanonecontainingfewerqueryterms.Torankthedocuments,sortthedotproductsofthequerytermvectorwiththedocumenttermvectors.Forexample,considerasmallercorpuscomprisingonlythedocumentsdoc2,doc5,anddoc7.>SmallIndex:=BuildIndex([doc2,doc5,doc7]):Theorderedlistofcorpustermsis:>SmallCorpusTerms:=sort([op](map(op,{indices}(>SmallIndex))));SmallCorpusTerms:=[ÕarithmetÔ;ÕartÔ;ÕbeautiÔ;ÕbelievÔ;ÕexperiÔ;ÕgodÔ;ÕmathematÔ;ÕmysteriÔ;ÕsciencÔ;ÕsourcÔ]Note:Termsinthedocumentsarereplacedbytheirstemsandstopwordsareremovedfromtheindex.Thedocumenttermvectorcanbecomputedusingthefollowingprocedure.>DocumentTermVector:=proc(doc)>globalSmallCorpusTerms;>localterms;>terms:=DocumentTerms(doc);>Vector[row](1..nops(SmallCorpusTerms),>i->`if`(member(SmallCorpusTerms[i],terms),1,0))>endproc:>doc5Vector:=DocumentTermVector(doc5);doc5Vector:=[0;0;0;1;0;0;1;0;0;0]ComputethequerytermvectorforthesearchtermÕmathematicalbeautyÔ.>queryVector:=DocumentTermVector("mathematicalbeauty");queryVector:=[0;0;1;0;0;0;1;0;0;0]Theinnerproductis:>LinearAlgebra:-DotProduct(queryVector,doc5Vector);1 166¯Chapter2:ProgrammingwithModuleswhichindicatesthatoneofthequeryterms(correspondingtoÕmath-ematicalÔ)appearsinthedocument.Torankthedocumentsinthecorpusfortheirrelevancetothequery,applythisprocesstoeachdocumentinthecorpus.>useLinearAlgebrain>DotProduct(queryVector,DocumentTermVector(doc2));>DotProduct(queryVector,DocumentTermVector(doc5));>DotProduct(queryVector,DocumentTermVector(doc7));>enduse;011Itismoreeácienttorepresenttheentirecorpusbyaterm-documentmatrix,inwhichtherowsarethetermvectorsforthedocumentsinthecorpus.Firstdetermineaßxedorderingofthedocumentsinthecorpus.Thedotproductscanthenbecomputedbyformingtheproductoftheterm-documentmatrixrepresentingthecorpuswiththetermvectorforaquery.>TermDocumentMatrix:=Matrix(>map([s->s],map(DocumentTermVector,>[doc2,doc5,doc7])));TermDocumentMatrix:=2310000100004000100100050110100111>useLinearAlgebrain>Scores:=TermDocumentMatrix.Transpose(queryVector)>enduse;230Scores:=4151Thereisageometricinterpretationofthesearchprocess.Thedotproductoftwovectors,uandv,isrelatedtotheanglebetweenthevectors, 2.7ExtendedExample:ASearchEngine¯167forwhichthecosineisgivenbytheformula:hu;vi=(jjujj¡jjvjj):Considertheprojectionofthedocumenttermvectorsontothehyperplanedeßnedbythecomponentvectorsofthequeryvector,andthenintroduceappropriatescaling,usingvectornorms.Inthiscontext,searchingcanbeviewedasaprocessofdeterminingthosevectorsrepresentingdocumentsinacorpusforwhichtheanglebetweentheirprojectionsandthequeryvectorissmall.TermWeightingAdocumentthatcontainsmanyinstancesofagiventermisgenerallyconsideredtobemorerelevanttoqueriescontainingthattermthanadocumentwithfewerinstances.Toimproverankings,therefore,recordnotonlythepresenceofaterminadocument,butalsoitsfrequency.ThisisasimplechangetoDocumentTermMatrix.ThetermvectorofadocumentisthevectorofEnwhoseithentryisequaltothenumberoftimestheithcorpustermoccursinthedocument.>DocumentTermVector:=proc(doc)>globalSmallCorpusTerms;>localterms;>terms:=DocumentTerms(doc);>Vector[row](1..nops(SmallCorpusTerms),>i->numboccur(terms,SmallCorpusTerms[i]))>endproc:Thiscanleadtosignißcantlyimprovedresultswhensearchingalargercorpus.Toimprovethismethod,scalethenumberofinstancesbythesize(thetotalnumberoftermswithmultiplicities)ofthedocument.Forexample,abookaboutcatsisnotmorerelevantthanashortpaperoncatsmerelybecausethetermÕcatsÔappearsmoreofteninthebookthanintheshortarticle.>DocumentTermVector:=proc(doc)>globalSmallCorpusTerms;>localterms;>terms:=DocumentTerms(doc);>Vector[row](1..nops(SmallCorpusTerms),>i->evalf(numboccur(terms,SmallCorpusTerms[i])>/nops(terms)))>endproc:Withthischange,recomputetheterm-documentmatrixandthematrixofscores,whichrepresentsthesearchresults.Alsorecomputethequerytermvector. 168¯Chapter2:ProgrammingwithModules>TermDocumentMatrix:=Matrix(map([s->s],>map(DocumentTermVector,[doc2,doc5,doc7]))):>queryVector:=DocumentTermVector("mathematicalbeauty"):>useLinearAlgebrain>Scores:=TermDocumentMatrix.Transpose(queryVector)>enduse;230:Scores:=40:25000000000000000050:0833333333499999968Accordingtotheseresults,theseconddocumentinthecorpus(doc5)isthemostrelevanttothequery,followedbythethirddocument(doc7).Theßrstdocument(doc2)isjudgedtohavenorelevancetothequery.BuildingaSearchEnginePackageThenextstepistodesignasearchenginepackagethatincludesallthefeaturesdescribedtothispoint.Thesearchenginemustalsobeasgenericaspossible,andacceptavarietyofdocumentandtermtypes.Thepackagemanagestwokindsofdataobjects:documentsandcor-pora.Eachisrepresentedbyanobjectthatsupportscertainfeatures.Adocumentisabstractedasarecordobjectwiththreeslots.Theconstructoris:>Document:=proc(id,fetch,filter)>Record(>':-id'=id,>':-fetch'=fetch,>':-filter'=filter)>endproc:TheidslotisthedocumentID.ThedocumentIDmustuniquelyrepresentthedocumentwithinthecorpus.Foreáciency,documentIDsaresmall,whiletheirreferentsmaybequitelarge.Whileenormousdocumentscanbehandledinthedesign,forsimplicity,itisassumedthatanydocumentcanreasonablybereadintomemoryinitsentirety.Thefetchslotisaprocedurethatreturnsthebodyofadocument,givenitsdocumentID.Thefilterslotcontainsaprocedurethatgeneratesalistoftermsap-pearinginthedocument,withmultiplicities.Severalaccessorproceduresfordocumentsarealsoprovidedinthepackage.Acorpusisacollectionofdocuments.Itisrepresentedbyanobjectthatsupportsmethodsforaccessing,indexing,andsearchingthecollec-tion.>SearchEngine:=module()>description"asimplesearchengine"; 2.7ExtendedExample:ASearchEngine¯169>optionpackage;>export>Filters,#subpackageoffilters>Document,#documentconstructor>DocumentID,#accessorprocedure>FilterDocument,#accessorprocedure>FetchDocument,#accessorprocedure>Corpus,#corpusconstructor>NumberOfDocuments,#returnsnumberofdocumentsincorpus>BuildIndex,#indexacorpus>GetDocumentIdByIndex,#retrieveadocumentID>Search;#performasearch>local>documentTermVector,#constructdocumenttermvector>queryTermVector;#constructquerytermvector>>#Exports>>#Documentconstructor>Document:=proc(id,fetch,filter)>Record(>':-id'=id,>':-fetch'=fetch,>':-filter'=filter)>endproc;>>#Accessorroutinesfordocuments.>DocumentID:=doc->doc:-id;>FetchDocument:=doc->doc:-fetch(doc:-id);>FilterDocument:=doc->doc:-filter(FetchDocument(doc));>>#Corpusconstructor.Calledwitheitherasequenceof>#documentsoralistofdocumentIDs,afetcher,adocument>#filterroutine,andanoptionalqueryfilterroutine.>>Corpus:=proc(listOfIds::list,fetch,filter,_qfilter)>localdocs,qfilter;>>#Processarguments.>ifnargs=0then>error"expectingcorpusdescription">elifnargs>3then>#Allowthequeryfiltertobedifferent>#fromthedocumentfilter>qfilter:=eval(_qfilter,2)>else>#Ifqueryfilterisnotspecified,>#usethedocumentfilter.>qfilter:=eval(filter,2)>endif;>>#Constructlistofdocuments.>docs:=map(Document,listOfIds,fetch,filter);> 170¯Chapter2:ProgrammingwithModules>#Buildthecorpus.>module()>exportsearch,buildIndex,>numberOfDocuments,>getDocumentIdByIndex;>localids,corpusTerms,>documents,>term_document_matrix;>>ids:=listOfIds;>documents:=docs;>>numberOfDocuments:=()->nops(documents);>getDocumentIdByIndex:=proc(idx::posint)>ifidx<=numberOfDocuments()then>ids[idx]>else>error"therearefewerthan%1documentsinthecorpus",>idx>endif>endproc;>>buildIndex:=proc()>localdocterms;>#Constructcorpusterms.>docterms:=map(FilterDocument,documents);>corpusTerms:=sort([op](>`union`(op(map({op},docterms)))));>#Buildtheterm-documentmatrix.>term_document_matrix:=Matrix(map([s->s],>map(documentTermVector,docs,corpusTerms)),>'datatype'='float'[8],'storage'='sparse');>eval(thismodule,1)>endproc;>>search:=proc(query,numberOfResults::posint)>localqt,qv,scores;>ifnottype(term_document_matrix,'Matrix')then>error"corpusnotyetindexed">endif;>qt:=qfilter(query);>qv:=queryTermVector(qt,corpusTerms);>useLinearAlgebrain>scores:=Transpose(>MatrixVectorMultiply(>term_document_matrix,qv))>enduse>endproc;>endmodule>endproc;>>NumberOfDocuments:=corpus->corpus:-numberOfDocuments();>GetDocumentIdByIndex:=(corpus,idx)>->corpus:-getDocumentIdByIndex(idx); 2.7ExtendedExample:ASearchEngine¯171>BuildIndex:=corpus->corpus:-buildIndex();>Search:=(corpus,query)->corpus:-search(query);>>#Locals>documentTermVector:=proc(doc,corpusTerms::list)>localterms;>terms:=FilterDocument(doc);>Vector[row](1..nops(corpusTerms),>i->evalf(numboccur(terms,corpusTerms[i])>/nops(terms)),>'datatype'='float'[8],>'storage'='sparse')>endproc;>>queryTermVector:=proc(queryTerms::list,corpusTerms::list)>Vector[column](1..nops(corpusTerms),>i->evalf(numboccur(queryTerms,corpusTerms[i])>/nops(queryTerms)),>'datatype'='float'[8],>'storage'='sparse')>endproc;>>#Filterssubpackage>Filters:=module()>description"filtersubpackage";>optionpackage;>exportText;>localstopWords;>>stopWords:={"a","i","an","the","in","to",>"which","that","is","and","we","it","of",>"all","can","does","don't","most","true",>"thing"}:>>Text:=proc(text::string)>localwords;>useStringToolsin>words:=map(LowerCase,Words(text));>words:=remove(type,words,stopWords);>map(Stem,words)>enduse>endproc;>>endmodule;>>endmodule:>>with(SearchEngine):>corpus:=Corpus([doc||($1..9)],s->s,Filters:-Text):>NumberOfDocuments(corpus);9 172¯Chapter2:ProgrammingwithModules>GetDocumentIdByIndex(corpus,1);ÕThemathematician'spatterns,likethepainter'snorthepoet'smustbebeautiful;theideas,likethnecolorsorthewordsmustßttogetherinaharmnoniousway.Beautyistheßrsttest:thereisnopnermanentplaceinthisworldforuglymathematincs.Ô>BuildIndex(corpus):>Search(corpus,"mathematicalbeauty");[0:0483870967749999992;0:;0:0208333333349999990;0:;0:250000000000000000;0:;0:0833333333499999968;0:;0:0500000000000000028]LatentSemanticAnalysisThesimplevectorspacemodeldescribedpreviouslyhasshortcomings.SupposeausersearchesacorpusofdocumentsaboutpetsforthetermÕcatÔ.Thesimplevectorspacemodelsearchenginelocatesallthedocu-mentsthatcontainthetermÕcatÔ.However,thesearchenginedoesnotlocatedocumentsthatcontainthewordÕfelineÔ,butnotthewordÕcatÔ(oranytermforwhichthestemisÕcatÔ).ThisissueiscalledsynonymyÛtheproblemthatdistinctsearchtermsmayrepresentthesameconcept.Onewaytocircumventthisproblemistohaveahumandomainexpertpreparesearchtermlistsforeachdocumentinthecorpus.AlldocumentsreferringeithertoÕcatsÔorÕfelinesÔwouldcontainthesearchtermÕcatÔincludedintheirlistofsearchterms.Thissolutionis,however,veryex-pensive.Anautomaticindexingprocedureknownaslatentsemanticanalysis(LSA)helpstodiscoverrelationsbetweentermsanddocumentsthatarelatentinthecorpusbyanalyzingthecorpusasawhole.Theprocessisrelatedtofactoranalysis,andisessentiallyastatisticaltechnique,relyingheavilyonlinearalgebra.Whenusedtoprepareasearchindexforacorpus,LSAisreferredtoaslatentsemanticindexing(LSI).AthoroughdiscussionofLSIisbeyondthescopeofthismanual,soonlytheoperationaldetailsnecessarytoconstructtheSearchEnginepackagearediscussed. 2.7ExtendedExample:ASearchEngine¯173LSIcomputesalowerrankapproximationtotheterm-documentma-trix.Theapproximationiscomputedbyusingthesingularvaluedecom-positionoftheterm-documentmatrix.ThesingularvaluedecompositionofamatrixAisafactorization:A=U¡S¡VTwhereUandVarecolumnorthogonalmatrices,andSisadiagonalma-trixwhosediagonalentriesarearrangedindescendingorder.ThediagonalentriesofSarecalledthesingularvaluesofA,thecolumnsofUarecalledtheleftsingularvectorsofA,andthecolumnsofVarecalledtherightsingularvectorsofA.IfAisaterm-documentmatrix,thenthecolumnsofUcanbeinterpretedasanorthogonalbasisforthesemanticfactorsofterm-termcorrelationsbetweentermsinthecorpusrepresentedbyA,whilethecolumnsofVcanbeinterpretedasanorthogonalbasisforthesemanticfactorsofthecorrelationsbetweendocuments.Forlargecorpora,therankofSmaybeontheorderofafewthousand.ToobtainarankkapproximationofAthatisclosestintheleastsquaressense,choosearankksmallerthantherankofS(say,ontheorderofafewhundred),andformthematrix:A=U¡S¡VTkkkkwhereUkconsistsoftheßrstkcolumnsofU,VkconsistsoftheßrstkcolumnsofV,andSkistheßrstk¢ksubmatrixofS.WhenthematrixAisaterm-documentmatrix,itsapproximationAkisusedasasurrogatecorpusindexforsearching.ItcanbearguedthatthematrixAkisbetterabletodeterminecorrelationsbetweentermsinsuchawaythatsearchesusingitareabletoapproximateresultsobtainedbyhumanexpertindexing.Forexample,inacorpusonpets,somedocumentsmaycontainthetermÕcatÔ,othersthetermÕfelineÔ,andstillothersmaycontainbothterms.LSIplacesdocumentscontainingonlyoneofthesetermsclosertogetherinthelowerdimensionalprojectionbyvirtueoftheirco-occurrenceinsomeofthedocumentsinthecorpus.Inpractice,therankkchosenfortheapproximationisanempiricallydeterminedvalue,basedonthequalityofsearchresults.BecauseLSIisastatisticaltechnique,ingeneral,itproducesusefulresultsonlyforlargecorpora.TheSearchEnginePackageThissectionmodißestheSearchEnginepackagetoincorporateLSIwith-outchangingtheinterfacethatwasdesignedforthesimplerindexingscheme.Theupdatedpackagecontainsmoreßlterstoallowforagreatervarietyofcorpora. 174¯Chapter2:ProgrammingwithModules>SearchEngine:=module()>description"agenericsearchenginepackage";>optionpackage;>export>Filters,#subpackageoffilters>Document,#documentconstructor>DocumentID,>FilterDocument,>FetchDocument,>Corpus,#corpusconstructor>NumberOfDocuments,>BuildIndex,>GetDocumentIdByIndex,>Search;>local>Tools,#privatesubmodule>documentTermVector,>queryTermVector;>>#Exports>>#Documentconstructor>Document:=proc(id,fetch,filter)>description"documentconstructor";>Record(>':-id'=id,>':-fetch'=fetch,>':-filter'=filter)>endproc;>>#Documentaccessors.>DocumentID:=doc->doc:-id;>FetchDocument:=doc->doc:-fetch(doc:-id);>FilterDocument:=doc->doc:-filter(FetchDocument(doc));>>#Corpusconstructor.Calledwitheitherasequenceofdocuments,>#oralistofdocumentIDs,afetcherandadocumentfilter>#routine,andaqueryfilterroutine.>>Corpus:=proc(listOfIds::list,fetch,filter,_qfilter)>description"corpusconstructor";>localdocs,qfilter;>>#Processarguments.>ifnargs=0then>error"expectingcorpusdescription">elifnargs>3then>#Allowthequeryfiltertobedifferent>#thanthedocumentfilter>qfilter:=eval(_qfilter,2)>else>#Ifnotqueryfilterisspecified,>#usethedocumentfilter>qfilter:=eval(filter,2) 2.7ExtendedExample:ASearchEngine¯175>endif;>>#Constructlistofdocuments.>docs:=map(Document,listOfIds,fetch,filter);>>#Buildthecorpus.>module()>exportsearch,buildIndex,>numberOfDocuments,>getDocumentIdByIndex;>localids,corpusTerms,>documents,>term_document_matrix;>>#Initializeprivatedata.>ids:=listOfIds;>documents:=docs;>>#Accessormethods.>numberOfDocuments:=()->nops(docs);>getDocumentIdByIndex:=proc(idx::posint)>ifidx<=numberOfDocuments()then>ids[idx]>else>error"therearefewerthan%1documentsinthecorpus",>idx>endif>endproc;>>#Constructanindexbasedona_k-dimensionalapproximation>#totheterm-documentmatrix.>buildIndex:=proc(_k::posint)>localdocterms,k,u,s,v;>>#Constructcorpusterms.>docterms:=map(FilterDocument,documents);>corpusTerms:=sort([op](`union`(op(map({op},>docterms)))));>>#Buildtheterm-documentmatrix.>term_document_matrix:=Matrix(map([s->s],>map(documentTermVector,docs,corpusTerms)),>'datatype'='float'[8],'storage'='sparse');>>useLinearAlgebrain>u,s,v:=SingularValues(term_document_matrix,>'output'=[':-U',':-S',':-Vt']);>v:=Transpose(v);>ifnargs>0then>k:=_k>else>#Useadefaultifnodimensionprovided.>k:=floor(Rank(DiagonalMatrix(s))*0.7)>endif; 176¯Chapter2:ProgrammingwithModules>u:=u[1..-1,1..k];>v:=v[1..k,1..-1];>s:=DiagonalMatrix(s[1..k]);>#Replacetheterm-documentmatrixwithitsrank>#kapproximation>term_document_matrix:=MatrixMatrixMultiply(u,>MatrixMatrixMultiply(s,v))>enduse;>eval(thismodule,1)>endproc;>>search:=proc(query,numberOfResults::posint)>localqt,qv,scores;>ifnottype(term_document_matrix,'Matrix')then>error"corpusnotyetindexed">endif;>qt:=qfilter(query);>qv:=queryTermVector(qt,corpusTerms);>useLinearAlgebrain>scores:=Transpose(MatrixVectorMultiply(>term_document_matrix,qv));>Tools:-permSort(scores)>enduse>endproc;>endmodule>endproc;>>NumberOfDocuments:=corpus->corpus:-numberOfDocuments();>GetDocumentIdByIndex:=(corpus,idx)->>corpus:-getDocumentIdByIndex(idx);>BuildIndex:=(corpus,k)->`if`(nargs=1,>corpus:-buildIndex(),corpus:-buildIndex(k));>Search:=(corpus,query)->corpus:-search(query);>>#Locals>documentTermVector:=proc(doc,corpusTerms::list)>localterms,norm;>terms:=FilterDocument(doc);>Vector[row](1..nops(corpusTerms),>i->evalf(numboccur(terms,corpusTerms[i])/>nops(corpusTerms)),>'datatype'='float'[8],>'storage'='sparse')>endproc;>>queryTermVector:=proc(queryTerms::list,corpusTerms::list)>Vector[column](1..nops(corpusTerms),>i->evalf(numboccur(queryTerms,corpusTerms[i])/>nops(corpusTerms)),>'datatype'='float'[8],>'storage'='sparse')>endproc;>>#TheToolssubmodule 2.7ExtendedExample:ASearchEngine¯177>Tools:=module()>exportpermSort;>>permSort:=proc(V::Vector)>localpartition,quickSort,n,P,i;>>partition:=proc(a,lb,ub)>locali,j,k,v;>i,j,k:=lb,1+ub,lb;>v:=a[k];>whileii:=1+i;>whileii:=1+i>enddo;>j:=j-1;>whilea[j]>vdo>j:=j-1>enddo;>ifiP[i],P[j]:=P[j],P[i];>a[i],a[j]:=a[j],a[i]>endif>enddo;>P[k],P[j]:=P[j],P[k];>a[k],a[j]:=a[j],a[k];>j>endproc;>>quickSort:=proc(a,lb,ub)>localk;>iflbk:=partition(a,lb,ub);>procname(a,lb,k-1);>procname(a,k+1,ub)>endif;>a>endproc;>>n:=LinearAlgebra:-Dimensions(V);>P:=Array(1..n,[$1..n],'datatype'=>'integer[4]');>quickSort(V,1,n);>[seq](P[i],i=1..n)>endproc;>>endmodule;>>#TheFilterssubpackage>Filters:=module()>optionpackage;>exportText,XML,Maple,Worksheet;>localstopWords;> 178¯Chapter2:ProgrammingwithModules>stopWords:={>#The48mostcommonEnglishwords>"i","a","all","an","and","are",>"as","at","be","been","but","by",>"can","do","for","from","had","has",>"have","he","his","if","in","is",>"it","not","of","on","or","she",>"that","the","their","there","they","this",>"to","was","we","were","what","which",>"who","will","with","would","you",>#afewothers>"thing","true","most","does","don't",>NULL};>>Text:=proc(text::string)>description"computethetermsinatextstring";>localwords;>useStringToolsin>words:=map(LowerCase,Words(text));>words:=remove(type,words,stopWords);>map(Stem,words)>enduse>endproc;>>XML:=proc(xml)>description"computethetermsinanXMLdocument";>localt,count,rec;>>rec:=proc(xml,t::table)>localcm,texts,text,others;>useXMLToolsin>ifIsElement(xml)then>cm:=ContentModel(xml);>texts,others:=selectremove(IsText,cm);>fortextintextsdo>count:=1+count;>t[count]:=text>enddo;>map(procname,others,t)>endif>enduse>endproc;>count:=0;>t:=rec(xml,t)>[seq](t[i],i=1..count)>endproc;>>Maple:=proc(expr)>description"computethetermsinaMapleexpression";>localfns,terms,nocc;>fns:=[op](map2(op,0,indets(expr,'function')));>nocc:=map2(numboccur,expr,fns);>terms:=[seq]([seq(fns[i],j=1..nocc[i])],>i=1..nops(fns)); 2.7ExtendedExample:ASearchEngine¯179>sort(map(op,terms),'lexorder')>endproc;>>Worksheet:=proc(mws)>description"computethetermsinaworksheet";>localrec,wks,count,t,i;>>rec:=proc(x,t::table)>localcm,texts,text,others;>useXMLToolsin>ifIsElement(x)andElementName(x)="Text-field"then>cm:=ContentModel(x);>texts,others:=selectremove(IsText,cm);>fortextintextsdo>count:=1+count;>t[count]:=text>enddo;>map(procname,others,t)>elifnottype(x,'string')then>map(procname,args)>endif>enduse>endproc;>>useXMLToolsin>ifIsDocument(mws)then>wks:=select(IsElement,[op](mws));>ifnops(wks)=1then>wks:=wks[1]>else>error"ill-formedworksheet`%1'",fname>endif>endif>enduse;>>count:=0;>t:=table();>rec(wks,t);>t:=[seq](t[i],i=1..count);>>useXMLToolsin>t:=map(TextText,t);>t:=cat(op(t));>Filters:-Text(t)>enduse;>endproc;>>endmodule;>>endmodule:Therevisedpackagecontainsseveralnewdocumentßlters.Tousedoc-umentformatsthatarenotdirectlysupported,composetheseßlterswith 180¯Chapter2:ProgrammingwithModulescustomcode.Ratherthanprovidingavectorofrawscores,theSearchcommandinthepackagenowreturnsapermutationofthedocumentlistindicatingdocumentrankings.ThiscanbeuseddirectlywiththeGetDocumentIdByIndexroutine.UsingthePackageThepackagecanbeusedwithavarietyofcorpora.Thissubsectiondemon-stratestwoexamples.Theßrstisthecorpusofshorttextstringsusedpreviouslyinthissection.>with(SearchEngine):>corpus:=Corpus([doc||($1..9)],id->id,>Filters:-Text):>NumberOfDocuments(corpus);9>GetDocumentIdByIndex(corpus,1);ÕThemathematician'spatterns,likethepainter'snorthepoet'smustbebeautiful;theideas,likethnecolorsorthewordsmustßttogetherinaharmnoniousway.Beautyistheßrsttest:thereisnopnermanentplaceinthisworldforuglymathematincs.Ô>ranking:=Search(BuildIndex(corpus),>"mathematicalbeauty");ranking:=[1;3;5;6;2;7;9;8;4]>map2(GetDocumentIdByIndex,corpus,ranking[1..3]); 2.7ExtendedExample:ASearchEngine¯181[ÕThemathematician'spatterns,likethepainter'nsorthepoet'smustbebeautiful;theideas,liketnhecolorsorthewordsmustßttogetherinaharnmoniousway.Beautyistheßrsttest:thereisnonpermanentplaceinthisworldforuglymathemnatics.Ô;ÕAnyonewhocannotcopewithmathemnaticsisnotfullyhuman.Atbestheisatolerablnesubhumanwhohaslearnedtowearshoes,batnhe,andnotmakemessesinthehouse.Ô;ÕIdon'tbelieveinmathematics.Ô]Thesecondexamplecorpusisadatabaseofformulae.Theintentistobeabletolocateformulaerelevanttoasearchqueryconsistingoffunctionnames.Fortheformuladatabase,generatealistofidentitiesamongelementaryfunctionsusingtheFunctionAdvisorcommand.>Formulae:=map2(FunctionAdvisor,'identities',>FunctionAdvisor('elementary','quiet'),'quiet'):>Formulae:=map(op,sort(Formulae,'length')):>nops(Formulae);132UseeachformulaasboththedocumentanditsID.TheMapleßlterintheFilterssubpackageextractsthetermsfromeachdocument.>corpus2:=Corpus(Formulae,id->id,Filters:-Maple,>query->[op]({op}(query))):>BuildIndex(corpus2):Itispossibletolocateformulaerelevantto,forexample,thesinandcosfunctions.>ranking:=Search(corpus2,['sin','cos']); 182¯Chapter2:ProgrammingwithModulesranking:=[120;19;103;127;29;104;126;119;59;81;131;97;125;102;101;124;49;76;107;4;9;96;132;128;83;6;82;108;22;16;114;91;116;113;92;94;118;24;86;112;90;105;42;65;33;95;25;117;20;32;23;14;17;2;12;10;7;3;5;18;80;110;111;109;21;30;89;87;88;115;44;39;64;38;85;68;61;69;93;40;36;35;62;67;1;43;37;66;34;41;63;31;13;11;60;130;122;129;121;123;48;47;26;27;53;50;57;84;106;99;100;98;77;75;56;74;55;54;45;28;72;78;52;51;58;15;79;71;70;46;8;73]>map2(GetDocumentIdByIndex,corpus2,ranking[1..3]);21tan(z)6214tan(z)=2;12csc(arccsch(x)I+arccsch(y)I)41tan(z)211+(+)2x2y2y2x222=0;csc(arccsch(x)I+arccsch(y)I)2x2y2311tan(z)2127cot(z)=521tan(z)2ConstructasimilarcorpususingadiÞerentchoiceforthedocumentIDsandthefetcherroutinepassedtotheconstructor.InsteadofusingformulaeforboththedocumentanditsID,usethepositionoftheformulainthegloballistFormulaeasthedocumentID,andpassasuitablefetcherroutine.>corpus3:=Corpus([$1..nops(Formulae)],id->Formulae[>id],Filters:-Maple,query->[op]({op}(query))):>ranking:=Search(corpus2,['sin','cos']); 2.7ExtendedExample:ASearchEngine¯183ranking:=[120;19;103;127;29;104;126;119;59;81;131;97;125;102;101;124;49;76;107;4;9;96;132;128;83;6;82;108;22;16;114;91;116;113;92;94;118;24;86;112;90;105;42;65;33;95;25;117;20;32;23;14;17;2;12;10;7;3;5;18;80;110;111;109;21;30;89;87;88;115;44;39;64;38;85;68;61;69;93;40;36;35;62;67;1;43;37;66;34;41;63;31;13;11;60;130;122;129;121;123;48;47;26;27;53;50;57;84;106;99;100;98;77;75;56;74;55;54;45;28;72;78;52;51;58;15;79;71;70;46;8;73]Thecommonandpracticalcase,inwhichacorpusrepresentsacol-lectionofßlestobeindexed,canbehandledbyusingaconstructorcallsuchasthefollowing.>corpus:=Corpus(>remove(type,listdir("MyDocuments"),{".",".."}),>fname->readbytes(fname,'TEXT',infinity),>Filters:-Text):IfthedocumentscontainstructuredtextencodedasXML,thenasimilarinvocationcanbeused.>corpus:=Corpus(>remove(type,listdir("MyDocuments"),{".",".."}),>fname->XMLTools:-ParseFile(fname),Filters:-XML):Finally,adirectoryofMapleworksheetscanberepresentedbyacor-pusconstructedasfollows.>corpus:=Corpus(>remove(type,listdir("MyDocuments"),{".",".."}),>fname->Worksheet:-ReadFile(fname),Filters:-Worksheet>):AclientoftheSearchEnginepackagecanprovideaspecializedßlterroutinetobeusedinconstructingacorpusobjecttorepresentacollectionofdocumentsofaspecißctype.Genericinterfacesandcarefulhidingofrepresentationaldetailsprovideconsiderableclientàexibilityandtheabilitytoevolvetheimplementation. 184¯Chapter2:ProgrammingwithModules2.8ConclusionThischapterintroducedtheconceptofMaplemodules.Itdescribedthestructureandàexibilityofmodules.Encapsulationandgenericprogrammingwithmodulesallowyoutowritecodethatcanbereused,transported,andeasilymaintained.Bycollectingproceduresintoamodulecalledapackage,youcanorganizeproceduresintodistinctsetsofrelatedfunctions.YoucanalsousemodulestoimplementobjectsinMaple. 3InputandOutputAlthoughMapleisprimarilyasystemandlanguageforperformingmath-ematicalmanipulations,manysituationsarisewheresuchmanipulationsrequire:¯DataoriginatingoutsideMaple¯Outputofdatainaformacceptedbyotherapplications¯Inputdirectlyfromtheuser¯OutputpresenteddirectlytotheuserTheMaplesoftwareincludesacomprehensivecollectionofinputandoutput(I/O)commands.MapleI/Olibraryreferstothesecommandsasagroup.InThisChapter¯TutorialExample¯FileTypesandModes¯FileDescriptorsVersusFileNames¯FileManipulationCommands¯InputCommands¯OutputCommands¯ConversionCommands¯NotestoCProgrammers185 186¯Chapter3:InputandOutput3.1ATutorialExampleThissectionillustrateshowyoucanusetheMapleI/Olibrary.Speciß-cally,theexamplesshowhowtowriteatableofnumericaldatatoaßle,andhowtoreadsuchatablefromaßle.Theexamplesrefertothefollow-ingdataset,givenintheformofalistoflistsandassumedtorepresentalistof(x;y)pairs,whereeachxisanintegerandeachyisarealnumber.>A:=[[0,0],>[1,.8427007929],>[2,.9953222650],>[3,.9999779095],>[4,.9999999846],>[5,1.000000000]]:Inarealapplication,thislistisgeneratedbyaMaplecommandorpro-cedure.Inthisexample,thelistwassimplyenteredasabove.Ifyouwanttouseanotherprogram(likeapresentationgraphicspro-gram,orperhapsacustomCprogram)toprocessdatathatMaplehasgenerated,thenyouoftenneedtosavethedatatoaßleinaformatthattheotherprogramrecognizes.UsingtheI/Olibrary,youcanwritesuchdatatoaßle.>forxyinAdofprintf("myfile","%d%e ",xy[1],xy[2])>enddo:>fclose("myfile");Theßlemyfileissavedinthecurrentdirectory.Todeterminethecurrentdirectory,usethecurrentdir()command.Ifyouprinttheßlemyfile,orviewitwithatexteditor,itlookslikethis:00.000000e-0118.427008e-0129.953223e-0139.999779e-0141.000000e+0051.000000e+00Thefprintfcommandwriteseachpairofnumberstotheßle.Thiscom-mandtakestwoormorearguments.TheßrstargumentspecißestheßlethatMapleistowrite,andthesecondargumentspecißestheformatforthedataitems.TheremainingargumentsaretheactualdataitemsthatMapleistowrite.OpeningaFileIntheprecedingexample,theßlenameismyfile.Theßrsttimeagivenßlenameappearsasanargumenttofprintf(orany 3.1ATutorialExample¯187oftheotheroutputcommandsdescribedlater),thecommandcreatestheßleifitdoesnotalreadyexist,andprepares(opens)itforwriting.Iftheßleexists,thenewversionoverwritestheoldone.Youcanoverridethisbehavior(forexample,ifyouwanttoappendtoanalreadyexistingßle)byusingthefopencommand.Formoreinformationonthefopencommand,see3.4OpeningandClosingFiles.FormatStringTheformatstring,"%d%e ",specißesthatMaplewritethedataitemsasfollows:¯Firstdataitemasadecimalinteger(%d)¯SeconddataiteminFortran-likescientißcnotation(%e)¯Asinglespaceseparatestheßrstandseconddataitems¯Alinebreak( )followstheseconddataitem(towriteeachpairofnumbersonanewline)Bydefault,asintheexample,Mapleroundsàoating-pointnumberstosixsignißcantdigitsforoutput.Youcanspecifymoreorfewerdigitsbyusingoptionstothe%eformat.Thesectiononfprintfdescribestheseoptionsinmoredetail.ClosingaFileWhenyouareßnishedwritingtoaßle,youmustcloseit.Untilyoucloseaßle,thedatamaynotbeintheßle,becauseoutputisbuÞeredundermostoperatingsystems.Thefclosecommandclosesaßle.Ifyouforgettocloseaßle,Mapleautomaticallyclosesitwhenyouexit.OneCommandforOpening,Writing,andClosingaFileForasimplecaseliketheonepresentedhere,writingthedatatoaßlebyusingthewritedatacommandiseasier.>writedata("myfile2",A,[integer,float]):Thewritedatacommandperformsalltheoperationsofopeningtheßle,writingthedatainthespecißedformat(anintegerandaàoating-pointnumber)andthenclosingtheßle.However,writedatadoesnotprovidethepreciseformattingcontrolthatyoumayneedinsomecases.Forthis,usefprintf.ReadingDataFromaFileInsomeapplications,youneedtoreaddatafromaßle.Forexample,somedataacquisitionsoftwaresuppliesdatathatyouneedtoanalyze.Readingdatafromaßleisalmostaseasyaswritingtoit. 188¯Chapter3:InputandOutput>A:=[];A:=[]>do>xy:=fscanf("myfile2","%d%e");>ifxy=0thenbreakendif;>A:=[op(A),xy];>enddo;xy:=[0;0:]A:=[[0;0:]]xy:=[1;0:8427007929]A:=[[0;0:];[1;0:8427007929]]xy:=[2;0:995322265]A:=[[0;0:];[1;0:8427007929];[2;0:995322265]]xy:=[3;0:9999779095]A:=[[0;0:];[1;0:8427007929];[2;0:995322265];[3;0:9999779095]]xy:=[4;0:9999999846]A:=[[0;0:];[1;0:8427007929];[2;0:995322265];[3;0:9999779095];[4;0:9999999846]]xy:=[5;1:000000000]A:=[[0;0:];[1;0:8427007929];[2;0:995322265];[3;0:9999779095];[4;0:9999999846];[5;1:000000000]]xy:=[] 3.1ATutorialExample¯189A:=[[0;0:];[1;0:8427007929];[2;0:995322265];[3;0:9999779095];[4;0:9999999846];[5;1:000000000];[]]xy:=0>fclose("myfile2");ThisexamplestartsbyinitializingAtobetheemptylist.Uponenteringtheloop,Maplereadspairsofnumbersfromtheßle.Thefscanfcommandreadscharactersfromaspecißedßle,andparsesthemaccordingtothespecißedformat(inthiscase,"%d%e",indicatingadecimalintegerandarealnumber).Iteitherreturnsalistoftheresultingvaluesortheinteger0toindicatethatithasreachedtheendoftheßle.Theßrsttimeyoucallfscanfwithagivenßlename,Mapleprepares(opens)theßleforreading.Ifitdoesnotexist,Maplegeneratesanerror.Thesecondlineoftheloopchecksiffscanfreturned0toindicatetheendoftheßle,andbreakstheloopifithas.Otherwise,MapleappendsthepairofnumberstothelistofpairsinA.(ThesyntaxA:=[op(A),xy]tellsMapletoassigntoAalistconsistingoftheexistingelementsofA,andthenewelementxy.)OneCommandforOpening,Reading,andClosingaFileAswhenyouwritetoaßle,youcanreadfromaßlemoreeasilybyusingthereaddatacommand.>A:=readdata("myfile2",[integer,float]);A:=[[0;0:];[1;0:8427007929];[2;0:995322265];[3;0:9999779095];[4;0:9999999846];[5;1:000000000]]Thereaddatacommandperformsalltheoperationsofopeningtheßle,readingthedata,parsingthespecißedformat(anintegerandaàoating-pointnumber),andthenclosingtheßle.However,readdatadoesnotprovidethepreciseparsingcontrolthatyoumayneedinsomecases.Forthis,usefscanfdirectly.ThenextsectionexpandsonthebasicconceptsoftheMapleI/Olibrary. 190¯Chapter3:InputandOutput3.2FileTypesandModesMostoftheMapleI/Olibrarycommandsoperateonßles.Inthischapter,thetermßleisnotlimitedtoadiskßle.Itcanincludethedefaultoutputstreamtoaterminalorworksheetoutputregion.Almostanyoperationthatyoucanperformonarealßleyoucanperformonadataoutputstreamtotheterminalorworksheet.BuÞeredFilesversusUnbuÞeredFilesTheMapleI/Olibrarycanusetwoßletypes:buÞered(STREAM)andunbuÞered(RAW).Mapleusestheseßlessimilarly.BuÞeredFiles:¯WhenbuÞeringalotofI/O,buÞeredßleoperationsareusuallyfaster.¯MaplecollectscharactersinabuÞerandwritesthemtoaßlewhenthebuÞerisfullortheßleisclosed.(ChangesmadeinMaplemaynotappearondiskuntillater.)¯Ingeneral,youshouldusebuÞeredßles.TheyareusedbydefaultwithmostI/Olibrarycommands.RawFiles:¯Rawßlesareusefulwhenexaminingthepropertiesoftheunderlyingoperatingsystem,suchastheblocksizeonthedisk.IdentißersCommandsthatprovideinformationaboutI/OstatususetheidentißersSTREAMandRAWtoindicatebuÞeredandunbuÞeredßles,respectively.TextFilesversusBinaryFilesManyoperatingsystems,includingDOS/Windows•randtheMacintoshoperatingsystem(MacOS•r),distinguishbetweenßlescontainingse-quencesofcharacters(textßles)andßlescontainingsequencesofbytes(binaryßles).Thedistinctionliesprimarilyinthetreatmentofthenew-linecharacter.Otherdistinctionsmayexistonsomeplatforms,buttheyarenotvisiblewhenusingtheMapleI/Olibrary.WithinMaple,thenewlinecharacter,whichrepresentsendingonelineandbeginninganewone,isasinglecharacter(althoughyoucantypeitasthetwocharactersÕ ÔwithinMaplestrings).Theinternal 3.2FileTypesandModes¯191representationofthischaracteristhebytewhosevalueis10,theASCIIlinefeedcharacter.Manyoperatingsystems,however,representthecon-ceptofnewlinewithinaßleusingadiÞerentcharacter,orasequenceoftwocharacters.Forexample,DOS/Windowsrepresentsanewlinewithtwoconsecutivebyteswhosevaluesare13and10(carriagereturnandlinefeed).TheMacintoshrepresentsanewlinewiththesinglebytewithvalue13(carriagereturn).TheMapleI/Olibrarycanusetextßlesorbinaryßles.WhenMaplewritestoatextßle,anynewlinecharactersthatitwritestotheßlearetranslatedintotheappropriatecharacterorcharactersequencethattheunderlyingoperatingsystemuses.WhenMaplereadsthischaracterorcharactersequencefromaßle,ittranslatesittothesinglenewlinechar-acter.WhenMaplewritestoabinaryßle,notranslationtakesplace;itreadsnewlinecharactersandwritesthemasthesinglebytewithvalue10.WhenrunningMapleundertheUNIX•roperatingsystemoroneofitsmanyvariants,Maplemakesnodistinctionbetweentextandbinaryßles.Ittreatsbothinthesameway,andnotranslationtakesplace.IdentißersCommandsthatcanspecifyorquerywhetheraßleisatextßleorabinaryßleusetheidentißersTEXTandBINARY,respectively.ReadModeversusWriteModeAtanygiventime,aßlemaybeopeneitherforreadingorforwriting.¯Youcannotwritetoaßlethatisopenonlyforreading.Ifyouattempt,usingtheMapleI/Olibrary,towritetoaßlewhichisopenforreading,Mapleclosesandreopenstheßleforwriting.Iftheuserdoesnothavethenecessarypermissionstowritetotheßle(iftheßleisread-only,orresidesonaread-onlyßlesystem),errorsoccur.¯Youcanwritetoandreadfromaßlethatisopenforwriting.IdentißersCommandswhereyoucanspecifyorquerywhetheraßleisopenforreadingorwritingusetheidentißersREADandWRITE,respec-tively.ThedefaultandterminalFilesTheMapleI/OlibrarytreatstheMapleuserinterfaceasaßle.Theiden-tißersdefaultandterminalrefertothisßle.Thedefaultidentißerreferstothecurrentinputstream,theonefromwhichMaplereadsand 192¯Chapter3:InputandOutputprocessescommands.Theterminalidentißerreferstothetop-levelin-putstream,theonewhichwasthecurrentinputstreamwhenyoustartedMaple.WhenMapleisruninteractively,defaultandterminalareequiv-alent.Onlywhenreadingcommandsfromasourceßleusingthereadstatementdoesadistinctionarise.Inthatcase,defaultreferstotheßlebeingread;whereas,terminalreferstothesession.UnderUNIX,ifinputisredirectedfromaßleorpipe,terminalreferstothatßleorpipe.Notethatonlythesymbolsdefaultandterminalarespecial;thestrings"default"and"terminal"refertoßleswiththosenames.3.3FileDescriptorsversusFileNamesThecommandsoftheMapleI/Olibraryrefertoßlesinoneoftwoways:bynameorbydescriptor.NameReferringtoaßlebynameisthesimplerofthetwomethods.TheßrsttimeMapleperformsanoperationontheßle,itopenstheßle,eitherinREADmodeorinWRITEmodeandasaTEXTßleoraBINARYßle,asappropriatetotheoperationthatitisperforming.Theprimaryadvantageofreferringtoßlesbynameissimplicity.However,youwillexperienceaslightperformancepenaltyforusingthismethod,especiallyifperformingmanysmalloperationsonaßle(suchaswritingindividualcharacters).DescriptorReferringtoaßlebydescriptorisonlyslightlymorecomplexandisafamiliarconcepttothosewhohaveprogrammedinmoretradi-tionalenvironments.Adescriptorsimplyidentißesaßleafteryouhaveopenedit.Usethenameoftheßleoncetoopenitandcreateadescriptor.Whenyousubsequentlymanipulatetheßle,usethedescriptorinsteadoftheßlename.AnexampleinOpeningandClosingFilesonpage194illustratestheuseofaßledescriptor.Theadvantagesofthedescriptormethodincludemoreàexibilitywhenopeningtheßle(youcanspecifywhethertheßleisTEXTorBINARY,andwhetherMapleopensitinREADmodeorinWRITEmode),improvedeá-cencywhenperformingmanyoperationsonaßle,andtheabilitytoworkwithunbuÞeredßles.Thedisadvantageisaslightincreaseintheamountofprogrammingthatyoumustdo. 3.4FileManipulationCommands¯193BestApproachWhichapproachisbestdependsonthetaskathand.YoucanperformsimpleßleI/Otasksmosteasilybyusingnames,whereas,morecomplextaskscanbeneßtfromtheuseofdescriptors.Note:Insubsequentsections,thetermßleIdentißerreferstoaßlenameoraßledescriptor.3.4FileManipulationCommandsOpeningandClosingFilesBeforeyoucanreadfromorwritetoaßle,youmustopenit.Whenrefer-ringtoßlesbyname,thishappensautomaticallywiththeßrstattemptatanyßleoperation.Whenyouusedescriptors,however,youmustexplicitlyopentheßleßrsttocreatethedescriptor.Thetwocommandsforopeningßlesarefopenandopen.ThefopencommandopensbuÞered(STREAM)ßles,whereas,theopencommandopensunbuÞered(RAW)ßles.Usethefopencommandasfollows.fopen(fileName,accessMode,fileType)TheßleNamespecißesthenameoftheßletoopen.Thisnameisspecißedasastring,andfollowstheconventionsthattheunderlyingoperatingsystemuses.TheaccessModemustbeoneofREAD,WRITE,orAPPEND,indicatingwhetheryoushouldinitiallyopentheßleforreading,writing,orappending.TheoptionalßleTypeiseitherTEXTorBINARY.Ifyoutrytoopentheßleforreadinganditdoesnotexist,fopengeneratesanerror.Ifyoutrytoopentheßleforwritinganditdoesnotexist,Maplecreatesit.IfitdoesexistandyouspecifyWRITE,Mapletruncatestheßletozerolength;ifyouspecifyAPPEND,subsequentcallstocommandsthatwritetotheßleappendtoit.Calltheopencommandasfollows.open(fileName,accessMode)Theargumentstoopenarethesameasthosetofopen,exceptthatyoucannotspecifyaßleType(TEXTorBINARY).MapleopensanunbuÞeredßlewithtypeBINARY. 194¯Chapter3:InputandOutputBothfopenandopenreturnaßledescriptor.Usethisdescriptortorefertotheßleforsubsequentoperations.Youcanstillusetheßlename.Whenyouhaveßnishedwithaßle,instructMapletocloseit.Thisen-suresthatMaplewritesallinformationtothedisk.Italsofreesresourcesoftheunderlyingoperatingsystem,whichoftenimposesalimitonthenumberofßlesthatyoucanopensimultaneously.Closeßlesbyusingthefcloseorclosecommands.Thesetwocom-mandsareequivalent.Youcancallthemasfollows.fclose(fileIdentifier)close(fileIdentifier)TheßleIdentißeristhenameordescriptoroftheßletoclose.Onceyoucloseaßle,anydescriptorsreferringtotheßlearenolongervalid.>f:=fopen("testFile.txt",WRITE):>writeline(f,"Thisisatest"):>fclose(f);>writeline(f,"Thisisanothertest"):Error,(infprintf)filedescriptornotinuseWhenyouexitMapleorissuearestartcommand,Mapleautomaticallyclosesanyopenßles,whetheryouopenedthemexplicitlybyusingfopenoropen,orimplicitlythroughaßleI/Ocommand.PositionDeterminationandAdjustmentAssociatedwitheachopenßleistheconceptofitscurrentposition.Thisisthelocationwithintheßletowhichasubsequentwriteoccurs,orfromwhichasubsequentreadoccurs.Anyreadingorwritingoperationadvancesthepositionbythenumberofbytesreadorwritten.Youcandeterminethecurrentpositionwithinaßlebyusingthefileposcommand.Usethiscommandinthefollowingmanner.filepos(fileIdentifier,position)TheßleIdentißeristhenameordescriptoroftheßlewhosepositiontodetermineoradjust.Ifyougiveaßlename,andthatßleisnotyetopen,MapleopensitinREADmodewithtypeBINARY. 3.4FileManipulationCommands¯195Thepositionisoptional.Ifyoudonotspecifytheposition,Maplereturnsthecurrentposition.Ifyousupplytheposition,Maplesetsthecurrentpositiontopositionandreturnstheresultingposition.Inthatcase,thereturnedpositionisthesameasthespecißedpositionunlesstheßleisshorterthanthespecißedposition,inwhichcasethereturnedpositionisthatoftheendoftheßle(thatis,itslength).Youcanspecifythepositioneitherasanintegerorasthenameinfinity,whichspecißestheendoftheßle.Thefollowingcommandreturnsthelengthoftheßlemyfile.txt.>filepos("myfile.txt",infinity);36DetectingtheEndofaFileThefeofcommanddetermineswhetheryouhavereachedtheendofaßle.OnlyusethefeofcommandonßlesthatyouhaveopenedasSTREAMsimplicitlyorexplicitlyviafopen.Callfeofinthefollowingmanner.feof(fileIdentifier)TheßleIdentißeristhenameordescriptoroftheßletoquery.Ifyougiveaßlename,andthatßleisnotyetopen,MapleopensitinREADmodewithtypeBINARY.Thefeofcommandreturnstrueifandonlyifyouhavereachedtheendoftheßleduringthemostrecentreadline,readbytes,orfscanfoperation.Otherwise,feofreturnsfalse.Thismeansthatif20bytesremaininaßleandyouusereadbytestoreadthese20bytes,thenfeofstillreturnsfalse.Youencountertheend-of-ßleonlyafteryouattemptanotherread.DeterminingFileStatusTheiostatuscommandreturnsdetailedinformationaboutalltheßlescurrentlyinuse.Calltheiostatuscommandwiththefollowingsyntax.iostatus()Theiostatuscommandreturnsalist.Thelistcontainsthefollowingelements:iostatus()[1]ThenumberofßlesthattheMapleI/Olibraryiscur-rentlyusing. 196¯Chapter3:InputandOutputiostatus()[2]Thenumberofactivenestedreadcommands(whenreadreadsaßle,whichitselfcontainsareadstatement).iostatus()[3]Theupperboundoniostatus()[1]+iostatus()[2]thattheunderlyingoperatingsystemimposes.iostatus()[n]forn>3.AlistgivinginformationaboutaßlecurrentlyinusebytheMapleI/Olibrary.Whenn>3,theliststhatiostatus()[n]returneachcontainthefollowingelements:iostatus()[n][1]Theßledescriptorwhichfopenoropenreturned.iostatus()[n][2]Theßlename.iostatus()[n][3]Theßlekind(STREAM,RAW,orDIRECT).iostatus()[n][4]Theßlepointerorßledescriptorthattheunderlyingoperatingsystemuses.ThepointerisintheformFP=integerorFD=integer.iostatus()[n][5]Theßlemode(READorWRITE).iostatus()[n][6]Theßletype(TEXTorBINARY).RemovingFilesManyßlesaresolelyfortemporaryuse.BecauseyoudonotneedtheseßlesinfutureMaplesessions,removethem.Usethefremovecommandtodothis.fremove(fileIdentifier)TheßleIdentißeristhenameordescriptoroftheßletoremove.Iftheßleisopen,Mapleclosesitbeforeremovingit.Iftheßledoesnotexist,Maplegeneratesanerror.Toremoveaßleregardlessofwhetheritexists,useatry/catchstate-menttotraptheerrorthatfremovemightcreate.>tryfremove("myfile.txt")catch:endtry: 3.5InputCommands¯1973.5InputCommandsReadingTextLinesfromaFileThereadlinecommandreadsasinglelineoftextfromaßle.Charactersarereaduptoandincludinganewline.Thereadlinecommandthendiscardsthenewlinecharacter,andreturnsthelineofcharactersasaMaplestring.Ifreadlinecannotreadawholelinefromtheßle,thenitreturns0insteadofastring.Callthereadlinecommandbyusingthefollowingsyntax.readline(fileIdentifier)TheßleIdentißeristhenameordescriptoroftheßletoread.ForcompatibilitywithearlierversionsofMaple,youcanomittheßleI-dentißer,inwhichcaseMapleusesdefault.Thusreadline()andreadline(default)areequivalent.Ifyouuse-1astheßleIdentißer,Maplealsotakesinputfromthedefaultstream,exceptthattheMaplecommand-linepreprocessorrunsonallinputlines.ThismeansthatlinesbeginningwithÕ!Ôpasstotheoperatingsysteminsteadofreturningthroughreadline,andthatlinesbeginningwithÕ?Ôtranslatetocallstothehelpcommand.Ifyoucallreadlinewithaßlename,andthatßleisnotopen,MapleopensitinREADmodeasaTEXTßle.Ifreadlinereturns0(indicatingtheendoftheßle)whencalledwithaßlename,itautomaticallyclosestheßle.ExampleThefollowingexampledeßnesaMapleprocedurewhichreadsatextßleanddisplaysitonthedefaultoutputstream.>ShowFile:=proc(fileName::string)>localline;>do>line:=readline(fileName);>ifline=0thenbreakendif;>printf("%s ",line);>enddo;>endproc:ReadingArbitraryBytesfromaFileThereadbytescommandreadsoneormoreindividualcharactersorbytesfromaßle,returningastringoralistofintegers.Iftherearenocharactersremainingintheßlewhenyoucallreadbytes,thecommandreturns0,indicatingthatyouhavereachedtheendoftheßle. 198¯Chapter3:InputandOutputUsethefollowingsyntaxtocallthereadbytescommand.readbytes(fileIdentifier,length,TEXT)TheßleIdentißeristhenameordescriptoroftheßletoread.Thelength,whichyoumayomit,specißeshowmanybytesMapleneedstoread.Ifyouomitlength,Maplereadsonebyte.TheoptionalparameterTEXTindicatesthattheresultistobereturnedasastringratherthanalistofintegers.Youcanspecifythelengthasinfinity,inwhichcaseMaplereadstheremainderoftheßle.IfyouspecifyTEXTwhenabytewithvalue0residesamongthebytesbeingread,theresultingstringcontainsonlythosecharactersprecedingthe0byte.Ifyoucallreadbyteswithaßlename,andthatßleisnotopen,MapleopensitinREADmode.IfyouspecifyTEXT,MapleopensitasaTEXTßle;otherwise,MapleopensitasaBINARYßle.Ifreadbytesreturns0(indi-catingtheendoftheßle)whenyoucallitwithaßlename,itautomaticallyclosestheßle.ExampleThefollowingexampledeßnesaMapleprocedurewhichreadsanentireßle,byusingreadbytes,andcopiesittoanewßle.>CopyFile:=proc(sourceFile::string,destFile::string)>writebytes(destFile,readbytes(sourceFile,infinity))>endproc:Note:Forinformationonthewritebytesfunction,referto?writebytesorseeWritingBytestoaFileonpage210.FormattedInputThefscanfandscanfcommandsreadfromaßle,parsingnumbersandsubstringsaccordingtoaspecißedformat.Thecommandsreturnalistoftheseparsedobjects.Ifnomorecharactersremainintheßlewhenyoucallfscanforscanf,theyreturn0insteadofalist,indicatingthatithasreachedtheendoftheßle.Callthefscanfandscanfcommandsasfollows.fscanf(fileIdentifier,format)scanf(format)TheßleIdentißeristhenameordescriptoroftheßletoread.AcalltoscanfisequivalenttoacalltofscanfwithdefaultastheßleIdentißer. 3.5InputCommands¯199Ifyoucallfscanfwithaßlename,andthatßleisnotopen,MapleopensitinREADmodeasaTEXTßle.Iffscanfreturns0(indicatingtheendoftheßle)whenyoucallitwithaßlename,Mapleautomaticallyclosestheßle.FormatStringTheformatspecißeshowMapleistoparsetheinput.TheformatisaMaplestringconsistsofasequenceofconversionspec-ißcations,thatmaybeseparatedbyothercharacters.Eachconversionspecißcationhasthefollowingformat,wherethebracketsindicateop-tionalcomponents.%[*][width][modifiers]code¯TheÕ%Ôsymbolbeginstheconversionspecißcation.¯TheoptionalÕ*ÔindicatesthatMapleistoscantheobject,butnotreturnitaspartoftheresult.Itisdiscarded.¯Theoptionalwidthindicatesthemaximumnumberofcharacterstoscanforthisobject.Youcanusethistoscanonelargerobjectastwosmallerobjects.Theoptionalmodißersareusedtoindicatethetypeofthevaluetobereturned:lorLTheletterslandLaresupportedforcompatibilitywiththeCscanffunction,andindicatethataÕlongintÔorÕlonglongÔistobereturned.InMaple,theseàagshavenoeÞect.zcorZOneoftheseàagscanprecedeanyofthenumericformats,namelyd,o,x,e,f,org,indicatingthatacomplexvalueistobescanned.TherealandimaginarypartsofthecomplexvaluearescannedbyusingthespecißedformatwiththezorZelided.Thezformatscanstherealpart,followedbythecharacterspecißedbyc,followedbytheimaginarypart.TheZformatscanstherealpart,followedbyaÕ+ÔorÕ-Ôsign,followedbytheimaginarypart,fol-lowedbyastringofcharacterscorrespondingtothecurrentsettingofinterface(imaginaryunit).ThezandZoptionscanresultinoneofthefewconditionsinwhichscanfraisesanexception.Ifscanfisscanningacomplexvalue(forexample,therealparthasalreadybeensuccessfullyscanned),andisunabletoßnishscanningtheremainder(forexample,thereisnoimag-inarypartaftertherealpart),scanfraisesanexceptionoftheform" 200¯Chapter3:InputandOutput`%1`expectedininputforcomplexformat",where%1isre-placedbytheexpectedcharacter(forexample,acomma).Thecodeindicatesthetypeofobjecttoscan.ItdeterminesthetypeofobjectthatMaplereturnsintheresultinglist.Thecodecanbeoneofthefollowing.dThenextnon-whitespacecharactersintheinputmustcompriseasignedorunsigneddecimalinteger.AMapleintegerisreturned.oThenextnon-whitespacecharactersintheinputmustmakeupanunsignedoctal(base8)integer.Theintegerisconvertedtoadecimal,andthenreturnedasaMapleinteger.xThenextnon-whitespacecharactersintheinputmustconsistofanunsignedhexadecimal(base16)integer.ThelettersAthroughF(up-perorlowercase)representthedigitscorrespondingtothedecimalnumbers10through15.Theintegerisconvertedtoadecimal,andthenreturnedasaMapleinteger.yThenextnon-whitespacecharactersintheinputmustconsistofanIEEEhex-dumpformatàoating-pointvalue.Thisvaluemustconsistofsixteenhexadecimalcharacters.Thevalueisconvertedtoandre-turnedasaMapleàoat.e,f,orgThenextnon-whitespacecharactersintheinputmustconsistofasignedorunsigneddecimalnumber,possiblyincludingadecimalpoint,andpossiblyfollowedbyEore,anoptionalsign,andadecimalintegerindicatingapoweroften.ThenumberisreturnedasaMapleàoating-pointvalue.Inadditiontonumericvalues,thee,f,andgformatsalsorecognizethespecialvaluesÕinfÔandÕNaNÔ.IfaniorNisencounteredwhenscanfislookingfortheßrstdigitofanumber,itassumesthatoneofthesespecialvalueshasbeenfound,andproceedstolookforthesubsequentnforaN.Iftherestofthespecialvalueisnotfound,anexceptionisraised.he,hf,orhgThesearespecialformatsforreadingoneortwo-dimensionalnumericarrays.Ingeneral,sucharraysshouldbereadbyusingthemoresophisticatedfunctionalityprovidedbythe{}format,butthehe,hf,andhgformatsareprovidedforbackwardcompatibilitywithhfarrays,andprovidesomeintelligenceinautomaticallydealingwithavarietyoftextuallayoutsofsucharrays. 3.5InputCommands¯201Thefollowinginputmustconsistofaoneortwo-dimensionalarrayofàoating-point(orinteger)values.Charactersencounteredduringscanningarecategorizedintothreeclasses:numeric,separator,andterminator.Allthecharactersthatcanappearwithinanumber(thedigits,decimalpoint,signs,E,e,D,andd)arenumeric.Anywhitespace,commas,orsquarebracketsareseparators.Asquarebracketnotimmediatelyfollowedbyacomma,andanyothercharacter,isaterminator.Ifabackslashisencountered,itandthefollowingcharac-terareignored.Thedimensionsofthearrayaredeterminedbythenumberoflinesread,andthenumberofvaluesintheßrstline.Ifeitheroftheseis1,orifthenumberofrowsmultipliedbythenumberofcolumnsdoesnotequalthetotalnumberofvaluesread,aone-dimensionalarrayisproduced.ThedeßnitionofÕtheßrstlineÔisÕeverythingreaduptotheßrstlinebreakthatdoesnotimmediatelyfollowacommaorabackslash,oruptotheßrstclosingsquarebracketthatisimmediatelyfollowedbyacommaÔ.Thismethodcanreadanythingthatcanbewrittenbythecorre-spondingprintf,typicaltablesofnumbers,andlprintedorsaved(intextform)Maplelistsandlistsoflists.Theresultisreturnedasanhfarrayofoneortwodimensions.hxThefollowinginputmustconsistofaoneortwodimensionalarrayofàoating-pointnumbersinIEEEhex-dumpformat(16characterspernumber).Thedimensionsofthearrayaredeterminedasdescribedfortheprevious"%he","%hf",and"%hg"formats.sThenextnon-whitespacecharacters,uptobutnotincludingthefol-lowingblankcharacters(ortheendofthestring),arereturnedasaMaplestring.aMaplecollectsandparsesthenextnon-whitespacecharacters,uptobutnotincludingthefollowingblankcharacters(ortheendofthestring).AnunevaluatedMapleexpressionisreturned.mThenextcharactersmustbeaMapleexpressionencodedintheMaple.mßleformat.Maplereadsenoughcharacterstoparseasinglecom-pleteexpression;itignoresthewidthspecißcation.TheMapleexpres-sionisreturned. 202¯Chapter3:InputandOutputcThiscodereturnsthenextcharacter(whitespaceorotherwise)asaMaplestring.Ifawidthisspecißed,thatmanycharacters(blankorotherwise)arereturnedasasingleMaplestring.[:::]ThecharactersbetweenÕ[ÔandÕ]Ôbecomealistofcharactersthatareacceptableasacharacterstring.Maplescanscharactersfromtheinputuntilitencountersonethatisnotinthelist.ThescannedcharactersarethenreturnedasaMaplestring.IfthelistbeginswithaÕ^Ôcharacter,thelistrepresentsallthosecharactersnotinthelist.IfaÕ]Ôistoappearinthelist,itmustimmediatelyfollowtheopeningÕ[ÔortheÕ^Ôifoneexists.YoucanuseaÕ-Ôinthelisttorepresentarangeofcharacters.Forexample,ÕA-ZÔrepresentsanycapitalletter.IfaÕ-Ôistoappearasacharacterinsteadofrepresentingarange,itmustappearatthebeginningortheendofthelist.{:::}wftThecharactersbetweentheleftbrace,"{",andtherightbrace,"}",areoptionsforscanningArrays,Matrices,orVectors(thatis,thevariousclassesofrtable).Theoptionalwisanintegerspecifyingthewidthtoscanforeachelement(anywidthspecißedbeforetheopening"{"appliestotheentirertablebeingscanned,butisignored).Thecharacterfspecißestheformatcode,andcanbeanyformatcodesupportedbyscanfexcept[...]or{...}.Thecharactert,whichmustbeoneofa,m,c,orr,specißesthetypeofobjecttobecreated(Array,Matrix,Vector[column],orVector[row]respectively).Formoreinformationonrtableformattingoptions,referto?rtable_scanf.MThenextsequenceofcharactersmustcorrespondtoawellformedXMLelement.TheresultisaMaplefunctioncallwhosenameisconstructedfromtheXMLelement,whoseargumentsareeitherfunctioncallsforthechildelementsortheCDATAasstrings,andwhoseattributesareequationsdeßningtheXMLattributesoftheobject.nThetotalnumberofcharactersscanneduptotheÕ%nÔisreturnedasaMapleinteger.Mapleskipsnon-whitespacecharactersintheformatbutnotwithinaconversionspecißcation(wheretheymustmatchthecorrespondingchar-actersintheinput).Itignoreswhitespaceintheformat,exceptthata 3.5InputCommands¯203spaceimmediatelyprecedingaÕ%cÔspecißcationcausestheÕ%cÔspeci-ßcationtoskipanyblanksintheinput.Ifitdoesnotsuccessfullyscananyobjects,Maplereturnsanemptylist.Thefscanfandscanfcommandsusetheunderlyingimplementa-tionthatthehardwarevendorprovidesfortheÕ%oÔandÕ%xÔformats.Asaresult,inputofoctalandhexadecimalintegersaresubjecttotherestrictionsoftheoperatingsystem.ExampleThefollowingexampledeßnesaMapleprocedurethatreadsaßlecontainingatableofnumbers,inwhicheachrowcanhaveadiÞerentwidth.Theßrstnumberineachrowisanintegerspecifyinghowmanyrealnumbersfollowitinthatrow,andcommasseparateallthenumbersineachrow.>ReadRows:=proc(fileName::string)>localA,count,row,num;>A:=[];>do>#Determinehowmanynumbersareinthisrow.>count:=fscanf(fileName,"%d");>ifcount=0thenbreakendif;>ifcount=[]then>error"integerexpectedinfile">endif;>count:=count[1];>>#Readthenumbersintherow.>row:=[];>whilecount>0do>num:=fscanf(fileName,",%e");>ifnum=0then>error"unexpectedendoffile">endif;>ifnum=[]then>error"numberexpectedinfile">endif;>row:=[op(row),num[1]];>count:=count-1>enddo;>>#Appendtherowtotheaccumulatedresult.>A:=[op(A),row]>enddo;>A>endproc: 204¯Chapter3:InputandOutputReadingMapleStatementsThereadstatcommandreadsasingleMaplestatementfromtheterminalinputstream.Mapleparsesandevaluatesthestatement,andreturnstheresult.Callthereadstatcommandasfollows.readstat(prompt,ditto3,ditto2,ditto1)Thepromptargumentspecißesthepromptthatreadstatistouse.Ifyouomitthepromptargument,Mapleusesablankprompt.Youcaneithersupplyoromitallofthethreeargumentsditto3,ditto2,andditto1.Ifyousupplythem,theyspecifythevalueswhichMapleusesfor%%%,%%,and%inthestatementthatreadstatreads.SpecifyeachoftheseargumentsasaMaplelistcontainingtheactualvalueforsubstitution.Thisallowsforvaluesthatareexpressionsequences.Forexample,if%istohavethevalue2*n+3and%%istohavethevaluea,b,thenuse[2*n+3]forditto1and[a,b]forditto2.TheresponsetoreadstatmustbeasingleMapleexpression.Theexpressioncanspanmorethanoneinputline,butreadstatdoesnotpermitmultipleexpressionsononeline.Iftheinputcontainsasyntaxerror,readstatreturnsanerrordescribingthenatureoftheerror,anditspositionintheinput.ExampleThefollowingexampleshowsatrivialuseofreadstatwithinaprocedure.>InteractiveDiff:=proc()>locala,b;>a:=readstat("Pleaseenteranexpression:");>b:=readstat("Differentiatewithrespectto:");>printf("Thederivativeof%awithrespectto%ais%a ",>a,b,diff(a,b))>endproc:ReadingTabularDataThereaddatacommandreadsTEXTßlescontainingtablesofdata.Forsimpletables,thisismoreconvenientthanwritingaprocedurebyusingaloopandthefscanfcommand.Usethefollowingsyntaxtocallthereaddatacommand.readdata(fileIdentifier,dataType,numColumns)TheßleIdentißeristhenameordescriptoroftheßlefromwhichreaddatareadsthedata.ThedataTypemustbeoneofintegerorfloat,oryou 3.5InputCommands¯205canomitit,inwhichcasereaddataassumesfloat.Ifreaddataneedstoreadmorethanonecolumn,youcanspecifythetypeofeachcolumnbyusingalistofdatatypes.ThenumColumnsargumentindicateshowmanycolumnsofdataaretobereadfromtheßle.IfyouomitnumColumns,readdatareadsthenumberofcolumnsspecißedbythenumberofdatatypesthatyouspec-ißed(onecolumnifyoudidnotspecifyanydataType).IfMaplereadsonlyonecolumn,readdatareturnsalistofthevaluesread.IfMaplereadsmorethanonecolumn,readdatareturnsalistoflists,eachsublistofwhichcontainsthedatareadfromonelineoftheßle.Ifyoucallreaddatawithaßlename,andthatßleisnotopen,MapleopensitinREADmodeasaTEXTßle.Furthermore,ifyoucallreaddatawithaßlename,itautomaticallyclosestheßlewhenreaddatareturns.ExampleThefollowingtwoexamplesareequivalentusesofreaddatatoreadatableof(x;y;z)-triplesofrealnumbersfromaßle.>A1:=readdata("my_xyz_file.text",3);A1:=[[1:5;2:2;3:4];[2:7;3:4;5:6];[1:8;3:1;6:7]]>A2:=readdata("my_xyz_file.text",[float,float,float]);A2:=[[1:5;2:2;3:4];[2:7;3:4;5:6];[1:8;3:1;6:7]]Note:Dataelementsintheßlearewhitespacedelimited.Newlinessepa-raterows,andwhitespaceseparatescolumns.ThenumColumnsargumentdeßneshowmanycolumnstoreadandthosecolumnsarereadfromallrows.Fortheßle:12345678readdata(...,2)returns[[1,2],5,6]]andreaddata(...,3)returns[[1,2,3],[5,6,7]]. 206¯Chapter3:InputandOutput3.6OutputCommandsConßguringOutputParametersUsingtheinterfaceCommandTheinterfacecommandisnotanoutputcommand.ItisamechanismtoprovidecommunicationbetweenMapleandtheuserinterface.YoucanuseittoconßgureparametersaÞectingtheoutputproducedbyvariouscommandswithinMaple.Tosetaparameter,calltheinterfacecommandasfollows.interface(variable=expression)Thevariableargumentspecißeswhichparametertochange,andtheex-pressionargumentspecißesthevaluethattheparameteristohave.Foralistofparametersyoucanuse,seethefollowingsectionsorreferto?interface.Youcansetmultipleparametersbygivingseveralargu-mentsoftheformvariable=expression,withcommasseparatingthem.Toquerythesettingofaparameter,usethefollowingsyntax.interface(variable)Thevariableargumentspecißestheparametertoquery.Theinterfacecommandreturnsthecurrentsettingoftheparameter.Youcanqueryonlyoneparameteratatime.One-DimensionalExpressionOutputThelprintcommandprintsMapleexpressionsinaone-dimensionalno-tationsimilartotheformatMapleusesforinput.Inmostcases,youcanusethisoutputasinput,andthesameexpressionwouldresult.ThesingleexceptionisiftheexpressioncontainsMaplenamescontainingnon-alphanumericcharacters.Thelprintcommandiscalledasfollows.lprint(expressionSequence)TheexpressionSequenceconsistsofoneormoreMapleexpressions.Eachoftheexpressionsisprintedinturn,withthreespacesseparatingeachofthem.Mapleprintsanewlinecharacterafterthelastexpression.Maplealwayssendstheoutputthatlprintproducestothedefaultoutputstream.Youcanusethewritetoandappendtocommands,de-scribedlater,totemporarilyredirectthedefaultoutputstreamtoaßle. 3.6OutputCommands¯207TheinterfaceparameterscreenwidthaÞectstheoutputoflprint.Ifpossible,Maplewrapstheoutputbetweentokens.Ifasingletokenistoolongtodisplay(forexample,averylongnameornumber),Maplebreaksitacrosslines,andprintsabackslash,ÕÔ,beforeeachlinebreak.ExampleThefollowingcommand-lineexampleillustrateslprintout-put,andhowscreenwidthaÞectsit.>lprint(expand((x+y)^5));x^5+5*x^4*y+10*x^3*y^2+10*x^2*y^3+5*x*y^4+y^5>interface(screenwidth=30);>lprint(expand((x+y)^5));x^5+5*x^4*y+10*x^3*y^2+10*x^2*y^3+5*x*y^4+y^5Two-DimensionalExpressionOutputTheprintcommandprintsMapleexpressionsinatwo-dimensionalno-tation.DependingontheversionofMapleandtheuserinterface,thisnotationiseitherthestandardmathnotationthatappearsintextbooksandothertypesetmathematicaldocuments,oranapproximationofstan-dardmathnotationusingonlytextcharacters.Theprintcommandiscalledasfollows.print(expressionSequence)TheexpressionSequenceconsistsofoneormoreMapleexpressions.Mapleprintseachexpression,inturn,withcommasseparatingthem.Theoutputproducedbyprintisalwayssenttothedefaultoutputstream.Youcanusethewritetoandappendtocommands,describedlater,totemporarilyredirectthedefaultoutputstreamtoaßle.SeveralinterfaceparametersaÞecttheoutputofprint.Theyaresetusingthesyntax 208¯Chapter3:InputandOutputinterface(parameter=value)Theyinclude:prettyprintThisselectsthetypeofoutputthatprintistoproduce.¯Ifyousetprettyprintto0,printproducesthesameoutputaslprint.¯Ifyousetprettyprintto1,printproducesasimulatedmathnotationusingonlytextcharacters.¯Ifyousetprettyprintto2,andtheversionofMapleyouarerunningiscapableofit,printproducesoutputusingstandardmathnotation.¯Thedefaultsettingofprettyprintis2.indentamountThisspecißesthenumberofspacesthatMapleusestoindentthecontinuationofexpressionsthataretoolargetoßtonasingleline.ThisparametertakeseÞectonlywhenyousetprettyprint(seepreviousdeßnition)to1,orwhenMapleisprintingprocedures.Thedefaultsettingofindentamountis4.labellingorlabelingYoucansetthistotrueorfalse,indicatingwhetherMapleshoulduselabelstorepresentcommonsubexpressionsinlargeexpressions.Labelscanmakelargeexpressionseasiertoreadandcomprehend.Thedefaultsettingoflabellingistrue.labelwidthThisindicatesthesizethatasubexpressionmusthaveforMapletoconsideritforlabeling(iflabellingistrue).Thesizeistheapproximatewidth,incharacters,oftheexpressionwhenprintedwithprintandprettyprint=1.screenwidthThisindicatesthewidthofthescreenincharacters.Whenprettyprintis0or1,Mapleusesthiswidthtodecidewhentowraplongexpressions.Whenprettyprintis2,theuserinterfaceusespix-elsinsteadofcharacters,anddeterminesthewidthautomatically.verboseprocUsethisparameterwhenprintingMapleprocedures.¯Ifyousetverboseprocto1,Mapleprintsonlyuserdeßnedproce-dures;Mapleshowssystemdeßnedproceduresinasimplißedformgivingonlythearguments,andpossiblyabriefdescriptionoftheprocedure. 3.6OutputCommands¯209¯Ifyousetverboseprocto2,Mapleprintsallproceduresinfull.¯Ifyousetverboseprocto3,Mapleprintsallproceduresinfull,andprintsthecontentsofaprocedure'sremembertableintheformofMaplecommentsaftertheprocedure.WhenyouuseMapleinteractively,itautomaticallydisplayseachcom-putedresult.Theformatofthisdisplayisthesameasifyouusedtheprintcommand.Therefore,alltheinterfaceparametersthataÞecttheprintcommandalsoaÞectthedisplayofresults.ExampleThefollowingcommand-lineexampleillustratesprintoutput,andhowprettyprint,indentamount,andscreenwidthaÞectit.>print(expand((x+y)^6));x6+6x5y+15x4y2+20x3y3+15x2y4+6xy5+y6>interface(prettyprint=1);>print(expand((x+y)^6));654233245x+6xy+15xy+20xy+15xy+6xy6+y>interface(screenwidth=35);>print(expand((x+y)^6));654233x+6xy+15xy+20xy2456+15xy+6xy+y>interface(indentamount=1);>print(expand((x+y)^6)); 210¯Chapter3:InputandOutput654233x+6xy+15xy+20xy2456+15xy+6xy+y>interface(prettyprint=0);>print(expand((x+y)^6));x^6+6*x^5*y+15*x^4*y^2+20*x^3*y^3+15*x^2*y^4+6*x*y^5+y^6WritingMapleStringstoaFileThewritelinecommandwritesoneormoreMaplestringstoaßle.Eachstringappearsonaseparateline.Callthewritelinecommandasfollows.writeline(fileIdentifier,stringSequence)TheßleIdentißeristhenameordescriptionoftheßletowhichMapleistowrite,andstringSequenceisthesequenceofstringsthatwritelineshouldwrite.IfyouomitthestringSequence,thenwritelinewritesablanklinetotheßle.WritingBytestoaFileThewritebytescommandwritesoneormoreindividualcharactersorbytestoaßle.Youcanspecifythebyteseitherasastringoralistofintegers.Thefollowingsyntaxcallsthewritebytescommand.writebytes(fileIdentifier,bytes)TheßleIdentißeristhenameordescriptoroftheßletowhichwritebytesiswriting.Thebytesargumentspecißesthebytestowrite.Thiscanbeeitherastringoralistofintegers.Ifyoucallwritebyteswithaßlename,andthatßleisnotopen,MapleopensitinWRITEmode.Ifyouspecifythebytesasastring,MapleopenstheßleasaTEXTßle;ifyouspecifythebytesasalistofintegers,MapleopenstheßleasaBINARYßle. 3.6OutputCommands¯211ExampleThefollowingexampledeßnesaMapleprocedurewhichreadsanentireßleandcopiesittoanewßleusingwritebytes.>CopyFile:=proc(sourceFile::string,destFile::string)>writebytes(destFile,readbytes(sourceFile,infinity));>endproc:FormattedOutputThefprintfandprintfcommandswriteobjectstoaßle,usingaspec-ißedformat.Callthefprintfandprintfcommandsasfollows.fprintf(fileIdentifier,format,expressionSequence)printf(format,expressionSequence)TheßleIdentißeristhenameordescriptoroftheßletowhichMapleistowrite.AcalltoprintfisequivalenttoacalltofprintfwithdefaultastheßleIdentißer.Ifyoucallfprintfwithaßlename,andthatßleisnotyetopen,MaplesopensitinWRITEmodeasaTEXTßle.TheformatspecißeshowMapleistowritetheelementsoftheex-pressionSequence.ThisMaplestringconsistsofasequenceofformattingspecißcations,possiblyseparatedbyothercharacters.Eachformatspec-ißcationhasthefollowingsyntax,wherethebracketsindicateoptionalcomponents.%[flags][width][.precision][modifiers]codeTheÕ%Ôsymbolbeginstheformatspecißcation.Oneormoreofthefol-lowingàagscanoptionallyfollowtheÕ%Ôsymbol:+AsignednumericvalueisoutputwithaleadingÕ+ÔorÕ-Ôsign,asappropriate.-Theoutputisleft-justißedinsteadofright-justißed.blankAsignednumericvalueisoutputwitheitheraleadingÕ-Ôoraleadingblank,dependingonwhetherthevalueisnegativeornon-negative.0Theoutputispaddedontheleft(betweenthesignandtheßrstdigit)withzeroes.IfyoualsospecifyaÕ-Ô,theÕ0Ôisignored. 212¯Chapter3:InputandOutput{}Thebracesencloseasetofdetailedformattingoptionsforprintinganrtable.Thesearedescribedinmoredetailinthehelppage?rtable_printf.Theoptionalwidthindicatestheminimumnumberofcharacterstooutputforthisßeld.Iftheformattedvaluehasfewercharacters,Maplepadsitwithblanksontheleft(orontheright,ifyouspecifyÕ-Ô).Theoptionalprecisionspecißesthenumberofdigitsthatappearafterthedecimalpointforàoating-pointformats,orthemaximumßeldwidthforstringformats.YoucanspecifybothwidthorprecisionasÕ*Ô,inwhichcaseMapletakesthewidthorprecisionfromtheargumentlist.Thewidthorprecisionargument(s)mustappear,inthatorder,beforetheargumentthatisbeingoutput.AnegativewidthargumentisequivalenttotheappearanceoftheÕ-Ôàag.Theoptionalmodißersareusedtoindicatethetypeofthevaluetobeprinted:lorLTheletterslandLaresupportedforcompatibilitywiththeCprintffunction,andindicatethata"longint"or"longlong"istobeformatted.InMaple,theseàagshavenoeÞect.zcorZOneoftheseàagscanprecedeanyofthenumericformats,namelyd,o,x,e,f,org,indicatingthatacomplexvalueistobeformatted.Eachoftherealandimaginarypartsofthecomplexvalueareformattedusingthespecißedformat,withthezorZelided.Thezformatprintstherealpart,followedbythecharacterspecißedbyc,followedbytheimaginarypart.TheZformatprintsthevalueintheformx+yi,wherexistherealpart,yistheimaginarypart,andiisthecurrentsettingofinterface(imaginaryunit).Ifyisnegative,a"-"isoutputinsteadofa"+".Ifasuppliedvalueisnotcomplex,itistreatedasacomplexvaluewithazeroimaginarypart.ThecodeindicatesthetypeofobjectthatMapleistowrite.Thecodecanbeoneofthefollowing.dFormatstheobjectasasigneddecimalinteger.oFormatstheobjectasanunsignedoctal(base8)integer.xorXFormatstheobjectasanunsignedhexadecimal(base16)integer.Maplerepresentsthedigitscorrespondingtothedecimalnumbers10through15bythelettersÕAÔthroughÕFÔifyouuseÕXÔ,orÕaÔthroughÕfÔifyouuseÕxÔ. 3.6OutputCommands¯213eorEFormatstheobjectasaàoating-pointnumberinscientißcnota-tion.Onedigitwillappearbeforethedecimalpoint,andprecisiondigitswillappearafterthedecimalpoint(sixdigitsifyoudonotspecifyaprecision).ThisisfollowedbytheletterÕeÔorÕEÔ,andasignedintegerspecifyingapowerof10.Thepowerof10willhaveasignandatleastthreedigits,withleadingzeroesaddedifnecessary.Ifthevaluebeingformattedisinßnity,-inßnity,orundeßned,theoutputis"Inf","-Inf",or"NaN"respectively.fFormatstheobjectasaßxed-pointnumber.Thenumberofdigitsspec-ißedbytheprecisionwillappearafterthedecimalpoint.Ifthevaluebeingformattedisinßnity,-inßnity,orundeßned,theoutputis"Inf","-Inf",or"NaN"respectively.gorGFormatstheobjectusingÕdÔ,ÕeÔ(orÕEÔifyouspecißedÕGÔ),orÕfÔformat,dependingonitsvalue.Iftheformattedvaluedoesnotcontainadecimalpoint,MapleusesÕdÔformat.Ifthevalueislessthan104orgreaterthan10precision,MapleusesÕeÔ(orÕEÔ)format.Otherwise,MapleusesÕfÔformat.Ifthevaluebeingformattedisinßnity,-inßnity,orundeßned,theoutputis"Inf","-Inf",or"NaN"respectively.yorYTheàoating-pointobjectisformattedinbyte-order-independentIEEEhexdumpformat(16characterswide).Atleast16charactersarealwaysoutput,regardlessofthespecißedwidth.Theprecisionisignored.Thedigitscorrespondingtothedecimalnumbers10through15arerepresentedbytheletters"A"through"F"ifuppercaseYwasspecißed,or"a"through"f"iflowercaseywasspecißed.cOutputstheobject,whichmustbeaMaplestringcontainingexactlyonecharacter,asasinglecharacter.sOutputstheobject,whichmustbeaMaplestringofatleastwidthcharacters(ifspecißed)andatmostprecisioncharacters(ifspecißed).aorAOutputstheobject,whichcanbeanyMapleobject,incorrectMaplesyntax.Mapleoutputsatleastwidthcharacters(ifspecißed)andatmostprecisioncharacters(ifspecißed).Note:TruncatingaMapleexpressionbyspecifyingaprecisioncanresultinanincompleteorsyntacticallyincorrectMapleexpressionintheoutput.The"%a"and"%A"formatsareidentical,exceptthat"%A"omitsanyquotesthatwouldnormallyappeararoundMaplesymbolsthatrequirethem. 214¯Chapter3:InputandOutputqorQThesearesimilarto"%a"or"%A",exceptthat"%q"or"%Q"ignoresallremainingargumentsandprintthemasanexpressionsequence,witheachelementformattedin"%a"or"%A"formatrespectively.Noadditionalformatspecißerscanappearafter"%q"or"%Q",sincetherearenoargumentstoformat.mTheobject,whichcanbeanyMapleobject,isoutputintheMaple.mßleformat.Mapleoutputsatleastwidthcharacters(ifspecißed),andatmostprecisioncharacters(ifspecißed).Note:TruncatingaMaple.mformatexpressionbyspecifyingaprecisioncanresultinanincompleteorincorrectMapleexpressionintheoutput.%Apercentsymbolisoutputverbatim.Mapleoutputscharactersthatareinformatbutnotwithinaformatspecißcationverbatim.AlltheformatsapplytoArrays(typeArray),Matrices(typeMatrix),Vectors(typeVector),andhfarrays(typehfarray),allofwhichareobjectsoftypertable.¯Ifnortable-specißcformattingoptionsarespecißed(viathe{...}op-tion,referto?rtable_printf),the%a,%A,%m,and%Mformatcodesprintarepresentationofthertablestructureitself.Forexample,theformatcode%aprintsaMatrix,Vector,orArraycall.¯Ifnoadditionalrtable-specißcformattingoptionsarespecißedforaformatcodeotherthan%a,%A,%m,and%M,orifanemptyrtableoptionsequence(thatis,just{})isspecißedforanyformatcode,thefollowingdefaultformattingisapplied:One-dimensionalobjectsareformattedasonelongline,withtheele-mentsseparatedbyatleastonespace.ObjectsofNdimensions,whereN>1,areformattedasasequenceof(N1)-dimensionalobjectsseparatedbyN2blanklines.There-fore,two-dimensionalobjectsareformattedintheobviousway,three-dimensionalobjectsareformattedasaseriesoftwo-dimensionalob-jectsseparatedbyblanklines,andsoon.¯Anyoftheàoating-pointformatscanacceptinteger,rational,oràoating-pointobjects;Mapleconvertstheobjectstoàoating-pointvalues,andthenoutputsthemappropriately.¯Thefprintfandprintfcommandsdonotautomaticallystartanewlineattheendoftheoutput.Ifyourequireanewline, 3.6OutputCommands¯215theformatstringmustcontainanewlinecharacter,Õ Ô.Out-putfromfprintfandprintfisnotsubjecttolinewrappingatinterface(screenwidth)characters.¯TheÕ%oÔ,Õ%xÔ,andÕ%XÔformatsusetheunderlyingimplementa-tionthatthehardwarevendorprovides.Asaresult,outputofoctalandhexadecimalvaluesissubjecttotherestrictionsoftheoperatingsystem.WritingTabularDataThewritedatacommandwritestabulardatatoTEXTßles.Inmanycases,thisismoreconvenientthanwritinganoutputprocedurebyusingaloopandthefprintfcommand.Callthewritedatacommandinthefollowingmanner.writedata(fileIdentifier,data,dataType,defaultProc)TheßleIdentißeristhenameordescriptoroftheßletowhichwritedatawritesthedata.Ifyoucallwritedatawithaßlename,andthatßleisnotyetopen,MapleopensitinWRITEmodeasaTEXTßle.Furthermore,ifyoucallwritedatawithaßlename,theßleautomaticallycloseswhenwritedatareturns.Thedatamustbeavector,matrix,list,orlistoflists.1¯Ifthedataisavectororlistofvalues,writedatawriteseachvaluetotheßleonaseparateline.¯Ifthedataisamatrixoralistoflistsofvalues,writedatawriteseachroworsublisttotheßleonaseparateline,withtabcharactersseparatingtheindividualvalues.ThedataTypeisoptional,andspecißeswhetherwritedataistowritethevaluesasintegers,àoating-pointvalues(thedefault),orstrings.¯Ifyouspecifyinteger,thevaluesmustbenumeric,andwritedatawritesthemasintegers(Mapletruncatesrationalandàoating-pointvaluestointegers).¯Ifyouspecifyfloat,thevaluesmustbenumeric,andwritedatawritesthemasàoating-pointvalues(Mapleconvertsintegerandra-tionalvaluestoàoating-point).1Forinformationabouthowtoreadandwritertable-basedMatricesandVectors,referto?ImportMatrixand?ImportVector. 216¯Chapter3:InputandOutput¯Ifyouspecifystring,thevaluesmustbestrings.¯Whenwritingmatricesorlistsoflists,youcanspecifythedataTypeasalistofdatatypes,onecorrespondingtoeachcolumnintheoutput.TheoptionaldefaultProcargumentspecißesaprocedurethatwritedatacallsifadatavaluedoesnotconformtothedataTypeyouspecißed(forexample,ifwritedataencountersanon-numericvaluewhenthedataTypeisfloat).MaplepassestheßledescriptorcorrespondingtotheßleIdentißer,alongwiththenon-conformingvalue,asanargumenttothedefaultProc.ThedefaultdefaultProcsimplygeneratestheerror,Baddatafound.AmoreusefuldefaultProcmightbethefollowing.>UsefulDefaultProc:=proc(f,x)fprintf(f,"%a",x)endproc:Thisprocedureisgeneric.Itcanwriteanyvaluetotheßle.ExampleThefollowingexamplecomputesa5by5Hilbertmatrix,andwritesitsàoating-pointrepresentationtoaßle.>writedata("hilbertFile.txt",linalg[hilbert](5)):Examiningtheßleshows:1.5.3333333333.25.2.5.3333333333.25.2.1666666667.3333333333.25.2.1666666667.1428571429.25.2.1666666667.1428571429.125.2.1666666667.1428571429.125.1111111111FlushingaBuÞeredFileI/ObuÞeringmayresultinadelaybetweenwhenyourequestawriteoperationandwhenMaplephysicallywritesthedatatotheßle.Thiscapitalizesonthegreatereáciencyofperformingonelargewriteinsteadofseveralsmallerones.Normally,theI/Olibrarychooseswhentowritetoaßleautomatically.Insomesituations,however,youwanttoensurethatthedatayouwriteisinsertedintotheßle.Forexample,inUNIX,acommonprocedureistorunacommand,suchastail-fßleName,inanotherwindowtomonitortheinformationasMapleiswritingit.Forcasessuchasthese,theMapleI/Olibraryprovidesthefflushcommand.Callthefflushcommandusingthefollowingsyntax. 3.6OutputCommands¯217fflush(fileIdentifier)TheßleIdentißeristhenameordescriptoroftheßlewhosebuÞerMapleistoàush.Whenyoucallfflush,MaplewritesallinformationthatisinthebuÞer,butnotyetinthephysicalßle,totheßle.Typically,aprogramwouldcallfflushwheneversomethingsignißcantiswritten(forexample,acompleteintermediateresultorafewlinesofoutput).Notethatyoudonotneedtousefflush;anythingyouwritetoaßleisphysicallywrittenbeforeyouclosetheßle.ThefflushcommandsimplyforcesMapletowritedataondemand,sothatyoucanmonitortheprogressofaßle.RedirectingthedefaultOutputStreamThewritetoandappendtocommandsredirectthedefaultoutputstreamtoaßle.Thismeansthatanyoperationsthatwritetothedefaultstreamwritetotheßleyouspecifyinstead.Youcancallthewritetoandappendtocommandsasfollows.writeto(fileName)appendto(fileName)TheßleNameargumentspecißesthenameoftheßletowhichMapleistoredirecttheoutput.Ifyoucallwriteto,Mapletruncatestheßleifitexists,andwritessubsequentoutputtotheßle.Theappendtocommandappendstotheendoftheßleiftheßleexists.Iftheßleyouspecifyisopen(forexample,itisinusebyotherßleI/Ooperations),Maplegeneratesanerror.ThespecialßleNameterminal(specißedasaname,notastring)causesMapletosendsubsequentdefaultoutputtotheoriginaldefaultoutputstream(theonethatwasineÞectwhenyoustartedMaple).Thecallswriteto(terminal)andappendto(terminal)areequivalent.RecommendationIssuingawritetoorappendtocalldirectlyfromtheMaplepromptisnotrecommended.WhenwritetoorappendtoisineÞect,Maplealsowritesanyerrormessagesthatcanresultfromsubse-quentoperationstotheßle.Therefore,youcannotseewhatishappening.Generally,usethewritetoandappendtocommandswithinproceduresorßlesofMaplecommandsthatthereadcommandisreading. 218¯Chapter3:InputandOutput3.7ConversionCommandsConversionbetweenStringsandListsofIntegersThereadbytesandwritebytescommandsdescribedinsections3.5and3.6canworkwitheitherMaplestringsorlistsofintegers.Youcanusetheconvertcommandtoconvertbetweenthesetwoformatsasfollows.convert(string,bytes)convert(integerList,bytes)Ifyoupassconvert(...,bytes)astring,itreturnsalistofintegers;ifyoupassitalistofintegers,itreturnsastring.DuetothewaystringsareimplementedinMaple,thecharactercor-respondingtothebyte-value0cannotappearinastring.Therefore,ifintegerListcontainsazero,convertreturnsastringofonlythosechar-acterscorrespondingtotheintegersprecedingtheoccurrenceof0inthelist.ConversionbetweenstringsandlistsofintegersisusefulwhenMaplemustinterpretpartsofastreamofbytesasacharacterstring,whileitmustinterpretotherpartsasindividualbytes.Inthefollowingexample,Mapleconvertsastringtoalistofintegers.Then,itconvertsthesamelist,butwithoneentrychangedto0,backtoastring.Noticethatthestringistruncatedatthelocationofthe0.>convert("TestString",bytes);[84;101;115;116;32;83;116;114;105;110;103]>convert([84,101,115,116,0,83,116,114,105,110,103],bytes);ÕTestÔParsingMapleExpressionsandStatementsTheparsecommandconvertsastringofvalidMapleinputtothecorre-spondingMapleexpression.Theexpressionissimplißed,butnotevalu-ated.Usetheparsecommandasfollows.parse(string,options) 3.7ConversionCommands¯219Thestringargumentisthestringtobeparsed.ItmustdescribeaMapleexpression(orstatement,seethefollowingdeßnition)byusingtheMaplelanguagesyntax.Youcansupplyoneormoreoptionstotheparsecommand:statementThisindicatesthatparseistoacceptstatementsinadditiontoexpressions.However,sinceMapleautomaticallyevaluatesstate-ments,parseevaluatesthestringifyouspecifystatement.nosemicolonNormally,parsesuppliesaterminatingsemicolon,Õ;Ôifthestringdoesnotendinasemicolonoracolon,Õ:Ô.Ifyouspecifynosemicolon,thisdoesnothappen,andMaplegeneratesanunexpectedendofinputerrorifthestringisincomplete.Thereadstatcommand,whichusesreadlineandparse,makesuseofthisfacilitytoallowmulti-lineinputs.Ifthestringpassedtoparsecontainsasyntaxerror,parsegeneratesanerror(whichyoucantrapwithtraperror)ofthefollowingform.incorrectsyntaxinparse:errorDescription(errorLocation)TheerrorDescriptiondescribesthenatureoftheerror(forexample,`+`unexpected,orunexpectedendofinput).TheerrorLocationgivestheapproximatecharacterpositionwithinthestringatwhichMapledetectedtheerror.WhenyoucallparsefromtheMapleprompt,Mapledisplaystheparsedresultdependingonwhetherthecalltoparseendsinasemi-colonoracolon.Thestringpassedtoparsedoesnotrequireatrailingsemicolonoracolon.Ifincluded,itisignored.>parse("a+2+b+3");a+5+b>parse("sin(3.0)"):>%;0:1411200081 220¯Chapter3:InputandOutputFormattedConversiontoandfromStringsThesprintfandsscanfcommandsaresimilartofprintf/printfandfscanf/scanf,exceptthattheyreadfromorwritetoMaplestringsin-steadofßles.Callthesprintfcommandusingthefollowingsyntax.sprintf(format,expressionSequence)TheformatspecißeshowMapleistoformattheelementsoftheex-pressionSequence.ThisMaplestringconsistsofasequenceofformattingspecißcations,possiblyseparatedbyothercharacters.Formoreinforma-tion,see3.6FormattedOutputonpage211.Thesprintfcommandreturnsastringcontainingtheformattedre-sult.Callthesscanfcommandasfollows.sscanf(sourceString,format)ThesourceStringprovidestheinputforscanning.TheformatspecißeshowMapleistoparsetheinput.Asequenceofconversionspecißcations(andpossiblyotheranticipatedcharacters)consistofthisMaplestring.Forinformationontheformat,seeFormattedInputonpage198.Thesscanfcommandreturnsalistofthescannedobjects,justasfscanfandscanfdo.Thefollowingexampleillustratessprintfandsscanfbyconvertingaàoating-pointnumberandtwoalgebraicexpressionsintoaàoating-pointformat,Maplesyntax,andMaple.mformat,respectively.Thisstringisthenparsedintothecorrespondingobjectsusingsscanf.>s:=sprintf("%4.2f%a%m",evalf(Pi),sin(3),cos(3));s:=Õ3.14sin(3)-%$cosG6#ÕÕ$Ô>sscanf(s,"%f%a%m");[3:14;sin(3);cos(3)]Information:ForinformationontranslatingMapleexpressionsintootherprogramminglanguages,see6.1CodeGeneration. 3.8NotestoCProgrammers¯2213.8NotestoCProgrammersIfyouhaveexperienceprogrammingintheCorC++programminglan-guages,manyoftheI/Ocommandsdescribedinthischapterseemfamil-iar.TheMapleI/OlibrarydesignpurposelyemulatestheCstandardI/Olibrary.Ingeneral,theMapleI/OcommandsworkinasimilarmannertotheirCcounterparts.ThediÞerencesthatarisearetheresultofdiÞerencesbetweentheMapleandClanguages,andhowyouusethem.Forexample,intheClibrary,youmustpassthesprintffunctionabuÞerintowhichitwritestheresult.InMaple,stringsareobjectsthatyoucanpassaseasilyasnumbers,sothesprintfcommandsimplyreturnsastringthatissuácientlylongtoholdtheresult.Thismethodisbotheasiertoworkwithandlesserrorprone,asitremovesthedangerofwritingpasttheendofaßxedlengthbuÞer.Similarly,thefscanf,scanf,andsscanfcommandsreturnalistoftheparsedresultsinsteadofrequiringyoutopassreferencestovariables.Thismethodisalsolesserrorprone,asitremovesanydangerofpassingthewrongtypeofvariableoroneofinsuácientsize.OtherdiÞerencesincludetheuseofasinglecommand,filepos,toperformtheworkoftwoCfunctions,ftellandfseek.YoucandothisinMaplebecausefunctionscantakeavariablenumberofarguments.Ingeneral,ifyouhaveCorC++programmingexperience,youshouldhavelittletroubleusingtheMapleI/Olibrary.3.9ConclusionThischapterpresentedthedetailsofimportingandexportingdataandcodetoandfromMaple.Whilethisbookteachesfundamentalconceptsandprovidesapedagogicalintroductiontotopics,theMaplehelpsystemprovidesthedetailsoneachcommandandfeature.ItexplainssuchthingsastheoptionsandsyntaxofMaplecommandsandservesasaresourceforuseoftheMapleinterface.Formoreinformationonacommand,enter?command_nameattheMapleprompt. 222¯Chapter3:InputandOutput 4NumericalProgramminginMapleFloating-PointCalculationsThefocusofthischapterisonhowtoperformàoating-pointcalculationsinMaple.Youcanselectfromthefollowing.¯Softwareàoating-pointcalculationsofarbitraryprecisionÛotherthanspeed,independentofyourcomputer¯Hardwareàoating-pointarithematicÛprecisiondeterminedbythearchitectureofyourcomputer,butoÞersexceptionalspeedInThisChapter¯BasicsoftheevalfCommand¯HardwareFloating-PointNumbers¯Foating-PointModelsinMaple¯ExtendingtheevalfCommand¯UsingtheMatlabPackageWhyUseNumericalComputationsRepresentationandmanipulationofexpressionsinsymbolicmode,intermsofvariables,functions,andexactconstants,isapowerfulfeatureoftheMaplesystem.Practicalscientißccomputationalsodemandsàoating-pointcalculationswhichrepresentquantitiesbyapproximatenumericalvalues.Typically,numericalcomputationsareusedforoneofthreereasons.223 224¯Chapter4:NumericalProgramminginMaple1.Notallproblemshaveanalyticalorsymbolicsolutions.Forexample,therearemanyformsofpartialdiÞerentialequations,butonlyasmallsubsethaveknownclosed-formsolutions.Despitethis,itisusuallypossibletoßndnumericalsolutions.2.TheanalyticsolutionthatMaplereturnstoaproblemmaybeverylargeorcomplex.Tounderstandthebehavioroftheseexpressions,computeaàoating-pointapproximation.3.Insomecases,itiswastefultocomputeanexactanswer.Comput-ingananalyticsolutionisnotnecessaryifonlyanapproximationisneeded.Forexample,toplotasolution,anapproximationaccuratetotheresolutionoftheplottingdeviceissuácient.4.1TheBasicsofevalfTheevalfcommandistheprimarytoolinMapleforperformingàoating-pointcalculations.ItcausesMapletoevaluateinsoftwareàoating-pointmode.TheMaplesoftwareàoating-pointarithmetichasann-digitma-chineàoating-pointmodelasitsbasis,butallowscomputationsatarbi-traryprecision.TheenvironmentvariableDigits,whichhasaninitialsettingof10,determinesthedefaultnumberofdigitsforcalculations.>evalf(Pi);3:141592654YoucanalterthenumberofdigitseitherbychangingthevalueofDigits,orbyspecifyingthenumberasanindextoevalf.Notethatwhenyouspecifythenumberofdigitsasanindextoevalf,thedefault,Digits,remainsunchanged.>Digits:=20:>evalf(Pi);3:1415926535897932385>evalf[200](Pi); 4.1TheBasicsofevalf¯2253:1415926535897932384626433832795028841n97169399375105820974944592307816406286n20899862803482534211706798214808651328n23066470938446095505822317253594081284n81117450284102701938521105559644622948n9549303820>evalf(sqrt(2));1:4142135623730950488>Digits:=10:ThenumberofdigitsyouspecifyisthenumberofdecimaldigitsthatMapleusesduringcalculations.Specifyingalargernumberofdigitsislikelytogiveyouamoreaccurateanswer,andthemaximumvalueofDigitsissuácientlylargetobeconsideredinßniteforpracticalpur-poses.Unlikemosthardwareimplementationsofàoating-pointarithmetic,Maplestoresandperformssoftwareoperationsonàoating-pointnumbersinbase10.AccuracyAllàoating-pointcomputationsarepreferredinßnitepreci-sion,withintermediateresultsgenerallybeingroundedtoDigitspre-cision.Assuch,itispossibleforround-oÞerrorstoaccumulateinlongcomputations.Mapleensuresthattheresultofanysingleàoating-pointparithmeticoperation(+,,£,=,or)isfullyaccurate.Further,manyofthebasicfunctionsinMaple,suchasthetrigonometricfunctionsandtheirinverses,theexponentialandlogarithmfunctions,andsomeoftheotherstandardsspecialfunctionsformathematics,areaccuratetowithin.6unitsoflastplace(ulps),meaningthatiftheDigits+1stdigitofthetrueresultisa4,Maplemayrounditup,orifitisa6,Maplemayrounditdown.MostmathematicalfunctionsinMaple,includingnumericalintegration,achievethisaccuracyonnearlyallinputs.Somedeßniteintegralshavenoclosedformsolutionintermsofstan-dardmathematicalfunctions.Youcanuseevalftoobtainananswervianumericalintegration.>r:=Int(exp(x^3),x=0..1);Z1r:=e(x3)dx0 226¯Chapter4:NumericalProgramminginMaple>value(r);Z1e(x3)dx0>evalf(r);1:341904418Inothercases,Maplecanßndanexactsolution,buttheformoftheexactsolutionisalmostincomprehensible.ThefollowingfunctionBetaisaspecialfunctionthatappearsinmathematicalliterature.>q:=Int(x^99*(1-x)^199/Beta(100,200),x=0..1/5);Z1=599199x(1x)q:=dx0B(100;200)>value(q);278522905457805211792552486504343059984n03849800909690342170417622052715523897n76190682816696442051841690247452471818n79720294596176638677971757463413490644n25727501861101435750157352018112989492n.972548449217741280910371516468873n84971552115934384961767251671031013243n12241148610308262514475552524051323083n13238717840332750249360603782630341376n82537367383346083183346165228661133571n76260162148352832620593365691185012466n14718189600663973041983050027165652595n68426426994847133755683898925781250000n10B(100;200)>evalf(q); 4.2HardwareFloating-PointNumbers¯2270:3546007367107ThetwopreviousexamplesusetheIntcommandratherthanintfortheintegration.Ifyouuseint,Mapleßrsttriestointegratetheexpres-sionsymbolically.Thus,whenevaluatingthefollowingcommands,Mapledeterminesasymbolicanswerandthenconvertsittoaàoating-pointapproximation,ratherthanperformingdirectnumericalintegration.>evalf(int(x^99*(1-x)^199/Beta(100,200),x=0..1/5));0:3546007367107Whenperformingnumericalcalculations,donotusecommandslikeint,limit,andsumthatevaluatetheirargumentssymbolically.Ingeneral,resultsfromevalf(Int(...)),evalf(Sum(...)),andevalf(Limit(...)),aremoreaccuratethanresultsobtainedfromthecorrespondingevalf(int(...)),evalf(sum(...)),andevalf(limit(...))operations.Generally,symbolicevaluationcanbesuppressedbyusingunevaluationquotes.Forexample,evalf(sin(Pi/3))=evalf(1/2*3^(1/2))whileevalf('sin'(Pi/3))computesaàoating-pointapprox-imationtosin(evalf(Pi/3)).4.2HardwareFloating-PointNumbersMapleoÞersanalternativetosoftwareàoating-pointnumbers:computerhardwareàoating-pointarithmetic.Hardwareàoating-pointcalculationsaretypicallymuchfasterthansoftwareàoating-pointcalculations.How-ever,hardwareàoating-pointarithmeticaccuracydependsonyourcom-puter,andyoucannotincreasetheprecision.Theevalhfcommandevaluatesanexpressionusinghardwareàoating-pointarithmetic.>evalhf(1/3);0:333333333333333314>evalhf(Pi);3:14159265358979312 228¯Chapter4:NumericalProgramminginMapleGenerally,computersperformhardwareàoating-pointarithmeticus-ingacertainnumberofbinarydigits.Thespecialconstruct,evalhf(Digits),approximatesthecorrespondingnumberofdecimaldigits.>d:=evalhf(Digits);d:=15:Therefore,evalhfandevalfreturnsimilarresultsifevalfusesasettingofDigitsthatisclosetoevalhf(Digits).Mapleusuallydis-playstwoorthreedigitsmorethanthevalueofevalhf(Digits)specißes.Whenyouperformhardwareàoating-pointcalculations,Maplemustcon-vertallthebase-10softwareàoating-pointnumberstobase-2hardwareàoating-pointnumbers,andthenconverttheresultbacktobase10.TheextradecimaldigitsallowMapletoreproducethebinarynumberpreciselyifyouuseitagaininasubsequenthardwareàoating-pointcalculation.>expr:=ln(2/Pi*(exp(2)-1));e21expr:=ln(2)¹>evalhf(expr);1:40300383684168617>evalf[round(d)](expr);1:40300383684169Theresultsthatevalhfreturns,evenincludingforevalhf(Digits),arenotaÞectedbythevalueofDigits.>Digits:=4658;Digits:=4658>evalhf(expr);1:40300383684168617 4.2HardwareFloating-PointNumbers¯229>evalhf(Digits);15:>Digits:=10;Digits:=10Youcanusetheevalhf(Digits)constructtodeterminewhetherhardwareàoating-pointarithmeticprovidessuácientprecisioninapar-ticularapplication.IfDigitsislessthanevalhf(Digits),thenyoucantakeadvantageofthefasterhardwareàoating-pointcalculations.Oth-erwise,youshouldusesoftwareàoating-pointarithmetictoperformthecalculation,withsuácientdigits.Thefollowingevaluateproceduretakesanunevaluatedparameter,expr.Withouttheunevaldeclaration,Maplewouldevaluateexprsymbolicallybeforeinvokingevaluate.>evaluate:=proc(expr::uneval)>ifDigitsevalf(evalhf(expr));>else>evalf(expr);>endif;>endproc:TheevalhfcommandevaluatesmanyMaplefunctions,butnotall.Forexample,youcannotevaluateanintegralusinghardwareàoating-pointarithmetic.>evaluate(Int(exp(x^3),x=0..1));Error,(inevaluate)unabletoevaluatefunction`Int`inevalhfYoucanimprovetheevaluateproceduresothatittrapssucherrorsandtriestoevaluatetheexpressionusingsoftwareàoating-pointnumbersinstead.>evaluate:=proc(expr::uneval)>localresult;>ifDigitstry>returnevalf(evalhf(expr));>catch:>endtry;>else>evalf(expr);>endif; 230¯Chapter4:NumericalProgramminginMaple>endproc:>evaluate(Int(exp(x^3),x=0..1));Theevaluateprocedureprovidesamodelofhowtowriteproceduresthatusehardwareàoating-pointarithmeticwheneverpossible.Newton'sMethodThissectionillustrateshowtotakeadvantageofhardwareàoating-pointarithmetictocalculatesuccessiveapproximationsusingNewton'smethod.YoucanuseNewton'smethodtoßndnumericalsolutionstoequations.Assection1.2describes,ifxnisanapproximatesolutiontotheequationf(x)=0,thenxn+1,givenbythefollowingformula,istypicallyabetterapproximation.f(xn)xn+1=xn0f(xn)ExampleTheiterateproceduretakesafunction,f,itsderivative,df,andaninitialapproximatesolution,x0,asinputtotheequationf(x)=0.TheiterationprocedurecalculatesatmostNsuccessiveNewtonitera-tionsuntilthediÞerencebetweenthenewapproximationandthepreviousoneissmall.Theiterateprocedureprintsthesequenceofapproxima-tionstoshowsuccessiveapproximations.>iterate:=proc(f::procedure,df::procedure,>x0::numeric,N::posint)>localxold,xnew;>xold:=x0;>xnew:=evalf(xold-f(xold)/df(xold));>toN-1whileabs(xnew-xold)>10^(1-Digits)do>xold:=xnew;>print(xold);>xnew:=evalf(xold-f(xold)/df(xold));>enddo;>xnew;>endproc:Thefollowingprocedurecalculatesthederivativeoffandpassesallthenecessaryinformationtoiterate.>Newton:=proc(f::procedure,x0::numeric,N::posint)>localdf;>df:=D(f);>print(x0);>iterate(f,df,x0,N);>endproc: 4.2HardwareFloating-PointNumbers¯231UseNewtontosolvetheequationx22=0.>f:=x->x^2-2;f:=x!x22>Newton(f,1.5,15);1:51:4166666671:4142156861:4142135621:414213562ExampleThisversionofNewtonuseshardwareàoating-pointarithmeticifpossible.Sinceiterateonlytriestoßndasolutiontoanaccuracyof10^(1-Digits),Newtonusesevalftoroundtheresultofthehardwareàoating-pointcomputationtoanappropriatenumberofdigits.>Newton:=proc(f::procedure,x0::numeric,N::posint)>localdf,result;>df:=D(f);>print(x0);>ifDigitstry>returnevalf(evalhf(iterate(f,df,x0,N)));>catch:>endtry;>else>iterate(f,df,x0,N);>endif;>endproc:Newtonuseshardwareàoating-pointarithmeticfortheiterationsandroundstheresulttosoftwareprecision.Hardwareàoating-pointnum-bershavemoredigitsthanthesoftwareàoating-pointnumbers,giventhepresentsettingofDigits.>Newton(f,1.5,15); 232¯Chapter4:NumericalProgramminginMaple1:51:416666666666666741:414215686274509881:414213562374689871:414213562373095141:414213562Newtonmustusesoftwareàoating-pointarithmetictoßndarootofthefollowingBesselfunction.>F:=z->BesselJ(1,z);F:=z!BesselJ(1;z)>Newton(F,4,15);4SoftwarearithmeticisusedbecauseevalhfdoesnotrecognizeBesselJandthesymboliccodeforBesselJusesthetypecommandandremembertables,whichevalhfdoesnotallow.>evalhf(BesselJ(1,4));Error,unabletoevaluateexpressiontohardwarefloatsUsingatry-catchblockasinthepreviousNewtonprocedure,allowstheproceduretoworkwhenevalhffails.ThepreviousNewtonprocedureprintsmanydigitswhenitistryingtoßndaten-digitapproximation.Thereasonisthattheprintcommandislocatedinsidetheiterateprocedurewhichisinsideacalltoevalhf,whereallnumbersarehardwareàoating-pointnumbers,andprintassuch.ComputingwithArraysofNumbersUsetheevalhfcommandforcalculationswithnumbers.Theonlystruc-turedMapleobjectsallowedinacalltoevalhfarearraysofnumbers,eithertable-basedarraysorrtable-basedArrays.Ifanarrayhasunas-signedentries,evalhfinitializesthemtozero. 4.2HardwareFloating-PointNumbers¯233ExampleThefollowingprocedurecalculatesthepolynomial2+5x+4x2.>p:=proc(x)>locala,i;>a:=array(0..2);>a[0]:=2;>a[1]:=5;>a[2]:=4;>sum(a[i]*x^i,i=0..2);>endproc:>p(x);2+5x+4x2Ifyouintendtoenclosepinacalltoevalhf,youcannotdeßnethelo-calarrayausingarray(1..3,[2,5,4])becauselistsarenotsupportedinevalhf.Youcan,however,enclosepinacalltoevalhfiftheparameterxisanumber.>evalhf(p(5.6));155:439999999999997Youcanalsopassanarrayofnumbersasaparameterinsideacalltoevalhf.ExampleThefollowingprocedurecalculatesthedeterminantofa2¢2matrix.The(2,2)entryinthearrayaisunassigned.>det:=proc(a::array(2))>a[1,1]*a[2,2]-a[1,2]*a[2,1];>endproc:>a:=array([[2/3,3/4],[4/9]]);23236347a:=454a2;29>det(a); 234¯Chapter4:NumericalProgramminginMaple21a2;233Ifyoucalldetfrominsideacalltoevalhf,Mapleusesthevalue0fortheunassignedentry,a[2,2].>evalhf(det(a));0:333333333333333314evalhfpassesarraysbyvalue,sothe(2,2)entryofaisstillunas-signed.>a[2,2];a2;2Ifyouwantevalhftomodifyanarraythatyoupassasaparametertoaprocedure,youmustenclosethenameofthearrayinavarconstruct.Thevarconstructisspecialtoevalhfandisnecessaryonlyifyouwantevalhftomodifyanarrayofnumbersthatisaccessibleatthesessionlevel.>evalhf(det(var(a)));0:333333333333333314Nowaisanarrayofàoating-pointnumbers.>eval(a);[0:666666666666666629;0:750000000000000000][0:444444444444444420;0:]Theevalhfcommandalwaysreturnsasingleàoating-pointnumber,butthevarconstructallowsyoutocalculateawholearrayofnumberswithonecalltoevalhf.5.7GeneratingGridsofPointsillustratestheuseofvartocalculateagridoffunctionvaluesforplotting.Youcanalsocreatearraysofhardwareàoating-pointvaluesdirectlywiththeArraycommand.Properuseofthiscommandcansavesignißcantamountsoftime,especiallyinplottingroutines,whichrelyheavilyon 4.3Floating-PointModelsinMaple¯235arraysofàoating-pointvalues.Fordetailsandexamples,referto?Array,?Matrix,and?Vector.4.3Floating-PointModelsinMapleMaplecanrepresentsymbolicconstants,suchas¹and•,exactintegersandrationalnumbers,suchas37and3=4,andapproximationstonu-mericvalues,usingitsàoating-pointsystem.Numbersinthissystemarerepresentedbypairsofintegers,(m,e).Theßrstintegeriscalledthesignificandormantissa.Thesecondintegeriscalledtheexponent.Thenumberrepresentedism¢10e:Examplesofàoating-pointnumbersinMapleare3:1415,1:0,0:0007,1:0e0,and2e1234567.Thelasttwoareexamplesofàoating-pointnumbersenteredinscientißcnotation:the"e"separatesthemantissaandexpo-nentofthenumber.Suchnumberscanalsobeusedtorepresentcomplexnumbers(ascanexactintegersandrationals),forexample,1:0+2:7£I.Insomecontexts,Mapledistinguishesbetweensoftwareàoatsandhardwareàoats.Theevalhfevaluator(discussedinsection4.2),forex-ample,workswithhardwareàoats,andMaplecanconstructcertainkindsofmatricesandvectorswithhardwareàoatentries.Generally,however,Mapleworkswithsoftwareàoatstoperformapproximate(butusuallyveryaccurate)numericalcalculations.Floating-pointnumbersystemsareapproximationstothemathe-maticalsetofreal(andcomplex)numbers,andhencenecessarilyhavelimitations.Mostimportantly,suchsystemshavelimitedrange(therearelargestandsmallestrepresentablenumbers)andlimitedprecision(thesetofrepresentableàoating-pointnumbersisßnite).OneveryimportantfeatureoftheMaplesoftwareàoating-pointsystemisthatyoucontroltheprecision:youcanspecifytheprecisionMapleusesforàoating-pointcomputations.Someofthespecißcdetailsofthesecomputationsystemsareprovidedinthenextfewsections.SoftwareFloatsMaplesoftwareàoating-pointcomputationsareperformedinbase10.TheprecisionofacomputationisdeterminedbythesettingofDigits.Themaximumexponent,minimumexponent,andmaximumvaluefor 236¯Chapter4:NumericalProgramminginMapleDigitsaremachinewordsizedependent.YoucanobtainthevaluesfortheselimitsfromtheMaple_floatscommand.Thissoftwareàoating-pointsystemisdesignedasanaturalextensionoftheindustrystandardforhardwareàoating-pointcomputation,knownasIEEE754.Thus,therearerepresentationsforinfinityandundefined(whatIEEE754callsa"NaN",meaning"NotaNumber").Complexnum-bersarerepresentedbyusingthestandardx+I*yformat.Oneimportantfeatureofthissystemisthattheàoating-pointrep-resentationofzero,0.,retainsitsarithmeticsignincomputations.Thatis,Mapledistinguishesbetween+0.and-0.whennecessary.Inmostsituations,thisdiÞerenceisirrelevant,butwhendealingwithfunctionssuchasln(x),whichhaveadiscontinuityacrossthenegativerealaxis,preservingthesignoftheimaginarypartofanumberonthenegativerealaxisisimportant.Formoreintricateapplications,MapleimplementsextensionsoftheIEEE754notionofanumericevent,andprovidesfacilitiesformoni-toringeventsandtheirassociatedstatusàags.Tolearnmoreaboutthissystem,referto?numerics.RoundoÞErrorWhenyouperformàoating-pointarithmetic,whetherusingsoftwareorhardwareàoats,youareusingapproximatenumbersratherthanpre-ciserealnumbersorexpressions.Maplecanworkwithexact(symbolic)expressions.ThediÞerencebetweenanexactrealnumberanditsàoating-pointapproximationiscalledtheroundoÞerror.Forexample,supposeyourequestaàoating-pointrepresentationof¹.>pi:=evalf(Pi);¹:=3:141592654Mapleroundstheprecisevalue¹totensignißcantdigitsbecauseDigitsissettoitsdefaultvalueof10.YoucanapproximatetheroundoÞerrorabovebytemporarilyincreasingthevalueofDigitsto15.>evalf[15](Pi-pi);0:41021109RoundoÞerrorsarisefromtherepresentationofinputdata,andasaresultofperformingarithmeticoperations.Eachtimeyouperformanarithmeticoperationontwoàoating-pointnumbers,theinßnitely-precise 4.3Floating-PointModelsinMaple¯237resultisgenerallynotrepresentableintheàoating-pointnumbersystemandthereforethecomputedresultalsohasanassociatedroundoÞerror.Forexample,supposeyoumultiplytwoten-digitnumberswithDigits=10.Theresultcanhavenineteenortwentydigits,butMaplestoresonlytheßrsttendigits.>1234567890*1937128552;2391516709101395280>evalf(1234567890)*evalf(1937128552);0:23915167091019Wheneveryouapplyoneofthefourbasicarithmeticoperations(addi-tion,subtraction,multiplication,division,orsquareroot)totwoàoating-pointnumbers,theresultisthecorrectlyroundedrepresentationoftheinßnitelypreciseresult,unlessoveràoworunderàowoccurs.Ofcourse,Maplemayneedtocomputeanextradigitortwobehindthescenestoensurethattheansweriscorrect.Evenso,sometimesasurprisingamountoferrorcanaccumulate,particularlywhensubtractingtwonumberswhichareofsimilarmag-nitude.Inthefollowingcalculation,theaccuratesumofx,y,andzisy=3:141592654.>x:=evalf(987654321);x:=0:987654321109>y:=evalf(Pi);y:=3:141592654>z:=-x;z:=0:987654321109>x+y+z;3:1 238¯Chapter4:NumericalProgramminginMapleThisisknownascatastrophiccancellation.Duringthesubtractiontheeightleadingdigitscancelout,leavingonlytwosignißcantdigitsintheresult.OneadvantageofMaplesoftwareàoats,incontrasttoßxed-precisionàoating-pointnumberssystems,isthattheusercanincreasetheprecisiontoreduceroundoÞerrors.Forexample,increasingDigitsto20dramat-icallyimprovestheresult.>Digits:=20;Digits:=20>x+y+z;3:141592654Employstandardnumericalanalysistechniquestoavoidlargeerrorsaccumulatingincalculations.Often,reorderingtheoperationsleadstoamoreaccurateßnalresult.Forexample,whencomputingasum,addthenumberswiththesmallestmagnitudesßrst.4.4ExtendingtheevalfCommandTheevalfcommandcanevaluatemanyfunctionsandconstants,suchassinandPi.Youcanalsodeßnecustomfunctionsorconstants,andextendevalfbyaddinginformationabouthowtocomputesuchfunctionsorconstants.DeßningNewConstantsYoucandeßneanewconstantandwriteproceduresthatmanipulatethisconstantsymbolically.Youcanthenwriteaprocedurethatcalculatesaàoating-pointapproximationoftheconstanttoanynumberofdigits.Ifyouassigntheprocedureanameoftheform`evalf/constant/name`,Mapleinvokestheprocedurewhenyouuseevalftoevaluateanexpres-sioncontainingtheconstant,name.ExampleLetthenameMyConstrepresentthefollowinginßniteseries:X1(1)i¹iMyConst=2ii!i=1 4.4ExtendingtheevalfCommand¯239Youcancalculateapproximationstotheseriesinmanyways;thefollowingprocedureisoneimplementation.Notethatifaiistheithterminthesum,thenai+1=ai(¹=2)=igivesthenextterm.¯YoucancalculateanapproximationtotheseriesbyaddingtermsuntiltheMaplemodelforsoftwareàoating-pointnumberscannotdis-tinguishsuccessivepartialsums.¯Usingnumericalanalysis,youcanprovethatthisalgorithmcalcu-latesanapproximationofMyConstaccuratetothenumberofdigitsspecißedbyDigits,ifyouusetwoextradigitsinsidethealgorithm.ThefollowingprocedureincrementsDigitsbytwoandusesevalftoroundtheresulttothepropernumberofdigitsbeforereturning.TheproceduredoesnothavetoresetthevalueofDigitsbecauseDigitsisanenvironmentvariable,whichisautomaticallyresetafterexecutingtheprocedure.>`evalf/constant/MyConst`:=proc()>locali,term,halfpi,s,old_s;>Digits:=Digits+2;>halfpi:=evalf(Pi/2);>old_s:=1;>term:=1.0;>s:=0;>forifrom1whiles<>old_sdo>term:=-term*halfpi/i;>old_s:=s;>s:=s+term;>enddo;>evalf[Digits-2](s);>endproc:WhenyouinvokeevalfonanexpressioncontainingMyConst,Mapleinvokes`evalf/constants/MyConst`tocalculateanapproximatevalue.>evalf(MyConst);0:7921204237>evalf[40](MyConst);0:7921204236492380914530443801650212299661Youcanexpresstheparticularconstant,MyConst,inclosedformand,inthiscase,youcanusetheclosed-formformulatocalculateapproxima-tionstoMyConstmoreeáciently. 240¯Chapter4:NumericalProgramminginMaple>Sum((-1)^i*Pi^i/2^i/i!,i=1..infinity);X1(1)i¹i2ii!i=1>value(%);1e(1=2¹)e(1=2¹)>expand(%);1p1e¹>evalf(%);0:7921204237DeßningNewFunctionsIfyoudeßnenewfunctions,youcanwriteproceduresthatcalculatenu-mericalapproximationstothefunctionvalues.WhenyouinvokeevalfonanexpressioncontaininganunevaluatedcalltoafunctionF,Maplecallstheprocedure`evalf/F`ifsuchaprocedureexists.Considerthefunctionx7!(xsin(x))=x3.>MyFcn:=x->(x-sin(x))/x^3;xsin(x)MyFcn:=x!x3Thisfunctionisnotdeßnedatx=0,butyoucanextenditasacontinuousfunctionbyplacingthelimitingvalueintheMyFcnremembertable.>MyFcn(0):=limit(MyFcn(x),x=0);1MyFcn(0):=6 4.4ExtendingtheevalfCommand¯241Forsmallvaluesofx,sin(x)isalmostequaltox,sothesubtractionxsin(x)inthedeßnitionofMyFcncanleadtoinaccuraciesduetocatas-trophiccancellation.Whenyouevaluatevbelowtotendigits,onlytheßrsttwoarecorrect.>v:='MyFcn'(0.000195);v:=MyFcn(0:000195)>evalf(v);0:1618368482>evalf(v,2*Digits);0:16666666634973617222IfyoudependonaccuratenumericalapproximationsofMyFcn,youmustwriteacustomproceduretocomputethem.YoucouldwritesuchaprocedurebyexploitingtheseriesexpansionofMyFcn.>series(MyFcn(x),x=0,11);11214168x+xx+O(x)61205040362880Thegeneraltermintheseriesisx2ia=(1)i;iµ0:i(2i+3)!Notethatai=ai1x2=((2i+2)(2i+3)).¯Forsmallvaluesofx,youcanthencalculateanapproximationtoMyFcn(x)byaddingtermsuntiltheMaplemodelforsoftwareàoating-pointnumberscannotdistinguishsuccessivepartialsums.¯Forlargervaluesofx,catastrophiccancellationisnotaproblem,soyoucanuseevalftoevaluatetheexpression.¯Usingnumericalanalysis,youcanprovethatthisalgorithmcalculatesanapproximationofthefunctionvalueaccuratetothenumberofdigitsspecißedbyDigits,ifyouusethreeextradigitsinsidethealgorithm. 242¯Chapter4:NumericalProgramminginMapleThefollowingprocedureincrementsDigitsbythreeandusesevalftoroundtheresulttothepropernumberofdigitsbeforereturning.>`evalf/MyFcn`:=proc(xx::algebraic)>localx,term,s,old_s,xsqr,i;>x:=evalf(xx);>Digits:=Digits+3;>iftype(x,numeric)andabs(x)<0.1then>xsqr:=x^2;>term:=evalf(1/6);>s:=term;>old_s:=0;>forifrom1whiles<>old_sdo>term:=-term*xsqr/((2*i+2)*(2*i+3));>old_s:=s;>s:=s+term;>enddo;>else>s:=evalf((x-sin(x))/x^3);>endif;>eval[Digits-3](s);>endproc:WhenyouinvokeevalfonanexpressioncontaininganunevaluatedcalltoMyFcn,Mapleinvokes`evalf/MyFcn`.>evalf('MyFcn'(0.000195));0:1666666663498RecodethesymbolicversionofMyFcnsothatittakesadvantageof`evalf/MyFcn`iftheargumentisaàoating-pointnumber.>MyFcn:=proc(x::algebraic)>iftype(x,float)then>evalf('MyFcn'(x));>else>(x-sin(x))/x^3;>endif;>endproc:Theevalfcommandautomaticallylooksfor`evalf/MyFcn`whenusedintheevalf(`MyFcn`)syntax.>MyFcn(0):=limit(MyFcn(x),x=0);1MyFcn(0):=6 4.5UsingtheMatlabPackage¯243NowyoucanproperlyevaluateMyFcnwithnumericaswellassymbolicarguments.>MyFcn(x);xsin(x)x3>MyFcn(0.099999999);0:1665833531735>MyFcn(0.1);0:16658335317001.5ExtendingMapledescribeshowtoextendmanyotherMaplecommands.4.5UsingtheMatlabPackageAnotherwaytoaccomplishnumericalcomputationsinMapleistousetheMatlabpackage,whichprovidesaccesstoseveralMATLAB•rbuilt-infunctions.Note:YoumusthaveacopyofMATLABproperlyinstalledonyourcomputer.Themathematicalfunctionsprovidedare:¯chol:Choleskyfactorization¯defined:testwhethervariableexists¯det:determinant¯dimensions:computedimensionsofmatrix¯eig:eigenvaluesandeigenvectors¯evalM:evaluateexpression¯fft:discreteFouriertransforms¯getvar:getnumericarrayormatrix¯inv:matrixinverse 244¯Chapter4:NumericalProgramminginMaple¯lu:LUdecomposition¯ode45:solveordinarydiÞerentialequation¯qr:QRorthogonal-triangulardecomposition¯size:computesizeofmatrix¯square:determinewhethermatrixissquare¯transpose:matrixtranspositionSomesupportandutilitycommandsareprovided.MATLABconvertsallMaplestructurestoitsrepresentationofhardwareàoating-pointarraysbeforeitperformsanycomputations.TheresultsareusuallyArrayswithdatatypeàoat[8](thatis,hardwareàoatentries).Formoreinformation,referto?Arrayand?Matrix.FormoreinformationonallthesecommandsandtheMatlabpack-ageingeneral,referto?Matlab.TolearnhowtostarttheMATLABapplicationfromaMaplesession,referto?Matlab[openlink].4.6ConclusionWithnumericaltechniques,youcansolveequationswhichareother-wiseunsolvable,investigatethepropertiesofcomplicatedsolutions,andquicklyobtainnumericalestimates.Symboliccalculationsgivepreciserepresentations,butinsomecasescanbeexpensivetocomputeevenwithatoolaspowerfulasMaple.Attheotherextreme,hardwareàoating-pointarithmeticallowsyoufastcom-putationdirectlyfromMaple.Thisinvolves,however,limitedaccuracy.Softwareàoating-pointoÞersabalance.Aswellassometimesbeingmuchfasterthansymboliccalculations,youalsohavetheoptiontocontroltheprecisionofyourcalculations,thusexertingcontrolovererrors.Softwareàoating-pointcalculationsandrepresentationsmimictheIEEE754standardrepresentationclosely,exceptforthegreatadvan-tageofarbitraryprecision.Thesimilaritywiththispopularstandardallowsyoutoreadilyapplyaccumulationoferrorandnumericalanalysisprinciplescontainedinnumeroustextsandpapers. 5ProgrammingwithMapleGraphicsMaplePlotsMaplehasawiderangeofpackagesandproceduresforgenerating2-Dand3-Dplots.Theseinclude:¯Theplotandplot3dproceduresforgeneratingbasic2-Dand3-Dplots,respectively¯Theplotspackageforgeneratingspecializedplots,suchasvectorßeldplotsorcontourplots¯TheplottoolspackageforgeneratinggraphicalobjectsforinclusioninplotsInadditiontothoselistedabove,manyotherMaplepackages,suchasDEtools,Student,andstats,includespecializedproceduresforplottinginspecißccontexts.Theseproceduresrequireasargumentsinformationthatallowsthenu-mericalplotdatavaluestobecomputed.Theyalsoacceptoptionsthatsetattributessuchascolour,shading,andaxesstyle.CreatingPlottingProceduresThepurposeofthischapteristopresentsomeoftheMapleplottingpro-cedures,describethestructureoftheiroutput,anddescribewaysinwhichyoucanusethemtocreatecustomprocedures.Thischapterincludesba-sicinformationaboutargumentconventions,defaultsettings,andoptionprocessing.InThisChapter¯BasicPlottingProcedures245 246¯Chapter5:ProgrammingwithMapleGraphics¯ProgrammingwithPlottingLibraryProcedures¯MaplePlotDataStructures¯ProgrammingwithPlotDataStructures¯ProgrammingwiththeplottoolsPackage¯VectorFieldPlots¯GeneratingGridsofPoints¯Animation¯ProgrammingwithColor5.1BasicPlottingProceduresThissectionillustrates:¯Typicalcallingsequencesofplottingprocedures¯Propertiesthatarecommontoplottingprocedures¯Usingoperatorsorproceduresversusexpressionsintheindependentvariablestodeßneplots¯SpecifyingoptionalinformationManyMapleplottingprocedures,includingplot,plot3d,andsomecommandsintheplotspackage,acceptinputinoneoftwoforms:ex-pressionsinoneortwoindependentvariables,orexpressionsinvolvingproceduresandoperators.Forexample,theinputcanbetheexpres-siona2bb3+1invariablesaandb,ortheexpressionp+q,wherepandqareprocedures.Thefollowingcommandgeneratesa3-Dplotofthesurfacedeßnedbysin(x)sin(y).Theindependentvariablesarexandy.>plot3d(sin(x)*sin(y),x=0..4*Pi,y=-2*Pi..2*Pi); 5.1BasicPlottingProcedures¯247Youcanplotthesamesurfacebyßrstdeßningtwoproceduresthateachtaketwoarguments:>p:=(x,y)->sin(x):q:=(x,y)->sin(y):andthenprovidingp£qastheßrstargumenttotheplot3dcommand:>plot3d(p*q,0..4*Pi,-2*Pi..2*Pi);Intheßrstexample,theplot3dprocedurerecognizesthattheßrstargumentisanexpressioninxandybecausethesecondandthirdargu-mentshavetheformsx=rangeandy=range.Inthesecondexample,thesecondandthirdargumentsaresimplyrangesandcontainnovariablenames.Workingwithexpressionsinindependentvariablesissimple,butinmanycases,proceduresandoperatorsprovideabettermechanismfordeßningplots.Weusethetermoperatorformtorefertotheformofthecallingsequencethatacceptsproceduresandoperators.Example1Thefollowingprocedureacceptsacomplexstartingpointc=x+iyandcomputestherequirednumberofiterations(toamaximumof10)forthesequencezn+1=zn2+ctoexitthediskofradius2.>mandelbrotSet:=proc(x,y)>localz,m;>z:=evalf(x+y*I);>m:=0;>to10whileabs(z)<2do>z:=z^2+(x+y*I);>m:=m+1;>enddo:>m;>endproc: 248¯Chapter5:ProgrammingwithMapleGraphicsYoucanusetheproceduretocomputea3-DMandelbrotsetona50¢50grid.>plot3d(mandelbrotSet,-3/2..3/2,-3/2..3/2,grid=[50,50]);AlteringaPlotAfteryouissueaplottingcommand,theresultisdisplayedonthedefaultplottingdevice(intheworksheet,generally,thecurrentwindow).Youcanusethetoolsavailableintheworksheetinterfacetointeractivelyaltertheplotcharacteristics,suchasdrawingstyle,axesstyle,andorientation.Youcanalsospecifythisinformationusingoptionalargumentstoplot3d.>plot3d(sin(x)*sin(y),x=-2*Pi..2*Pi,y=-2*Pi..2*Pi,>style=patchnogrid,axes=frame);10.50–0.5–1–6–6–4–4–2–200y22x4466>plot3d(mandelbrotSet,-1.5..1.5,-1.5..1.5,grid=[50,50],>style=wireframe,orientation=[143,31]); 5.2ProgrammingwithPlottingLibraryProcedures¯249MostMapleplottingproceduresacceptoptionalargumentsintheformname=option.Someoftheseoptions,suchasthegridoptionusedinpreviousexamples,aÞectthenumericaldatageneratedbytheplottingcommands.Youcanuseotheroptionstospecifyvisualinformationsuchasshading,linestyle,andcoloring.Foradescriptionofalloptionsavailablefor2-Dand3-Dplotting,referto?plot/optionsand?plot3d/options.Itisrecommendedthatanyplottingprocedureyoucreateallowuserstospecifyasimilarsetofoptions.Whenwritingprogramsthatcallex-istingMapleplottingprocedures,simplypasstheoptionalargumentsdi-rectlytotheMapleprocedures.5.2ProgrammingwithPlottingLibraryProceduresThissectiongivesexamplesofprogrammingwithMapleplottingproce-dures.PlottingaLoopConsidertheproblemofplottingaloopfromalistofdata.>L1:=[[5,29],[11,23],[11,36],[9,35]];L1:=[[5;29];[11;23];[11;36];[9;35]]Theplotcommanddrawslinesbetweenthelistedpoints.>plot(L1); 250¯Chapter5:ProgrammingwithMapleGraphics36343230282624567891011Todrawalinefromthelastpointtotheßrstpoint,appendtheßrstpointinL1totheendofL1.>L2:=[op(L1),L1[1]];L2:=[[5;29];[11;23];[11;36];[9;35];[5;29]]>plot(L2);36343230282624567891011Example1Theprocedureloopplotautomatestheprevioustechnique.>loopplot:=proc(L)>plot([op(L),L[1]]);>endproc;loopplot:=proc(L)plot([op(L);L1])endprocTheloopplotprocedurehastwoshortcomings.¯Itshouldverifythattheinput,L,isalistofpoints,whereeachpointisalistoftwoconstants.Thatis,itshouldverifythatLisoftypelist([constant,constant]). 5.2ProgrammingwithPlottingLibraryProcedures¯251¯Itshouldacceptappropriateplottingoptionsandpassthemtotheplotprocedure.Example2Insideaprocedure,argsisthesequenceofargumentspassedtotheprocedure,andnargsisthenumberofarguments.Thus,args[2..nargs]isthesequenceofoptionspassedtoloopplot.Theloopplotprocedureshouldpassallbutitsßrstargument,L,directlytoplot.>loopplot:=proc(L::list([constant,constant]))>plot([op(L),L[1]],args[2..nargs]);>endproc:Thisversionofloopplotgivesaninformativeerrormessageifyoutrytospecifyimproperarguments.Italsoacceptsplottingoptions.>loopplot([[1,2],[a,b]]);Error,invalidinput:loopplotexpectsits1stargument,L,tobeoftypelist([constant,constant]),butreceived[[1,2],[a,b]]>loopplot(L1,thickness=10);36343230282624567891011Exercise1.Improvetheloopplotproceduresothatitacceptstheemptylistasinput.ARibbonPlotProcedureThissectionillustratesthecreationofaribbonplotproceduretogener-atea3-Dplotfromalistofexpressionsintwovariablesorfromalistofprocedures. 252¯Chapter5:ProgrammingwithMapleGraphicsExample3Theribbonplotprocedureusestheplots[display]pro-ceduretodisplaytheplots.Theribbonplotprocedureexplicitlycallstheplots[display]procedureusingitsfullnamesothatribbonplotworkswhentheshortformsoftheprocedurenamesintheplotspackagearenotloaded.Theexamplesinthissectionusethehasoptionproceduretoprocessoptions.Thehasoptioncommanddetermineswhetheracertainoptionispresent.Intheribbonplotprocedure,hasoptionreturnsfalseifnumpointsisnotamongtheoptionslistedinopts.Ifoptscontainsanumpointsoption,thenhasoptionassignsthevalueofthenumpointsoptionton,andreturnstheremainingoptionsinthefourthargument(inthiscase,modifyingthevalueofthelistopts).>ribbonplot:=proc(Flist,r1::name=range)>locali,m,p,y,n,opts;>opts:=[args[3..nargs]];>ifnothasoption(opts,'numpoints','n','opts')>thenn:=25#defaultnumpoints>endif;>>m:=nops(Flist);>#op(opts)isanyadditionaloptions>p:=seq(plot3d(Flist[i],r1,y=(i-1)..i,>grid=[n,2],op(opts)),>i=1..m);>plots[display](p);>endproc:Theribbonplotprocedureusesthenumberofgridpointsspecißed.>ribbonplot([cos(x),cos(2*x),sin(x),sin(2*x)],>x=-Pi..Pi,numpoints=16);Theinputtoribbonplotmustbealistofexpressions.Youcanextendribbonplotsothatitalsoacceptsalistofprocedures.Onediácultywith 5.2ProgrammingwithPlottingLibraryProcedures¯253thisextensionisthatyoumustcreatetwo-argumentproceduresfromone-argumentprocedures,whichwasnotrequiredinribbonplotinExample3.Todothis,createanauxiliaryprocedure,extend,thatusestheunapplycommand.>extend:=proc(f)>localx,y;>unapply(f(x),x,y);>endproc:Forexample,theextendprocedureconvertstheone-argumentpro-cedurerepresentingtheR!Rmathematicalfunctionx7!cos(2x)toatwo-argumentprocedure.>p:=x->cos(2*x):>q:=extend(p);q:=(x;y)!cos(2x)Example4Thefollowingisthenewribbonplotcode.>ribbonplot:=proc(Flist,r1::{range,name=range})>locali,m,p,n,opts,newFlist;>opts:=[args[3..nargs]];>iftype(r1,range)then>#Operator-forminput.>ifnothasoption(opts,'numpoints','n','opts')>thenn:=25#defaultnumpoints>endif;>m:=nops(Flist);>#Provideoperator-forminputtoplot3d.>p:=seq(plot3d(extend(Flist[i]),r1,(i-1)..i,>grid=[n,2],op(opts)),>i=1..m);>plots[display](p);>else>#Expressionsinvariablelhs(r1).Converteachtoa>#procedure.>newFlist:=map(unapply,Flist,lhs(r1));>#Uselhs(r1)asthedefaultx-axislabel.>opts:=['labels'=[lhs(r1),"",""],>args[3..nargs]];>ribbonplot(newFlist,rhs(r1),op(opts))>endif>endproc:Thefollowingisaribbonplotofthreefunctions.>ribbonplot([cos,sin,cos+sin],-Pi..Pi); 254¯Chapter5:ProgrammingwithMapleGraphics5.3MaplePlotDataStructuresMaplegeneratesplotsbysendingtheuserinterfaceaPLOTorPLOT3Ddatastructure,whichisinfactanunevaluatedfunctioncall.Theinformationincludedinsidethesestructuresspecißestheobjectstoplot.EveryMapleplottingprocedurecreatessuchastructure.Thisprocessisdescribedbelowandshownschematicallyinßgure5.1.1.AMaplecommandproducesaPLOTstructureandpassesittotheuserinterface.2.Intheuserinterface,MapleconstructsprimitivegraphicobjectsbasedonthePLOTstructure.3.Maplethenpassestheseobjectstothechosendevicedriverfordisplay. 5.3MaplePlotDataStructures¯255Figure5.1HowplotsaredisplayedYoucanassigntheplotdatastructurestovariables,transformthemintootherstructures,savethem,orprintthem.Example1Usethelprintcommandtoline-printaplotstructure.>lprint(plot(2*x+3,x=0..5,numpoints=3,adaptive=false));PLOT(CURVES([[0.,3.],[2.61565849999999989,8.2313170000000066],[5.,13.]],COLOUR(RGB,1.0,0.,0.)),AXESLABELS("x",""),VIEW(0...5.,DEFAULT))ThepreviousplotcommandgeneratesaPLOTdatastructurethatincludestheinformationforasinglecurvedeßnedbythreepoints.ThecurveiscoloredwithRGBvalues(1:0;0;0),whichcorrespondtored.Theplothasahorizontalaxisrunningfrom0to5.Maple,bydefault,deter-minesthescalealongtheverticalaxesusingtheinformationthatyouprovideintheverticalcomponentsofthecurve.Theadaptive=falseandnumpoints=3optionsturnoÞadaptivesamplingandensurethatthecurveconsistsofonlythreepoints.Example2Thisexampleisthegraphofz=xyovera3¢4grid.ThePLOT3Dstructurecontainsagridofzvaluesovertherectangularregion[0;1]¢[0;2].>lprint(plot3d(x*y,x=0..1,y=0..2,grid=[3,4]));PLOT3D(GRID(0...1.,0...2.,Array(1..3,1..4,{(2,2)=.333333333333333314,(2,3)=.666666666666666629,(2,4)=1.,(3,2)=.666666666666666629,(3,3)=1.33333333333333326,(3,4)=2.},datatype=float[8],storage=rectangular,order=C_order)),AXESLABELS(x,y,"")) 256¯Chapter5:ProgrammingwithMapleGraphicsThestructureincludeslabelsxandyforthex-axisandy-axisbutnolabelforthez-axis.Example3Thisexampleisagainthegraphofz=xybutincylindricalcoordinates.ThePLOT3Dstructurenowcontainsameshofpointsthatdeßnethesurface,alongwiththeinformationthattheplottingdevicemustdisplaythesurfaceinapointstyle.>lprint(plot3d(x*y,x=0..1,y=0..2,grid=[3,2],>coords=cylindrical,style=point));PLOT3D(MESH(Array(1..3,1..2,1..3,{(1,2,3)=2.,(2,2,1)=.877582561890372758,(2,2,2)=.479425538604203006,(2,2,3)=2.,(3,2,1)=1.08060461173627952,(3,2,2)=1.68294196961579300,(3,2,3)=2.},datatype=float[8],storage=rectangular,order=C_order)),STYLE(POINT))BecausetheplotisnotinCartesiancoordinatesandtherearenode-faultlabels,thePLOT3DstructuredoesnotcontainanAXESLABELSstruc-ture.ThePLOTDataStructureYoucanconstructandmanipulateaplotdatastructuredirectlytocreate2-Dand3-Dplots.ThedatastructureisanunevaluatedPLOTorPLOT3Dfunctioncallwithargumentscontaininginformationthatdeterminestheobjectsthattheplottingdevicedisplays.Mapleevaluatestheexpression,forexample,>PLOT(CURVES([[0,0],[2,1]]));10.80.60.40.200.511.52andpassesittotheMapleinterface,whichdeterminesthatthisisaplotdatastructure.TheMapleinterfacethendismantlesthecontentsandpassestheinformationtoaplotdriver,whichdeterminesthegraphical 5.3MaplePlotDataStructures¯257informationthatitrenderstotheplottingdevice.InthepreviousexamplePLOTstructure,theresultisasinglelinefromtheorigintothepoint(2;1).TheCURVESdatastructureconsistsofoneormorelistsofpointseachrepresentingacurve,alongwithoptionalarguments(forexample,linestyleorlinethicknessinformation).Thus,thecommands>n:=200:>points:=[seq([2*cos(i*Pi/n),sin(i*Pi/n)],i=0..n)]:>PLOT(CURVES(evalf(points)));10.80.60.40.2–2–1012generatetheplotofasequenceofn+1pointsintheplane.ThepointsfoundinsidethePLOTdatastructuremustbenumeric.Ifyouomittheevalfstatement,thennon-numericobjectswithinthePLOTstructure,suchassin(¹=200),causeanerror.>PLOT(CURVES(points));Plottingerror,non-numericvertexdefinition>type(sin(Pi/n),numeric);falseHence,noplotisgenerated.ArgumentsInsideaPLOTStructureAPLOTstructurehasthefollowingform:(Objects,Options)whereObjectsisasequenceofoneormoreplotobjectsoftheformObjectName(ObjectData,Options)andOptionsisasequenceofzeroormoreplotoptionsoftheformOptionName(OptionValue). 258¯Chapter5:ProgrammingwithMapleGraphicsNote:PlotoptionscanappearasargumentsofthePLOTstructuresorasargumentsofplotobjectstructures.Ifalocaloptionappearsinsideaplotobjectstructure,itappliestoonlythatobjectandoverridesanyvalueofaglobaloptionofthesamename.PlotObjectStructuresAsshownpreviously,plotobjectshavetheformObjectName(ObjectData,Options).ObjectNamecanbeCURVES,POLYGONS,POINTS,orTEXT,whileObjectDatacontainsthebasicnu-mericaldatathatdeßnesthegeometryoftheobject.Inthefollowingdescription,pointreferstoalistoftwonumericvalues,[x;y],represent-ingx-andy-coordinatesofapointintheplane.¯WhenObjectNameisCURVES,ObjectDataconsistsofoneormorelistsofpointswhereeachlistspecißesasinglecurveintheplane.¯WhenObjectNameisPOLYGONS,ObjectDataconsistsofoneormorelistsofpointswhereeachlistspecißestheverticesofasinglepolygonintheplane.¯WhenObjectNameisPOINTS,ObjectDataconsistsofoneormorepoints.¯WhenObjectNameisTEXT,ObjectDataconsistsofapointfollowedbyanamerepresentingthetextstring.PlotOptionStructuresPlotoptionshavetheformOptionName(OptionValue).ExamplesofoptionstructuresareAXESTYLE(BOX),COLOR(RGB,0.0,1.0,0.0),andVIEW(-4..4,-1..1).Foracompletelistoftheplotoptionstruc-turesandthevalueseachstructureaccepts,referto?plot/structure.Someplotoptionscannotbespecißedasalocaloptionwithinaplotobjectstructure.Forexample,theAXESSTYLEoptionmustbeaglobaloption,whileadiÞerentCOLORoptioncanbespecißedforeachplotobject.Example4Thisexampledemonstratesasimplewaytogenerateaßlledhistogramofsixty-threevaluesofthefunctiony=sin(x)from0to6:3,witheachtrapezoidcoloredindividuallybytheHUEvaluecorrespondingtoy=jcos(x)j.>p:=i->[[(i-1)/10,0],[(i-1)/10,sin((i-1)/10)],>[i/10,sin(i/10)],[i/10,0]]:Thefunctionp(i)returnstheverticesoftheithtrapezoidinalist.Forexample,p(2)containstheverticesofthesecondtrapezoid. 5.3MaplePlotDataStructures¯259>p(2);111111[[;0];[;sin()];[;sin()];[;0]]101010555Deßnetheprocedurehtogivethecolorofeachtrapezoid.>h:=i->abs(cos(i/10)):>PLOT(seq(POLYGONS(evalf(p(i)),COLOR(HUE,evalf(h(i)))),>i=1..63));10.50123456–0.5–1ASumPlotYoucancreateproceduresthatdirectlybuildPLOTdatastructures.Forexample,givenanunevaluatedsum,youcancomputethepartialsumsandplacethevaluesinaCURVESstructure.>s:=Sum(1/k^2,k=1..10);X101s:=k2k=1Usethetypematchcommandtoseparatetheunevaluatedsumintoitscomponents.>typematch(s,'Sum'(term::algebraic,>n::name=a::integer..b::integer));trueThetypematchcommandassignsthepartsofthesumtothegivennames.>term,n,a,b; 260¯Chapter5:ProgrammingwithMapleGraphics1;k;1;10k2Nowcalculatethepartialsums.>sum(term,n=a..a+2);4936Thefollowingdeßnesaprocedure,psum,thatcalculatesaàoating-pointvalueofthemthpartialsum.>psum:=evalf@unapply(Sum(term,n=a..(a+m)),m);À!1+Xm1psum:=evalf@m!k2k=1Nowcreatethenecessarylistofpoints.>points:=[seq([[i,psum(i)],[i+1,psum(i)]],>i=1..(b-a+1))];points:=[[[1;1:250000000];[2;1:250000000]];[[2;1:361111111];[3;1:361111111]];[[3;1:423611111];[4;1:423611111]];[[4;1:463611111];[5;1:463611111]];[[5;1:491388889];[6;1:491388889]];[[6;1:511797052];[7;1:511797052]];[[7;1:527422052];[8;1:527422052]];[[8;1:539767731];[9;1:539767731]];[[9;1:549767731];[10;1:549767731]];[[10;1:558032194];[11;1:558032194]]]>points:=map(op,points); 5.3MaplePlotDataStructures¯261points:=[[1;1:250000000];[2;1:250000000];[2;1:361111111];[3;1:361111111];[3;1:423611111];[4;1:423611111];[4;1:463611111];[5;1:463611111];[5;1:491388889];[6;1:491388889];[6;1:511797052];[7;1:511797052];[7;1:527422052];[8;1:527422052];[8;1:539767731];[9;1:539767731];[9;1:549767731];[10;1:549767731];[10;1:558032194];[11;1:558032194]]Thislisthasthecorrectform.>PLOT(CURVES(points));1.551.51.451.41.351.31.25246810Thesumplotprocedureautomatesthistechnique.>sumplot:=proc(s)>localterm,n,a,b,psum,m,points,i;>iftypematch(s,'Sum'(term::algebraic,>n::name=a::integer..b::integer))then>psum:=evalf@unapply(Sum(term,n=a..(a+m)),m);>points:=[seq([[i,psum(i)],[i+1,psum(i)]],>i=1..(b-a+1))];>points:=map(op,points);>PLOT(CURVES(points));>else>error"expectingaSumstructureasinput">endif>endproc:Thefollowingisasumplotofanalternatingseries.>sumplot(Sum((-1)^k/k,k=1..25)); 262¯Chapter5:ProgrammingwithMapleGraphics–0.5–0.55–0.6–0.65–0.7–0.75–0.8510152025Thelimitofthissumisln2.>Sum((-1)^k/k,k=1..infinity):%=value(%);X1k(1)=ln(2)kk=1ThePLOT3DDataStructureThe3-DplottingdatastructurehasaformsimilartothePLOTdatastructure.ThefollowingMapleexpressiongeneratesa3-Dplotofthreelinesandaxesoftypeframe.AxesaregeneratedusingAXESSTYLE.>PLOT3D(CURVES([[3,3,0],[0,3,1],>[3,0,1],[3,3,0]]),>AXESSTYLE(FRAME));10.80.60.40.20000.50.5111.51.5222.52.533Thefollowingprocedurecreatestheyellowsidesofabox.>yellowsides:=proc(x,y,z,u)>#(x,y,0)=coordinatesofacorner.>#z=heightofbox>#u=sidelengthofbox 5.3MaplePlotDataStructures¯263>POLYGONS(>[[x,y,0],[x+u,y,0],[x+u,y,z],[x,y,z]],>[[x,y,0],[x,y+u,0],[x,y+u,z],[x,y,z]],>[[x+u,y,0],[x+u,y+u,0],[x+u,y+u,z],[x+u,y,z]],>[[x+u,y+u,0],[x,y+u,0],[x,y+u,z],[x+u,y+u,z]],>COLOR(RGB,1,1,0));>endproc:Theredtopproceduregeneratesaredlidforthebox.>redtop:=proc(x,y,z,u)>#(x,y,z)=coordinatesofacorner.>#u=sidelengthofsquare>POLYGONS([[x,y,z],[x+u,y,z],[x+u,y+u,z],[x,y+u,z]],>COLOR(RGB,1,0,0));>endproc:Todisplaythesidesandthetop,placetheminaPLOT3Dstructure.>PLOT3D(yellowsides(1,2,3,0.5),>redtop(1,2,3,0.5),>STYLE(PATCH));Usingyellowsidesandredtop,youcancreatea3-Dhistogramplot.Thefollowingisthehistogramcorrespondingtoz=1=(x+y+4),for0´x´4and0´y´4.>sides:=seq(seq(yellowsides(i,j,1/(i+j+4),0.75),>j=0..4),i=0..4):>tops:=seq(seq(redtop(i,j,1/(i+j+4),0.75),>j=0..4),i=0..4):Histogramsdisplaywellinbox-styleaxes.>PLOT3D(sides,tops,STYLE(PATCH),AXESSTYLE(BOXED)); 264¯Chapter5:ProgrammingwithMapleGraphics0.250.20.150.10.0500011223344Tocreatealistbarchart3dprocedurewhich,foragivenlistoflistsofheights,givesa3-Dbarchartforitsoutput,modifythepreviouscon-struction.ObjectsInsideaPLOT3DDataStructureTheformatofaPLOT3DstructureissimilartothatofaPLOTstructure.TheallowableplotobjectsincludealltheobjectsthatcanappearinPLOTstructures.Ofcourse,pointsarespecißedbyalistofthreenumericalvalues,[x;y;z],insteadoftwo.ThreeadditionalplotobjectscanappearinaPLOT3Dstructure:GRID,MESH,andISOSURFACE.GRIDisastructurethatdescribesafunctionalgrid.ItconsistsoftworangesdeßningagridinthexÛyplaneandalistoflistsofzvaluesoverthisgrid.Example5Inthisexample,LLcontains4listseachoflength3.There-fore,thegridis4¢3,andxrunsfrom1to3inincrementsof2=3,whereasyrunsfrom1to2inincrementsof1=2.>LL:=[[0,1,0],[1,1,1],[2,1,2],[3,0,1]]:>PLOT3D(GRID(1..3,1..2,LL),AXESLABELS(x,y,z),>ORIENTATION(135,45),AXES(BOXED)); 5.3MaplePlotDataStructures¯26532.521.5z10.50312.51.221.4x1.6y1.51.812TheMESHstructurecontainsalistoflistsofpoints,LL,describingasurfacein3-Dspace.TheMESHstructurerepresentsthequadrilateralsspannedbyLLi;j;LLi;j+1;LLi+1;j;LLi+1;j+1forallmeaningfulvaluesofiandj.Example6Inthisexample,LLcontains3listseachoflength4,thatis,twelvepointsdeßningsixquadrilaterals.>LL:=[[[0,0,0],[1,0,0],[2,0,0],[3,0,0]],>[[0,1,0],[1,1,0],[2.1,0.9,0],>[3.2,0.7,0]],>[[0,1,1],[1,1,1],[2.2,0.6,1],>[3.5,0.5,1.1]]];LL:=[[[0;0;0];[1;0;0];[2;0;0];[3;0;0]];[[0;1;0];[1;1;0];[2:1;0:9;0];[3:2;0:7;0]];[[0;1;1];[1;1;1];[2:2;0:6;1];[3:5;0:5;1:1]]]>PLOT3D(MESH(LL),AXESLABELS(x,y,z),AXES(BOXED),>ORIENTATION(-140,45));10.80.6z0.40.203.5130.82.50.62xy0.411.50.20.500 266¯Chapter5:ProgrammingwithMapleGraphicsTheISOSURFACEstructurecontainssamplesofamathematicalfunc-tionftakenoveraregulargridin3-Dspaceandisrenderedasa3-Dsurfaceapproximatingthezerosurfaceoff.Thedataisanestedlistcontainingvalues[x;y;z;f(x;y;z)]foreachgridpoint(x;y;z).TheGRID,MESH,andISOSURFACEstructuresallowthedatatobeprovidedinaMapleArrayinsteadofalist.Often,Arraydataleadstofasterprocessing.Forbrevity,examplesofISOSURFACEstructuresanddatainArrayformarenotpresentedhere.ForacompletespecißcationofPLOT3Dob-jects,referto?plot3d/structure.AlltheoptionsavailableforPLOTarealsoavailableforPLOT3D.Thereareadditional3-DoptionssuchasGRIDSTYLE,LIGHTMODEL,andAMBIENTLIGHT.Foracompletelistofoptions,referto?plot3d/structure.5.4ProgrammingwithPlotDataStructuresThissectiondescribestoolsforprogrammingatthePLOTandPLOT3Ddatastructurelevel.PlottingdatastructuresallowsdirectaccesstotheMapleplottingfacilities.Theexamplesinsection5.3showedtheextentofthefacilities'power.Thissectionprovidesexamplesthatdescribehowtoprogramatthislowerlevel.WritingGraphicPrimitivesYoucanwriteproceduresthatallowyoutoworkwithplotobjectsatamorefundamentallevel.Forexample,thelineanddiskcommandsintheplottoolspackageprovideamodelforprogrammingprimitivessuchaspoints,lines,curves,circles,rectangles,andarbitrarypolygonsinbothtwoandthreedimensions.Inallcases,youcanspecifyoptions,suchaslineorpatchstyleandcolor,inthesameformatasinotherplottingproceduresinMaple.Example1Intheprocedureline,args[3..nargs]isthesequenceofargumentsthatfollowxandy.>line:=proc(x::list,y::list)>#xandyrepresentpointsineither2-Dor3-D>localopts;>opts:=[args[3..nargs]];>opts:=convert(opts,PLOToptions);>CURVES(evalf([x,y]),op(opts));>endproc: 5.4ProgrammingwithPlotDataStructures¯267Theconvert(...,PLOToptions)commandconvertsuser-levelop-tionstotheformatthatPLOTrequires.>convert([axes=boxed,color=red],PLOToptions);[AXESSTYLE(BOX);COLOUR(RGB;1:00000000;0:;0:)]Example2ThediskprocedureissimilartothelineprocedureinEx-ample1exceptthatyoucanspecifythenumberofpointsthatdiskusestogeneratethedisk.Therefore,diskmusthandletheoptionnumpointsseparately.>disk:=proc(x::list,r::algebraic)>#drawadiskofradiusrcenteredatxin2-D.>locali,n,opts,vertices;>opts:=[args[3..nargs]];>ifnothasoption(opts,numpoints,n,'opts')>thenn:=50;>endif;>opts:=convert(opts,PLOToptions);>vertices:=seq(evalf([x[1]+r*cos(2*Pi*i/n),>x[2]+r*sin(2*Pi*i/n)]),>i=0..n);>POLYGONS([vertices],op(opts));>endproc:Todisplaytwodisksconnectedbyaline,enter:>with(plots):Warning,thenamechangecoordshasbeenredefined>display(disk([-1,0],1/2,color=plum),>line([-1,1/2],[1,1/2]),>disk([1,0],1/2,thickness=3),>scaling=constrained);0.40.2–1.5–1–0.50.511.5–0.2–0.4 268¯Chapter5:ProgrammingwithMapleGraphicsTheoptionstotheindividualobjectsapplytoonlythoseobjects.PlottingGearsExample3showshowyoucanmanipulateplottingdatastructurestoembed2-Dplotsintoa3-Dsetting.Example3Thefollowingprocedurecreatespartoftheboundaryofa2-Dgraphofagear-likestructure.>outside:=proc(a,r,n)>localp1,p2;>p1:=evalf([cos(a*Pi/n),sin(a*Pi/n)]);>p2:=evalf([cos((a+1)*Pi/n),sin((a+1)*Pi/n)]);>ifr=1thenp1,p2;>elsep1,r*p1,r*p2,p2;>endif>endproc:Forexample:>outside(Pi/4,1.1,16);[0:9881327882;0:1536020604];[1:086946067;0:1689622664];[1:033097800;0:3777683623];[0:9391798182;0:3434257839]>PLOT(CURVES([%]),SCALING(CONSTRAINED));0.350.30.250.20.150.939181.013061.08695 5.4ProgrammingwithPlotDataStructures¯269Whenyoudisplaythepiecestogether,youproduceagear.Theop-tionstructureSCALING(CONSTRAINED),whichcorrespondstotheoptionscaling=constrained,ensuresthatthegearappearscircular.>points:=[seq(outside(2*a,1.1,16),a=0..16)]:>PLOT(CURVES(points),AXESSTYLE(NONE),SCALING(CONSTRAINED));FillthisobjectusingthePOLYGONSobject.BecauseMapleassumesthatthepolygonsareconvex,youmustdraweachwedge-shapedsectionofthegearasatriangularpolygon.>a:=seq([[0,0],outside(2*j,1.1,16)],j=0..15):>b:=seq([[0,0],outside(2*j+1,1,16)],j=0..15):>PLOT(POLYGONS(a,b),AXESSTYLE(NONE),SCALING(CONSTRAINED));AddingSTYLE(PATCHNOGRID)totheprecedingstructureandcom-biningitwiththecurvefromtheßrstpicturecreatesaßlledgear-likestructure.Toembedthisinthreedimensions,atathicknessoftunits,usetheutilityproceduresdouble:>double:=proc(L,t)>localu;>[seq([u[1],u[2],0],u=L)],>[seq([u[1],u[2],t],u=L)];>endproc: 270¯Chapter5:ProgrammingwithMapleGraphicswhichtakesalistofverticesandcreatestwocopiesin3-Dspace,theßrstatheight0andthesecondatheightt,andborder:>border:=proc(L1,L2)>locali,n;>n:=nops(L1);>seq([L1[i],L2[i],L2[i+1],L1[i+1]],i=1..n-1),>[L1[n],L2[n],L2[1],L1[1]];>endproc:whichacceptstwolistsofverticesandjoinsthecorrespondingverticesfromeachlistintoverticesthatcomprisequadrilaterals.Youcancreatethetopandbottomverticesofthegearembeddedinto3-Dspaceasfollows.>faces:=>seq(double(p,1/2),>p=[seq([outside(2*a+1,1.1,16),[0,0]],>a=0..16),>seq([outside(2*a,1,16),[0,0]],a=0..16)>]):Thefacesstructureisasequenceofdoubledoutsidevalues.>PLOT3D(POLYGONS(faces));Similarly,thefollowingarepointsontheoutlineofagear.>points:=[seq(outside(2*a,1.1,16),a=0..16)]:>PLOT(CURVES(points),AXESSTYLE(NONE),SCALING(CONSTRAINED)); 5.4ProgrammingwithPlotDataStructures¯271Tocreateverticesofthepolygonsthatcomprisetheborderofthe3-Dgear,doublethesepoints.>bord:=border(double([seq(outside(2*a+1,1.1,16),>a=0..15)],1/2)):>PLOT3D(seq(POLYGONS(b),b=bord));Todisplaythegear,combinethesetwoPLOT3Dstructuresintoasinglestructure.UseSTYLE(PATCHNOGRID)asalocaloptiontothetopandbottomofthegearsothattheydonotappearasseveraltriangles.>PLOT3D(POLYGONS(faces,STYLE(PATCHNOGRID)),>seq(POLYGONS(b),b=bord),>STYLE(PATCH),SCALING(CONSTRAINED)); 272¯Chapter5:ProgrammingwithMapleGraphicsNote:TheglobalSTYLE(PATCH)andSCALING(CONSTRAINED)optionsapplytothewholePLOT3Dstructure,exceptwherethelocalSTYLE(PATCHNOGRID)optiontothetopandbottomofthegearover-ridestheglobalSTYLE(PATCH)option.PolygonMeshesMESHdatastructures,describedonpage265,aregeneratedwhenyouuseplot3dtodrawparameterizedsurfaces.Example4convertsameshofpointstothesetofverticesforthecorrespondingpolygon.Byusingpoly-gonsinsteadofaMESHstructure,youcanmodifytheindividualpolygons.Example4Thepolygongridprocedurecreatestheverticesofaquad-rangleatthe(i;j)thgridvalue.>polygongrid:=proc(gridlist,i,j)>gridlist[j][i],gridlist[j][i+1],>gridlist[j+1][i+1],gridlist[j+1][i];>endproc:UsethemakePolygongridproceduretoconstructtheappropriatepolygons.>makePolygongrid:=proc(gridlist)>localm,n,i,j;>n:=nops(gridlist);>m:=nops(gridlist[1]);>POLYGONS(seq(seq([polygongrid(gridlist,i,j)],>i=1..m-1),j=1..n-1));>endproc:Thefollowingisameshofpointsin2-Dspace.>L:=[seq([seq([i-1,j-1],i=1..3)],j=1..4)]; 5.5ProgrammingwiththeplottoolsPackage¯273L:=[[[0;0];[1;0];[2;0]];[[0;1];[1;1];[2;1]];[[0;2];[1;2];[2;2]];[[0;3];[1;3];[2;3]]]ThemakePolygongridprocedurecreatesthePOLYGONSstructurecor-respondingtoL.>grid1:=makePolygongrid(L);grid1:=POLYGONS([[0;0];[1;0];[1;1];[0;1]];[[1;0];[2;0];[2;1];[1;1]];[[0;1];[1;1];[1;2];[0;2]];[[1;1];[2;1];[2;2];[1;2]];[[0;2];[1;2];[1;3];[0;3]];[[1;2];[2;2];[2;3];[1;3]])PutthepolygonsinsideaPLOTstructuretodisplaythem.>PLOT(grid1);32.521.510.500.511.52ToconvertGRIDorMESHstructurestopolygons,youcanalsousetheconvert(...,POLYGONS)command.Formoreinformation,referto?convert/POLYGONS.Theconvert(...,POLYGONS)commandcallstheprocedure`convert/POLYGONS`which,inthecaseofaMESHstructure,functionsthesameasthemakePolygongridprocedure.5.5ProgrammingwiththeplottoolsPackageWhiletheplottingdatastructureallowsdirectaccesstoallthefunction-alitythattheMapleplottingfacilitiesprovide,itdoesnotallowyoutospecifycolors(suchasredorblue)inanintuitiveway.ItalsodoesnotallowyoutousealltheMaplerepresentationsofnumericdata,suchas¹por2. 274¯Chapter5:ProgrammingwithMapleGraphicsThissectiondemonstrateshowtoworkwithbasicgraphicobjectsatalevelhigherthanthatoftheplottingdatastructures.Theplottoolspackageprovidescommandsforcreating2-Dobjectssuchaslinesanddisks,and3-Dobjectssuchasspheres,tori,andpolyhedra.Forexample,todrawasphereofunitradiusandatoruswithaspecißedcenterusingapatchrenderingstyleandaframeaxisstyle,enter:>with(plots):with(plottools):Warning,thenamechangecoordshasbeenredefinedWarning,thenamearrowhasbeenredefined>display(sphere([0,0,2]),torus([0,0,0]),>style=patch,axes=frame,scaling=constrained);20–3–3–2–2–1–100112233Torotatetheplotorapplyothertransformations,usetheproceduresintheplottoolspackage.>rotate(%,Pi/4,-Pi/4,Pi/4);210–1–2–3–2–2–1–10011223 5.5ProgrammingwiththeplottoolsPackage¯275APieChartYoucanwriteaplottingproceduretobuildapiechartofalistofintegerdata.Thepiechartprocedureusesthefollowingpartialsumprocedure,whichcalculatesthepartialsumsofalistofnumbersuptoagiventerm.>partialsum:=proc(d,i)>localj;>evalf(Sum(d[j],j=1..i))>endproc:Thefollowingisanexampleofacalltopartialsum.>partialsum([1,2,3,-6],3);6:Example1Thepiechartprocedure:¯Computestherelativeweightsofthedataalongwiththecentersofeachpieslice¯UsesaTEXTstructuretoplacethedatainformationatthecenterofeachpieslice¯Usesthepieslicecommandfromtheplottoolspackagetogeneratethepieslices¯Variesthecolorsofeachslicebyßrstdeßningacolorprocedurebasedonhuecoloring>piechart:=proc(data::list(integer))>localb,c,i,n,x,y,total;>>n:=nops(data);>total:=partialsum(data,n);>b:=0,seq(evalf(2*Pi*partialsum(data,i)/total),>i=1..n);>x:=seq((cos(b[i])+cos(b[i+1]))/3,i=1..n):>y:=seq((sin(b[i])+sin(b[i+1]))/3,i=1..n):>c:=(i,n)->COLOR(HUE,i/(n+1)):>PLOT(seq(plottools[pieslice]([0,0],1,>b[i]..b[i+1],color=c(i,n)),>i=1..n),>seq(TEXT([x[i],y[i]],convert(data[i],name)),>i=1..n),>AXESSTYLE(NONE),SCALING(CONSTRAINED));>endproc: 276¯Chapter5:ProgrammingwithMapleGraphicsTheAXESSTYLE(NONE)optionensuresthatMapledoesnotdrawanyaxeswiththepiechart.Thefollowingisapiechartwithsixslices.>piechart([8,10,15,10,12,16]);10158101612ADropshadowProcedureYoucanusetheexistingprocedurestocreateothertypesofplotsthatarenotpartoftheMapleplottinglibrary.Forexample,thefollowingprocedurecomputesthe3-Dplotofasurface,z=f(x;y),thathasadropshadowprojectionontoaplanelocatedbelowthesurface.Example2Theprocedureusesthecontourplot,contourplot3d,anddisplaycommandsfromtheplotspackage,andthetransformcom-mandfromtheplottoolspackage.>dropshadowplot:=proc(F::algebraic,r1::name=range,>r2::name=range,r3::name=range)>localminz,p2,p3,coption,opts,f,g,x,y;>>#setthenumberofcontours(default8)>opts:=[args[5..nargs]];>ifnothasoption(opts,'contours',coption,'opts')>thencoption:=8;>endif;>>#determinethebaseoftheplotaxes>#fromthethirdargument>minz:=lhs(`if`(r3::range,r3,rhs(r3)));>minz:=evalf(minz);>>>#create2-Dand3-DcontourplotsforF.>p3:=plots[contourplot3d](F,r1,r2,>'contours'=coption,op(opts));>p2:=plots[contourplot](F,r1,r2,>'contours'=coption,op(opts));> 5.5ProgrammingwiththeplottoolsPackage¯277>#embedcontourplotintoR^3viaplottools[transform]>g:=unapply([x,y,minz],x,y);>f:=plottools[transform](g);>plots[display]([f(p2),p3]);>endproc:Thefilled=trueoptiontocontourplotandcontourplot3dcausesthesetwocommandstoßlltheregionsbetweenthelevelcurveswithacolorthatindicatesthelevel.>expr:=-5*x/(x^2+y^2+1);xexpr:=5x2+y2+1>dropshadowplot(expr,x=-3..3,y=-3..3,z=-4..3,>filled=true,contours=3,axes=frame);210–1–2–3–4–3–3–2–2–1–1y00x112233Summary¯Theßrstsectionofthedropshadowproceduredeterminesifthereisacontoursoptionintheoptionalarguments(thoseafterthefourthargument)bycallingthehasoptionprocedure.¯Thenextsectionofdropshadowplotdeterminesthezvalueofthebase.Notethatitchecksforinputinoperatorform.¯Theremainingsectionscreatethecorrectplottingobjectswhichrep-resentthetwotypesofcontourplots.Thedropshadowplotprocedureembedsthe2-Dcontourplotinto3-Dspaceusingthetransformation(x;y)7![x;y;minz]fromR2!R3.Finally,itdisplaysthetwoplotsinone3-Dplottingobject. 278¯Chapter5:ProgrammingwithMapleGraphicsNote:Youcanprovideanalternatenumberoflevelsorspecifythepre-cisecontourlocationsbyusingthecontoursoption.Thus,>dropshadowplot(expr,x=-3..3,y=-3..3,z=-4..3,>filled=true,contours=[-2,-1,0,1,2]);producesaplotsimilartotheonejustgenerated,exceptthatitpro-duces5contoursatlevels2;1;0;1,and2.CreatingaTilingTheplottoolspackageprovidesaconvenientenvironmentforwritingplottingprograms.Forexample,youcandrawcirculararcsinaunitsquare.>with(plots):with(plottools):Warning,thenamechangecoordshasbeenredefinedWarning,thenamearrowhasbeenredefined>a:=rectangle([0,0],[1,1]),>arc([0,0],0.5,0..Pi/2),>arc([1,1],0.5,Pi..3*Pi/2):>b:=rectangle([1.5,0],[2.5,1]),>arc([1.5,1],0.5,-Pi/2..0),>arc([2.5,0],0.5,Pi/2..Pi):Youmustusedisplayfromtheplotspackagetoshowtheobjectsthatrectangleandarccreate.>display(a,b,axes=none,scaling=constrained); 5.5ProgrammingwiththeplottoolsPackage¯279Example3Youcantiletheplanewithaandbtyperectangles.Thefollowingprocedurecreatesam¢ntilingusingaproceduregtodeterminewhentouseanatileandwhentouseabtile.Thefunctiongreturnseither0,touseanatile,or1,touseabtile.>tiling:=proc(g,m,n)>locali,j,r,h,boundary,tiles;>>#defineanatile>r[0]:=plottools[arc]([0,0],0.5,0..Pi/2),>plottools[arc]([1,1],0.5,Pi..3*Pi/2);>#defineabtile>r[1]:=plottools[arc]([0,1],0.5,-Pi/2..0),>plottools[arc]([1,0],0.5,Pi/2..Pi);>boundary:=plottools[curve]([[0,0],[0,n],>[m,n],[m,0],[0,0]]);>tiles:=seq(seq(seq(plottools[translate](h,i,j),>h=r[g(i,j)]),i=0..m-1),j=0..n-1);>plots[display](tiles,boundary,args[4..nargs]);>endproc:Example4Deßnethefollowingprocedure,whichrandomlyreturnsei-ther0or1.>oddeven:=proc()rand()mod2endproc:Createa20¢10tiling(calledaTruchettiling)withnoaxesandconstrainedscaling.>tiling(oddeven,20,10,scaling=constrained,axes=none); 280¯Chapter5:ProgrammingwithMapleGraphicsWhenyouusethesameprocedureagain,therandomtilingisdiÞer-ent.>tiling(oddeven,20,10,scaling=constrained,axes=none);ASmithChartYoucanusethecommandsintheplottoolspackagetocreategraphs,suchasaSmithChart,whichisusedinmicrowavecircuitanalysis.>smithChart:=proc(r)>locali,a,b,c;>a:=PLOT(seq(plottools[arc]([-i*r/4,0],i*r/4,0..Pi),>i=1..4),>plottools[arc]([0,r/2],r/2,>Pi-arcsin(3/5)..3*Pi/2),>plottools[arc]([0,r],r,Pi..Pi+arcsin(15/17)),>plottools[arc]([0,2*r],2*r,>Pi+arcsin(3/5)..Pi+arcsin(63/65)),>plottools[arc]([0,4*r],4*r,>Pi+arcsin(15/17)..Pi+arcsin(63/65))>);>b:=plottools[transform]((x,y)->[x,-y])(a);>c:=plottools[line]([0,0],[-2*r,0]):>plots[display](a,b,c,axes=none,>scaling=constrained,args[2..nargs]);>endproc: 5.5ProgrammingwiththeplottoolsPackage¯281ThefollowingisaSmithChartofradius1.>smithChart(1);Exercise1.MakeaSmithChartbybuildingappropriatecirculararcsabovetheaxes.2.Createacopyreàectedontheaxis(usingtheplottools[transform]procedure).3.Addaßnalhorizontalline.Theparameterrdenotestheradiusofthelargestcircle.4.ModifythesmithChartproceduretoaddtexttomarkappropriategridmarkers.ModifyingPolygonMeshesYoucanconstructnewplottoolsthatworklikethoseintheplottoolspackage.Example5Createaprocedurethatremovestheinsideofasinglefaceofapolygon.Then,applyittoeveryfaceofapolygon.>cutoutPolygon:=proc(vlist::list,scale::numeric)>locali,center,outside,inside,n,edges,polys;>>n:=nops(vlist);>center:=add(i,i=vlist)/n;>inside:=seq(scale*(vlist[i]-center)+center,i=1..n);>outside:=seq([inside[i],vlist[i],vlist[i+1],>inside[i+1]],>i=1..n-1):>polys:=POLYGONS(outside,>[inside[n],vlist[n],vlist[1],inside[1]],>STYLE(PATCHNOGRID)); 282¯Chapter5:ProgrammingwithMapleGraphics>edges:=CURVES([op(vlist),vlist[1]],>[inside,inside[1]]);>polys,edges;>endproc:Thefollowingarethecornersofatriangle.>triangle:=[[0,2],[2,2],[1,0]];triangle:=[[0;2];[2;2];[1;0]]ThecutoutPolygonprocedureconvertstriangletothreepolygons(oneforeachside)andtwocurves.>cutoutPolygon(triangle,1/2);1535POLYGONS([[;];[0;2];[2;2];[;]];2323352215[[;];[2;2];[1;0];[1;]];[[1;];[1;0];[0;2];[;]];233323STYLE(PATCHNOGRID));CURVES(1535215[[0;2];[2;2];[1;0];[0;2]];[[;];[;];[1;];[;]])2323323Usetheplots[display]commandtoshowthetriangle.>plots[display](%,color=red);21.510.500.511.52ThefollowingcutoutprocedureappliescutoutPolygontoeveryfaceofapolyhedron.>cutout:=proc(polyhedron,scale)>localv;>seq(cutoutPolygon(v,evalf(scale)),v=polyhedron);>endproc: 5.5ProgrammingwiththeplottoolsPackage¯283Thefollowingcommandremoves3=4ofeachfaceofadodecahedronanddisplaystheresult.>display(cutout(dodecahedron([1,2,3]),3/4),>scaling=constrained);Example6Raiseorlowerthebarycenterofapolygon.>stellateFace:=proc(vlist::list,aspectRatio::numeric)>localapex,i,n;>>n:=nops(vlist);>apex:=add(i,i=vlist)*aspectRatio/n;>POLYGONS(seq([apex,vlist[i],vlist[modp(i,n)+1]],>i=1..n));>endproc:Thefollowingarethecornersofatrianglein3-Dspace.>triangle:=[[1,0,0],[0,1,0],[0,0,1]];triangle:=[[1;0;0];[0;1;0];[0;0;1]]ThestellateFaceprocedurecreatesthreepolygons,oneforeachsideofthetriangle.>stellateFace(triangle,1);111POLYGONS([[;;];[1;0;0];[0;1;0]];333111111[[;;];[0;1;0];[0;0;1]];[[;;];[0;0;1];[1;0;0]])333333Becausethesepolygonsare3-Dobjects,todisplaythem,placethePOLYGONSstructureinsideaPLOT3Dstructure. 284¯Chapter5:ProgrammingwithMapleGraphics>PLOT3D(%);AsinExample5,youcanextendthestellateFaceproceduretoactonarbitrarypolyhedrawithmorethanoneface.>stellate:=proc(polyhedron,aspectRatio)>localv;>seq(stellateFace(v,evalf(aspectRatio)),>v=polyhedron);>endproc:Thefollowingcommandsconstructanddisplayastellateddodecahe-dron.>stellated:=display(stellate(dodecahedron(),3),>scaling=constrained):>display(array([dodecahedron(),stellated]));Youcanusetheconvert(...,POLYGONS)commandtoconvertaGRIDorMESHstructuretotheequivalentsetofPOLYGONS.Example7ThisexampleusesaversionoftheKleinbottlecreatedfromPOLYGONSstructures.>kleinpoints:=proc()>localbottom,middle,handle,top,p,q;> 5.5ProgrammingwiththeplottoolsPackage¯285>top:=[(2.5+1.5*cos(v))*cos(u),>(2.5+1.5*cos(v))*sin(u),-2.5*sin(v)]:>middle:=[(2.5+1.5*cos(v))*cos(u),>(2.5+1.5*cos(v))*sin(u),3*v-6*Pi]:>handle:=[2-2*cos(v)+sin(u),cos(u),>3*v-6*Pi]:>bottom:=[2+(2+cos(u))*cos(v),sin(u),>-3*Pi+(2+cos(u))*sin(v)]:>p:=plot3d({bottom,middle,handle,top},>u=0..2*Pi,v=Pi..2*Pi,grid=[9,9]):>p:=select(x->op(0,x)=MESH,[op(p)]);>seq(convert(q,POLYGONS),q=p);>endproc:>display(kleinpoints(),style=patch,>scaling=constrained,orientation=[-110,71]);ToaltertheviewoftheKleinbottle,usepolygonmanipulationcom-mands.>display(seq(cutout(k,3/4),k=kleinpoints()),>scaling=constrained); 286¯Chapter5:ProgrammingwithMapleGraphics5.6VectorFieldPlotsThissectiondescribeshowtoplotavectorßeldof2-Dvectorsintheplane.Theexamplesillustratethetoolsavailableforplotobjectsongridsin2-Dand3-Dspace.Thegoalistocreateaprocedurethatplotsavectorßeldandhasthefollowingsyntax.vectorfieldplot(F,r1,r2,options)¯Theßrstargument,F,isalistofsizetwocontainingtheexpressionsthatspecifythehorizontalandverticalcomponentsofthevectorßeld.¯Theargumentsr1andr2describethedomaingridofthevectors.¯ThethreeargumentsF,r1,andr2aresimilarinformtotheargumentsrequiredfortheplot3dcommand.¯Theoptionalinformationincludesanyrelevantplottingoptionthatplotandplot3drecognize.Thus,optionssuchasgrid=[m,n],style=patch,andcolor=colorfunctionarevalid.DrawingaVectorTheßrststepistodrawavector.Let[x;y]representthestartingpointofthearrowand[a;b]representthecomponentsofthevector.Specifytheshapeofanarrowwiththreeindependentparameters,t1,t2,andt3,wheret1denotesthethicknessofthearrow,t2thethicknessofthearrowhead,andt3theratioofthelengthofthearrowheadtothelengthofthearrow.Example1Thefollowingmyarrowprocedureconstructssevenverticesofanarrow.Itthenbuildsthearrowbyconstructingtwopolygons:atriangle(spannedbyv5,v6,andv7)fortheheadofthearrowandarectangle(spannedbyv1,v2,v3,andv4)forthetail.Itthenremovesboundarylinesbysettingthestyleoptioninsidethepolygonstructure.Italsoconstructstheboundaryoftheentirearrowviaaclosedcurvethroughthevertices.>myarrow:=proc(point::list,vect::list,t1,t2,t3)>locala,b,i,x,y,L,Cos,Sin,v,locopts;>>a:=vect[1];b:=vect[2];>ifhas(vect,'undefined')or(a=0andb=0)then>returnPOLYGONS([]); 5.6VectorFieldPlots¯287>endif;>x:=point[1];y:=point[2];>#L=lengthofarrow>L:=evalf(sqrt(a^2+b^2));>Cos:=evalf(a/L);>Sin:=evalf(b/L);>v[1]:=[x+t1*Sin/2,y-t1*Cos/2];>v[2]:=[x-t1*Sin/2,y+t1*Cos/2];>v[3]:=[x-t1*Sin/2-t3*Cos*L+a,>y+t1*Cos/2-t3*Sin*L+b];>v[4]:=[x+t1*Sin/2-t3*Cos*L+a,>y-t1*Cos/2-t3*Sin*L+b];>v[5]:=[x-t2*Sin/2-t3*Cos*L+a,>y+t2*Cos/2-t3*Sin*L+b];>v[6]:=[x+a,y+b];>v[7]:=[x+t2*Sin/2-t3*Cos*L+a,>y-t2*Cos/2-t3*Sin*L+b];>v:=seq(evalf(v[i]),i=1..7);>>#convertoptionalargumentstoPLOTdatastructureform>locopts:=convert([style=patchnogrid,args[6..nargs]],>PLOToptions);>POLYGONS([v[1],v[2],v[3],v[4]],>[v[5],v[6],v[7]],op(locopts)),>CURVES([v[1],v[2],v[3],v[5],v[6],>v[7],v[4],v[1]]);>endproc:Note:Becauseeachpolygonmustbeconvex,youmustbuildthepoly-gonstructureforthearrowintwoparts.Inthespecialcasethatthevectorhasbothcomponentsequaltozerooranundefinedcomponent,suchasavalueresultingfromanon-numericvalue(forexample,acomplexvalueorasingularitypoint),themyarrowprocedurereturnsatrivialpolygon.Thefollowingarefourarrows.>arrow1:=PLOT(myarrow([0,0],[1,1],0.2,0.4,1/3,>color=red)):>arrow2:=PLOT(myarrow([0,0],[1,1],0.1,0.2,1/3,>color=yellow)):>arrow3:=PLOT(myarrow([0,0],[1,1],0.2,0.3,1/2,>color=blue)):>arrow4:=PLOT(myarrow([0,0],[1,1],0.1,0.5,1/4,>color=green)):Thedisplaycommandfromtheplotspackagecanshowanarrayofplots.>with(plots):Warning,thenamechangecoordshasbeenredefined 288¯Chapter5:ProgrammingwithMapleGraphics>display(array([[arrow1,arrow2],[arrow3,arrow4]]),>scaling=constrained);1.1.0.0.1.0.0.1.1.1.0.0.1.0.0.1.GeneratingaVectorPlotFieldTheremainderofthissectionpresentsanumberofsolutionstothepro-grammingproblemofgeneratingavectorßeldplot,eachmorepowerfulthanitspredecessors.Theßrstandsimplestsolutionrequirestheinputbeinoperatorform.Thissolutionusesthreeutilityproceduresthatprocessthedomaininformation,generateagridoffunctionvalues,andplacetheinformationinaPLOT3Dstructure.Example2Theproceduredomaininfodeterminestheendpointsandincrementsforthegrid.Ittakesasinputthetworangesr1andr2andthetwogridsizesmandn,andreturnsthegridinformationasanexpressionsequenceoffourelements.>domaininfo:=proc(r1,r2,m,n)>lhs(r1),lhs(r2),>evalf((rhs(r1)-lhs(r1))/(m-1)),>evalf((rhs(r2)-lhs(r2))/(n-1));>endproc:Thefollowingexampleusesmultipleassignmentstoassignthefourvaluesreturnedtoseparatevariables.>a,b,dx,dy:=domaininfo(0..12,20..100,7,9);a;b;dx;dy:=0;20;2:;10:Nowa,b,dx,anddyhavethefollowingvalues.>a,b,dx,dy; 5.6VectorFieldPlots¯2890;20;2:;10:Example3Toconverttoagridofnumericalpoints,usetheextensibilityoftheMapleconvertcommand.Theprocedure`convert/grid`takesaprocedurefasinputandappliesittothepointsinthegridwhichr1,r2,m,andnspecify.>`convert/grid`:=proc(f,r1,r2,m,n)>locala,b,i,j,dx,dy;>#obtaininformationaboutdomain>a,b,dx,dy:=domaininfo(r1,r2,m,n);>#outputgridoffunctionvalues>[seq([seq(evalf(f(a+i*dx,b+j*dy)),>i=0..m-1)],j=0..n-1)];>endproc:Nowapplytheundeßnedname,f,toagridasfollows.>convert(f,grid,1..2,4..6,3,2);[[f(1:;4:);f(1:500000000;4:);f(2:000000000;4:)];[f(1:;6:);f(1:500000000;6:);f(2:000000000;6:)]]Example4Theßnalutilityproceduredeterminesthescalingthaten-suresthatthearrowsdonotoverlap.Thengenerateplotcallsthemyarrowproceduretodrawthevectors.Note:generateplotcenterseacharrowoveritsgrid-point.>generateplot:=proc(vect1,vect2,m,n,a,b,dx,dy)>locali,j,L,xscale,yscale,mscale;>>#Determinescalingfactor.>L:=max(seq(seq(vect1[j][i]^2+vect2[j][i]^2,>i=1..m),j=1..n));>xscale:=evalf(dx/2/L^(1/2));>yscale:=evalf(dy/2/L^(1/2));>mscale:=max(xscale,yscale);>>#Generateplotdatastructure.>#Eacharrowiscenteredoveritspoint.>PLOT(seq(seq(myarrow(>[a+(i-1)*dx-vect1[j][i]*xscale/2,>b+(j-1)*dy-vect2[j][i]*yscale/2],>[vect1[j][i]*xscale,vect2[j][i]*yscale],>mscale/4,mscale/2,1/3),i=1..m),j=1..n));>#Thicknessoftail=mscale/4>#Thicknessofhead=mscale/2>endproc: 290¯Chapter5:ProgrammingwithMapleGraphicsExample5Withtheseutilityfunctions,youcanwritethevectorfieldplotcommand.>vectorfieldplot:=proc(F,r1,r2,m,n)>localvect1,vect2,a,b,dx,dy;>>#Generateeachcomponentoverthegridofpoints.>vect1:=convert(F[1],grid,r1,r2,m,n);>vect2:=convert(F[2],grid,r1,r2,m,n);>>#Obtainthedomaingridinformationfromr1andr2.>a,b,dx,dy:=domaininfo(r1,r2,m,n);>>#Generatethefinalplotstructure.>generateplot(vect1,vect2,m,n,a,b,dx,dy)>endproc:Trytheprocedureonthevectorßeld(cos(xy);sin(xy)).>p:=(x,y)->cos(x*y):q:=(x,y)->sin(x*y):>vectorfieldplot([p,q],0..Pi,0..Pi,15,20);32.521.510.500.511.522.53Thevectorfieldplotcodeshowshowtowriteaprocedurethatgen-eratesvectorßeldplotsbasedonalternativedescriptionsoftheinput.Example6Youcancreatethelistvectorfieldplotprocedure,whichacceptsinputconsistingofalistofmlists,eachofwhichconsistsofnlistswithtwoelements.Thepairsofelementsspecifythecomponentsofavector.Thedomaingridis1;:::;minthehorizontaldirectionand1;:::;nintheverticaldirection(aswiththeplots[listplot3d]command).>listvectorfieldplot:=proc(F)>localm,n,vect1,vect2;>>n:=nops(F);m:=nops(F[1]);>#Generatethe1stand2ndcomponentsofF.>vect1:=map(u->map(v->evalf(v[1]),u),F);>vect2:=map(u->map(v->evalf(v[2]),u),F);> 5.6VectorFieldPlots¯291>#Generatethefinalplotstructure.>generateplot(vect1,vect2,m,n,1,1,m-1,n-1)>endproc:Thefollowingisanexampleofacalltolistvectorfieldplot.>l:=[[[1,1],[2,2],[3,3]],>[[1,6],[2,0],[5,1]]]:>listvectorfieldplot(l);2.221.81.61.41.2112345Thereareproblemswiththevectorfieldplotprocedure.¯Theprocedureonlyworkswithoperatorform.Youcansolvethisproblembyconvertingexpressionstoprocedures,andthenrecursivelycallingthevectorfieldplotprocedurewiththeconvertedinput(asintheribbonplotprocedureinsection5.2).¯Theprocedureonlyworkswithlistsasinput,notArrays.Toovercomesuchproblems,ßrstconvertallinputprocedurestopro-ceduresthatgenerateonlyanumericrealvalueorthevalueundefined,theonlytypeofdatathatcanappearinaMapleplotdatastructure.Itisrecommendedthatyouusethemoreeácienthardwareàoating-pointcalculationsratherthansoftwareàoating-pointoperations,wheneverpos-sible.Formoreinformation,seetheexamplesin5.7GeneratingGridsofPoints.Insteadofwritingaprocedureforcomputingthegrid,usethelibraryfunctionconvert(...,gridpoints)which,inthecaseofasingleinput,generatesastructureofthefollowingform.[a..b,c..d,[[z11,...,z1n],...,[zm1,...,zmn]]] 292¯Chapter5:ProgrammingwithMapleGraphicsItuseseitherexpressionsorproceduresasinput.Theoutputgivesthedomaininformationa..bandc..dalongwiththezvaluesoftheinputthatitevaluatesoverthegrid.>convert(sin(x*y),'gridpoints',>x=0..Pi,y=0..Pi,grid=[2,3]);[0:::3:14159265358979;0:::3:14159265358979;[[0:;0:;0:];[0:;0:975367972083633571;0:430301217000074065]]]Whenxy>0,thenln(xy)iscomplex,sothegridcontainsthevalueundefined.>convert((x,y)->log(-x*y),'gridpoints',>1..2,-2..1,grid=[2,3]);[1:::2:;2:::1:;[[0:693147180559945286;0:693147180559945286;undeßned];[1:386294361;0:;undeßned]]]Example7Thisversionofthevectorfieldplotprocedureacceptsanumberofoptions.Inparticular,itallowsagrid=[m,n]option.Toaccomplishthis,passtheoptionstoconvert(...,gridpoints).Theutilityproceduremakevectorshandlestheinterfacetoconvert(...,gridpoints).>makevectors:=proc(F,r1,r2)>localv1,v2;>>#Generatethenumericalgrid>#ofcomponentsofthevectors.>v1:=convert(F[1],'gridpoints',r1,r2,>args[4..nargs]);>v2:=convert(F[2],'gridpoints',r1,r2,>args[4..nargs]);>>#Thedomaininformationiscontainedinfirst>#twooperandsofv1.Thefunctionvaluesin>#the3rdcomponentsofv1andv2.>[v1[1],v1[2],v1[3],v2[3]]>endproc:Thenewversionofvectorfieldplotis: 5.6VectorFieldPlots¯293>vectorfieldplot:=proc(F,r1,r2)>localR1,R2,m,n,a,b,v1,v2,dx,dy,v;>>v:=makevectors(F,r1,r2,args[4..nargs]);>R1:=v[1];R2:=v[2];v1:=v[3];v2:=v[4];>>n:=nops(v1);m:=nops(v1[1]);>a,b,dx,dy:=domaininfo(R1,R2,m,n);>>generateplot(v1,v2,m,n,a,b,dx,dy);>endproc:Testthisprocedure.>p:=(x,y)->cos(x*y):>q:=(x,y)->sin(x*y):>vectorfieldplot([p,q],0..Pi,0..Pi,grid=[3,4]);32.521.510.500.511.522.533.5Allthepreviousversionsofvectorfieldplotscaleallvectorsbythesamefactorsothateachvectorßtsintoasinglegridbox.Nooverlappingofarrowsoccurred.However,thelengthofthearrowsisdependentonthesizeofthegridboxes.Thiscanproducegraphsthathavealargenumberofverysmall,almostindiscerniblevectors.Forexample,thefollowingplotofthegradientßeldofF=cos(xy)exhibitsthisbehavior.>vectorfieldplot([y*cos(x*y),x*sin(x*y)],>x=0..Pi,y=0..Pi,grid=[15,20]);32.521.510.500.511.522.53 294¯Chapter5:ProgrammingwithMapleGraphicsTheßnalversionofvectorfieldplotdiÞersinthatallthearrowshavethesamelengthÜthecolorofeachvectorindicatesitsmagnitude.Firstcreateautilityprocedurethatgeneratesagridofcolorsfromthefunctionvalues.Example8UtilityProcedure>`convert/colorgrid`:=proc(colorFunction)>localcolorinfo,i,j,m,n;>>colorinfo:=op(3,convert(colorFunction,>'gridpoints',args[2..nargs]));>map(x->map(y->COLOR(HUE,y),x),colorinfo);>endproc:Thisprocedureusestheconvert(...,gridpoints)proceduretogeneratealistoflistsoffunctionvaluesthatspecifythecolors(usinghuecoloring).>convert(sin(x*y),'colorgrid',x=0..1,y=0..1,grid=[2,3]);[[COLOR(HUE;0:);COLOR(HUE;0:);COLOR(HUE;0:)];[COLOR(HUE;0:);COLOR(HUE;0:479425538604203006);COLOR(HUE;0:841470984807896505)]]Example9Theßnalversionofthevectorfieldplotprocedureis:>vectorfieldplot:=proc(F,r1,r2)>localv,m,n,a,b,dx,dy,opts,p,v1,v2,>L,i,j,norms,colorinfo,>xscale,yscale,mscale;>>v:=makevectors(F,r1,r2,args[4..nargs]);>v1:=v[3];v2:=v[4];>n:=nops(v1);m:=nops(v1[1]);>>a,b,dx,dy:=domaininfo(v[1],v[2],m,n);>>#Determinethefunctionusedforcoloringthearrows.>opts:=[args[4..nargs]];>ifnothasoption(opts,color,colorinfo,'opts')then>#Defaultcoloringwillbevia>#thescaledmagnitudeofthevectors.>L:=max(seq(seq(v1[j][i]^2+v2[j][i]^2,>i=1..m),j=1..n));>colorinfo:=(F[1]^2+F[2]^2)/L;>endif;> 5.6VectorFieldPlots¯295>#Generatetheinformationneededtocolorthearrows.>colorinfo:=convert(colorinfo,'colorgrid',>r1,r2,op(opts));>>#Getallthenormsofthevectorsusingzip.>norms:=zip((x,y)->zip((u,v)->>ifu=0andv=0then1elsesqrt(u^2+v^2)endif,>x,y),v1,v2);>#Normalizev1andv2(againusingzip).>v1:=zip((x,y)->zip((u,v)->u/v,x,y),v1,norms);>>v2:=zip((x,y)->zip((u,v)->u/v,x,y),v2,norms);>>#Generatescalinginformationandplotdatastructure.>xscale:=dx/2.0;yscale:=dy/2.0;>mscale:=max(xscale,yscale);>>PLOT(seq(seq(myarrow(>[a+(i-1)*dx-v1[j][i]*xscale/2,>b+(j-1)*dy-v2[j][i]*yscale/2],>[v1[j][i]*xscale,v2[j][i]*yscale],>mscale/4,mscale/2,1/3,>'color'=colorinfo[j][i]>),i=1..m),j=1..n));>endproc:Thisversionproducesthefollowingplots.>vectorfieldplot([y*cos(x*y),x*sin(x*y)],>x=0..Pi,y=0..Pi,grid=[15,20]);32.521.510.500.511.522.53Youcancolorthevectorsviaafunction,suchassin(xy).>vectorfieldplot([y*cos(x*y),x*sin(x*y)],>x=0..Pi,y=0..Pi,grid=[15,20],color=sin(x*y)); 296¯Chapter5:ProgrammingwithMapleGraphics32.521.510.500.511.522.53Othervectorßeldroutinescanbederivedfromtheprecedingroutines.Forexample,youcanalsowriteacomplexvectorßeldplotthattakescomplexnumberlocationsandcomplexnumberdescriptionsofvectorsasinput.Simplygeneratethegridofpointsinanalternatemanner.Thearrowprocedure,intheplotspackage,generatesarrowsandvec-tors.Thearrowprocedureismoreversatilethantheproceduresdescribedinthissection.5.7GeneratingGridsofPointsSection5.6illustratedthestepsinvolvedinthesimpleoperationofob-taininganArrayofgridvaluesfromagivenprocedure.Youmustconsidereáciency,errorconditions,andnon-numericoutput.Tohandlethecaseinwhichtheinputisanexpressionintwovariables,youcanusethemethodfromtheribbonplotprocedureinExample4ofsection5.2.Thus,forsimplicityofpresentation,thissectiondealswithonlyoperatorformin-put.ThegoalistocomputeanArrayofvaluesforfateachpointonam¢nrectangulargrid.Thatis,atthelocationsxi=a+(i1)®xandyj=c+(j1)®ywhere®x=(ba)=(m1)and®y=(dc)=(n1).Hereiandjvaryfrom1tomand1ton,respectively.Theßnalprocedurethatiscreatedinthissection(inExample3)issimilartotheconvert(...,gridpoints)libraryprocedure,exceptthatitproducesanArrayinsteadofalistoflists.Considerthefunctionf:(x;y)7!1=sin(xy).Youneedtoevaluatefoverthem¢ngridwiththerangesa::bandc::d. 5.7GeneratingGridsofPoints¯297>f:=(x,y)->1/sin(x*y);1f:=(x;y)!sin(xy)Example1Theßrststepistoconvertthefunctionftoanumericprocedure.BecauseMaplerequiresnumericvalues(ratherthansymbolic)forplots,convertftoaprocedurethatreturnsnumericalanswersorthespecialvalueundefined.>fnum:=convert(f,numericproc);fnum:=proc(x;y)localr;tryr:=evalhf(f(x;y))catch:endtry;ifnottype(r;'numeric')thentryr:=evalf(f(x;y))catch:endtryendif;`if`(type(r;'numeric');r;'undeßned')endprocThefnumprocedure,whichistheresultofthisconversion,attemptstocalculatethenumericalvaluesaseácientlyaspossible.Hardwareàoating-pointarithmetic,althoughoflimitedprecision,ismoreeácientthansoft-wareàoating-pointandisfrequentlysuácientforplotting.Thus,thefnumproceduretriestheevalhffunctionßrst.Ifevalhfgeneratesanerrororreturnsanon-numericresult,thefnumprocedureattemptsthecalculationagainbyusingsoftwareàoating-pointarithmeticandthencallingevalf.Eventhiscalculationisnotalwayspossible.Forexample,thefunctionfisundeßnedwheneverx=0ory=0.Insuchcases,theprocedurefnumreturnsthenameundefined.TheMapleplotdisplayroutinesrecognizethisspecialname.Atthepoint(1;1),thefunctionfhasthevalue1=sin(1)andsofnumreturnsanumericalestimate.>fnum(1,1);1:18839510577812123However,ifyoutrytoevaluatefat(0;0),Maplereturnsthatthefunctionisundeßnedatthesecoordinates. 298¯Chapter5:ProgrammingwithMapleGraphics>fnum(0,0);undeßnedSummaryCreatingsuchaprocedureistheßrststepincreatingthegridofvalues.Foreáciency,whenpossible,computethefunctionvaluesandthegridpointsbyusinghardwareàoating-pointarithmetic.Inaddition,itisrecommendedthatyouperformasmuchcomputationaspossibleinasinglecalltoevalhf.Forhardwareàoating-pointarithmetic,Maplemustßrstconverttheexpressiontoaseriesofcommandsinvolvinghardwareàoating-pointnumbers,andthenconverttheresultsbacktotheMapleformatfornumbers.Formoreinformationonnumericalcalculations,seechapter4.Example2ThefollowingproceduregeneratesthecoordinatesofthegridintheformofanArray.Becausetheprocedureplotssurfaces,theArrayistwodimensional.TheprocedurereturnsanArrayzoffunctionvalues.>evalgrid:=proc(F,z,a,b,c,d,m,n)>locali,j,dx,dy;>>dx:=(b-a)/m;dy:=(d-c)/n;>foritomdo>forjtondo>z[i,j]:=F(a+(i-1)*dx,c+(j-1)*dy);>enddo;>enddo;>endproc:Thisevalgridprocedureispurelysymbolicanddoesnothandleerrorconditions.>A:=Array(1..2,1..2):>evalgrid(f,'A',1,2,1,2,2,2):>A;23116sin(1)376sin()762761174539sin()sin()24>evalgrid(f,'A',0,Pi,0,Pi,2,2): 5.7GeneratingGridsofPoints¯299Error,(inf)numericexception:divisionbyzeroExample3Thegridpointsprocedureusestheevalgridprocedure.Theprocedureacceptsaprocedure,tworanges,andthenumberofgridpointstogenerateineachdimension.LiketheprocedurefnumwhichMaplegeneratedfromthepreviouslydeßnedproceduref,thisroutineattemptstocreatethegridusinghardwareàoating-pointarithmetic.Onlyifthisfails,doesgridpointsusesoftwareàoating-pointarithmetic.>gridpoints:=proc(f,r1,r2,m,n)>localu,x,y,z,a,b,c,d;>>#Domaininformation:>a:=lhs(r1);b:=rhs(r1);>c:=lhs(r2);d:=rhs(r2);>>ifDigits<=evalhf(Digits)then>try>#Trytousehardwarefloats.>z:=Array(1..m,1..n,datatype=float[8]);>evalhf(evalgrid(f,z,a,b,c,d,m,n));>catch:>#Usesoftwarefloats,firstconvertingfto>#asoftwarefloatfunction.>z:=Array(1..m,1..n);>evalgrid(convert(f,numericproc),z,a,b,c,d,m,n);>endtry;>else>#Usesoftwarefloats,firstconvertingfto>#asoftwarefloatfunction.>z:=Array(1..m,1..n);>evalgrid(convert(f,numericproc),z,a,b,c,d,m,n);>endif;>z;>endproc:TestingtheProceduresThegridpointsprocedurecanusehardwareàoating-pointarithmetictocalculatetwoofthenumbers,butitmustusesoftwarecalculationsinfourcaseswherethefunctionisundeßned.>gridpoints((x,y)->1/sin(x*y),0..3,0..3,2,3);[undeßned;undeßned;undeßned][undeßned;1:00251130424672485;7:08616739573718667] 300¯Chapter5:ProgrammingwithMapleGraphicsInthefollowingexample,gridpointscanusehardwareàoating-pointforallthecalculations.Therefore,thiscalculationisfaster,althoughthediÞerenceisnotapparentunlessyoutryamuchlargerexample.>gridpoints((x,y)->sin(x*y),0..3,0..3,2,3);[0:;0:;0:][0:;0:997494986604054445;0:141120008059867213]Ifyouaskformoredigitsthanhardwareàoating-pointarithmeticcanprovide,thengridpointsusessoftwareàoating-pointoperations.>Digits:=22:>gridpoints((x,y)->sin(x*y),0..3,0..3,2,3);[0:;0:;0:][0:;0:9974949866040544309417;0:1411200080598672221007]>Digits:=10:Whenhardwareàoating-pointcalculationsarepossible,thedataisre-turnedinanArraywithdatatype=float[8],inwhichcaseyoucandis-playitbyenclosingitinaGRIDstructureinaPLOT3Dstructure.>PLOT3D(GRID(0..3,0..3,gridpoints((x,y)->sin(x*y),0..3,>0..3,10,10)),AXES(BOXED));10.50–0.5–1000.50.5111.51.5222.52.533Otherwise,thedataisreturnedinanArraywiththedefaultdatatype=anything,whichmustbeconvertedtoanArraywithdatatype=float[8]beforebeingplacedinsideaplotdatastructure. 5.8Animation¯3015.8AnimationMaplecangenerateanimationsintwoorthreedimensions.AswithallMapleplottingfacilities,suchanimationsproduceuser-accessibledatastructures.Datastructuresofthefollowingtyperepresentanimations.PLOT(ANIMATE(...))orPLOT3D(ANIMATE(...))InsidetheANIMATEfunctionisasequenceofframes;eachframeisalistofthesameplottingobjectsthatcanappearinasingleplottingstruc-ture.Everyprocedurethatcreatesananimationbuildssuchasequenceofframes.Forexample,printtheoutputofsuchaprocedureusingthefollowingMaplecommand(outputnotshown).>lprint(plots[animate](plot,[x*t,x=-1..1],t=1..3,>numpoints=3,frames=3));Thefunctionpointsisaparameterizationofthecurve(x;y)=(1+cos(t¹=180)2;1+cos(t¹=180)sin(t¹=180)).>points:=t->evalf(>[(1+cos(t/180*Pi))*cos(t/180*Pi),>(1+cos(t/180*Pi))*sin(t/180*Pi)]):Forexample,>points(2);[1:998172852;0:06977773357]Youcanplotasequenceofpoints.>PLOT(POINTS(seq(points(t),t=0..90)));1.210.80.60.40.200.511.52 302¯Chapter5:ProgrammingwithMapleGraphicsYoucannowmakeananimation.Makeeachframeconsistofthepolygonspannedbytheorigin,(0;0),andthesequenceofpointsonthecurve.>frame:=n->[POLYGONS([[0,0],>seq(points(t),t=0..60*n)],>COLOR(RGB,1.0/n,1.0/n,1.0/n))]:Theanimation(notshown)consistsofsixframes.>PLOT(ANIMATE(seq(frame(n),n=1..6)));AnimationinStaticFormThedisplaycommandfromtheplotspackagecanshowananimationinstaticform.>with(plots):Warning,thenamechangecoordshasbeenredefined>display(PLOT(ANIMATE(seq(frame(n),n=1..6))));1.01.01.0.5.5.50.0.2.0.0.2.0.0.2.1.01.1..50.0.0.2.0.2.0.0.2.–1.–1.GraphicalObjectasInputThevaryAspectprocedureillustrateshowastellatedsurfacevarieswiththeaspectratio.Example1TheproceduretakesagraphicalobjectasinputandcreatesananimationinwhicheachframeisastellatedversionoftheobjectwithadiÞerentaspectratio.>with(plottools):Warning,thenamearrowhasbeenredefined 5.8Animation¯303>varyAspect:=proc(p)>localn,opts;>opts:=convert([args[2..nargs]],PLOT3Doptions);>PLOT3D(ANIMATE(seq([stellate(p,n/sqrt(2))],>n=1..4)),>op(opts));>endproc:Trytheprocedureonadodecahedron.>varyAspect(dodecahedron(),scaling=constrained);Thestaticversionis:>display(varyAspect(dodecahedron(),>scaling=constrained));MethodsforCreatingAnimationsTheMaplelibraryprovidestwomethodsforcreatinganimations:theanimatecommandintheplotspackageandthedisplaycommandwiththeinsequence=trueoption.Forexample,youcanshowhowaFourierseriesapproximatesafunction,f,onaninterval[a;b]byvisualizingthefunctionandsuccessiveapproximationsasthenumberoftermsincreasewitheachframe.YoucanderivethenthpartialsumoftheFourierseriesPn2¹2¹byusingfn(x)=c0=2+k=1ckcos(bakx)+sksin(bakx),whereZ²³2b2¹ck=f(x)coskxdxbaabaandZ²³2b2¹sk=f(x)sinkxdx:baaba 304¯Chapter5:ProgrammingwithMapleGraphicsExample2ThefourierPictureprocedureßrstcalculatesandplotsthekthFourierapproximationforkupton.ThenfourierPicturegeneratesananimationoftheseplots,andßnallyitaddsaplotofthefunctionasabackdrop.>fourierPicture:=>proc(func,xrange::name=range,n::posint)>localx,a,b,l,k,j,p,q,partsum;>>a:=lhs(rhs(xrange));>b:=rhs(rhs(xrange));>l:=b-a;>x:=2*Pi*lhs(xrange)/l;>>partsum:=1/l*evalf(Int(func,xrange));>forkfrom1tondo>#GeneratethetermsoftheFourierseriesoffunc.>partsum:=partsum>+2/l*evalf(Int(func*sin(k*x),xrange))>*sin(k*x)>+2/l*evalf(Int(func*cos(k*x),xrange))>*cos(k*x);>#Plotk-thFourierapproximation.>q[k]:=plot(partsum,xrange,color=blue,>args[4..nargs]);>enddo;>#Generatesequenceofframes.>q:=plots[display]([seq(q[k],k=1..n)],>insequence=true);>#Addthefunctionplot,p,toeachframe.>p:=plot(func,xrange,color=red,args[4..nargs]);>plots[display]([q,p]);>endproc:YoucannowusefourierPicturetoplot,forexample,theßrstsixFourierapproximationsofex.>fourierPicture(exp(x),x=0..10,6):Thestaticversionis:>display(fourierPicture(exp(x),x=0..10,6)); 5.8Animation¯305.2e5.2e5.2e5.1e5.1e5.1e5xxx0.0..1e20.0..1e20.0..1e2.2e5.2e5.2e5.1e5.1e5.1e5xxx0.0..1e20.0..1e20.0..1e2ThefollowingaretheßrstsixFourierapproximationsofx->signum(x-1).Becausethesignumfunctionisdiscontinuous,thediscont=trueoptionisrequired.>fourierPicture(2*signum(x-1),x=-2..3,6,>discont=true);Thestaticversionis:>display(fourierPicture(2*signum(x-1),x=-2..3,6,>discont=true));2.2.2.0.xx–2.0.2.0.x–2.0.0.2.–2.0.2.–2.–2.–2.2.2.2.xxx–2.0.0.2.–2.0.0.2.–2.0.0.2.–2.–2.–2.Youcanalsocreatesimilaranimationswithotherseriesapproxima-tions,suchasTaylor,Padæe,andChebyshevÛPadæe,withthegeneralizedseriesstructuresthatMapleuses.TwoandThreeDimensionsAnimationsequencesexistinbothtwoandthreedimensions.Example3Thefollowingproceduretiesatrefoilknotbyusingthetubeplotfunctionintheplotspackage. 306¯Chapter5:ProgrammingwithMapleGraphics>TieKnot:=proc(n::posint)>locali,t,curve,picts;>curve:=[-10*cos(t)-2*cos(5*t)+15*sin(2*t),>-15*cos(2*t)+10*sin(t)-2*sin(5*t),>10*cos(3*t)]:>picts:=[seq(plots[tubeplot](curve,>t=0..2*Pi*i/n,radius=3),>i=1..n)];>plots[display](picts,insequence=true,style=patch);>endproc:Youcantietheknotin,forexample,sixstages.>TieKnot(6);Thestaticversionis:>display(TieKnot(6));DemonstratingPhysicalObjectsinMotionYoucancombinethegraphicalobjectsfromtheplottoolspackagewiththedisplayin-sequenceoptiontoanimatephysicalobjectsinmotion.Example4ThespringPlotprocedurecreatesaspringfroma3-Dplotofahelix.ThespringPlotprocedurealsocreatesaboxandacopyofthisbox.Itmovesoneoftheboxestovariouslocationsdependingonavalueofu.Foreveryu,locatetheseboxesaboveandbelowthespring.ThespringPlotprocedurethenmakesasphereandtranslatesittolocationsabovethetopboxwiththeheightvaryingwithaparameter.Itproducestheentireanimationbyorganizingasequenceofpositionsandshowingtheminsequencebyusingdisplay.>springPlot:=proc(n)>localu,curve,springs,box,tops,bottoms,>helix,ball,balls;>curve:=(u,v)->spacecurve(>[cos(t),sin(t),8*sin(u/v*Pi)*t/200],>t=0..20*Pi, 5.8Animation¯307>color=black,numpoints=200,thickness=3):>springs:=display([seq(curve(u,n),u=1..n)],>insequence=true):>box:=cuboid([-1,-1,0],[1,1,1],color=red):>ball:=sphere([0,0,2],grid=[15,15],color=blue):>tops:=display([seq(>translate(box,0,0,sin(u/n*Pi)*4*Pi/5),>u=1..n)],insequence=true):>bottoms:=display([seq(translate(box,0,0,-1),>u=1..n)],insequence=true):>balls:=display([seq(translate(ball,0,0,>4*sin((u-1)/(n-1)*Pi)+8*sin(u/n*Pi)*Pi/10),>u=1..n)],insequence=true):>display(springs,tops,bottoms,balls,>style=patch,orientation=[45,76],>scaling=constrained);>endproc:ThecodeinthespringPlotprocedureusestheshortnamesofcom-mandsfromtheplotsandplottoolspackagestoimprovereadability.Ingeneral,itisrecommendedthatyouuselongnames.TousethisversionofthespringPlotprocedure,youmustßrstloadtheplotsandplottoolspackages.>with(plots):with(plottools):>springPlot(6);>display(springPlot(6));Forinformationonthecommandsintheplottoolspackagerelatedtographicsprocedures,see5.5ProgrammingwiththeplottoolsPackage. 308¯Chapter5:ProgrammingwithMapleGraphics5.9ProgrammingwithColorYoucancoloreachtypeofobjectinplotdatastructures,andaddcolorstoplottingroutines.Thecoloroptionallowsyoutousea:¯Solidcolorbyspecifyinganame,RGBvalue,orHUEvalue¯ColorfunctionbyspecifyingaMapleformulaorfunctionTrythefollowingcommands(outputnotshown).>plot3d(sin(x*y),x=-3..3,y=-3..3,color=red);>plot3d(sin(x*y),x=-3..3,y=-3..3,>color=COLOUR(RGB,0.3,0.42,0.1));>p:=(x,y)->sin(x*y):>q:=(x,y)->ifxplot3d(p,-3..3,-3..3,color=q);Althoughusuallylessconvenient,youcanalsospecifythecolorat-tributesatthelowerlevelofgraphicsprimitives.Atthelowestlevel,youcancoloragraphicalobjectbyincludingaCOLOURfunctionasoneoftheoptionsinsidetheobject.>PLOT(POLYGONS([[0,0],[1,0],[1,1]],>[[1,0],[1,1],[2,1],[2,0]],>COLOUR(RGB,1/2,1/3,1/4)));10.80.60.40.200.511.52YoucanusediÞerentcolorsforeachpolygonbyusingPLOT(POLYGONS(P1,...,Pn,COLOUR(RGB,p1,...,pn)))or 5.9ProgrammingwithColor¯309PLOT(POLYGONS(P1,COLOUR(RGB,p1)),...,POLYGONS(Pn,COLOUR(RGB,pn)))Forexample,thefollowingtwoPLOTstructuresrepresentthesamepictureofaredandagreentriangle.>PLOT(POLYGONS([[0,0],[1,1],[2,0]],>COLOUR(RGB,1,0,0)),>POLYGONS([[0,0],[1,1],[0,1]],>COLOUR(RGB,0,1,0)));>PLOT(POLYGONS([[0,0],[1,1],[2,0]],>[[0,0],[1,1],[0,1]],>COLOUR(RGB,1,0,0,0,1,0)));10.80.60.40.200.511.52ThethreeRGBvaluesmustbenumbersbetween0and1.GeneratingColorTablesThefollowingproceduregeneratesanm¢ncolortableofRGBvalues.Example1Thecolormapprocedurereturnsasequenceoftwoelements:aPOLYGONSstructureandaTITLE.>colormap:=proc(m,n,B)>locali,j,points,colors,flatten;>#points=sequenceofcornersforrectangles>points:=seq(seq(evalf(>[[i/m,j/n],[(i+1)/m,j/n],>[(i+1)/m,(j+1)/n],[i/m,(j+1)/n]]>),i=0..m-1),j=0..n-1):>#colors=listlistofRGBcolorvalues>colors:=[seq(seq([i/(m-1),j/(n-1),B],>i=0..m-1),j=0..n-1)];>#flattenturnsthecolorslistlistintoasequence>flatten:=a->op(map(op,a));>POLYGONS(points,>COLOUR(RGB,flatten(colors))),>TITLE(cat("Blue=",convert(B,string))); 310¯Chapter5:ProgrammingwithMapleGraphics>endproc:Thefollowingisa10¢10tableofcolors;thebluecomponentis0.>PLOT(colormap(10,10,0));Blue=010.80.60.40.200.20.40.60.81UsingAnimationYoucanuseanimationtovarythebluecomponentoftheprevioustable.Example2Thefollowingcolormapsprocedureusesanimationtogen-erateanm¢n¢fcolortable.>colormaps:=proc(m,n,f)>localt;>PLOT(ANIMATE(seq([colormap(m,n,t/(f-1))],>t=0..f-1)),>AXESLABELS("Red","Green"));>endproc:Forexample,thefollowingfunctionproducesa10¢10¢10colortable(notshown).>colormaps(10,10,10);YoucancreateacolorscaleforHUEcoloringasfollows.>points:=evalf(seq([[i/50,0],[i/50,1],>[(i+1)/50,1],[(i+1)/50,0]],>i=0..49)):>PLOT(POLYGONS(points,COLOUR(HUE,seq(i/50,i=0..49))),>AXESTICKS(DEFAULT,0),STYLE(PATCHNOGRID)); 5.9ProgrammingwithColor¯3110.20.40.60.81TheAXESTICKS(DEFAULT,0)specißcationeliminatestheaxeslabel-ingalongtheverticalaxisbutleavesthedefaultlabelingalongthehori-zontalaxis.YoucancreateacolormapHueprocedurethatcreatesthecolorscaleforanycolorfunctionbasedonHUEcoloring.>colormapHue:=proc(F,n)>locali,points;>points:=seq(evalf([[i/n,0],[i/n,1],>[(i+1)/n,1],[(i+1)/n,0]]>),i=0..n-1):>PLOT(POLYGONS(points,>COLOUR(HUE,seq(evalf(F(i/n)),i=0..n-1))),>AXESTICKS(DEFAULT,0),STYLE(PATCHNOGRID));>endproc:Thebasisofthiscolorscaleisy(x)=sin(¹x)=3for0´x´40.>colormapHue(x->sin(Pi*x)/3,40);0.20.40.60.81Tocreatethegrayscalecoloring,useanarbitraryprocedure,F,be-causegraylevelshaveequalpartsofred,green,andblue.>colormapGraylevel:=proc(F,n)>locali,flatten,points,grays; 312¯Chapter5:ProgrammingwithMapleGraphics>points:=seq(evalf([[i/n,0],[i/n,1],>[(i+1)/n,1],[(i+1)/n,0]]),>i=0..n-1):>flatten:=a->op(map(op,a));>grays:=COLOUR(RGB,flatten(>[seq(evalf([F(i/n),F(i/n),F(i/n)]),>i=1..n)]));>PLOT(POLYGONS(points,grays),>AXESTICKS(DEFAULT,0));>endproc:Theidentityfunction,x7!x,yieldsthebasicgrayscale.>colormapGraylevel(x->x,20);0.20.40.60.81AddingColorInformationtoPlotsYoucanaddcolorinformationtoanexistingplotdatastructure.Example3TheprocedureaddCurvecolorcolorseachcurveinaCURVESfunctionviathescaledycoordinates.>addCurvecolor:=proc(curve)>locali,j,N,n,M,m,curves,curveopts,p,q;>>#Getexistingpointinformation.>curves:=select(type,[op(curve)],>list(list(numeric)));>#Getalloptionsbutcoloroptions.>curveopts:=remove(type,[op(curve)],>{list(list(numeric)),>specfunc(anything,COLOR),>specfunc(anything,COLOUR)});>>#Determinethescaling.>#Mandmarethemaxandminofthey-coords.>n:=nops(curves);>N:=map(nops,curves);>M:=[seq(max(seq(curves[j][i][2],>i=1..N[j])),j=1..n)];>m:=[seq(min(seq(curves[j][i][2], 5.9ProgrammingwithColor¯313>i=1..N[j])),j=1..n)];>#BuildnewcurvesaddingHUEcolor.>seq(CURVES(seq([curves[j][i],curves[j][i+1]],>i=1..N[j]-1),>COLOUR(HUE,seq((curves[j][i][2]>-m[j])/(M[j]-m[j]),>i=1..N[j]-1)),>op(curveopts)),j=1..n);>endproc:Forexample:>c:=CURVES([[0,0],[1,1],[2,2],[3,3]],>[[2,0],[2,1],[3,1]]);c:=CURVES([[0;0];[1;1];[2;2];[3;3]];[[2;0];[2;1];[3;1]])>addCurvecolor(c);CURVES([[0;0];[1;1]];[[1;1];[2;2]];[[2;2];[3;3]];12COLOUR(HUE;0;;));CURVES([[2;0];[2;1]];33[[2;1];[3;1]];COLOUR(HUE;0;1))Toapplythenewcoloringtoaplot,maptheaddCurvecolorproce-dureoveralltheCURVESobjectsofanexistingplotstructure.>addcolor:=proc(aplot)>localrecolor;>recolor:=x->ifop(0,x)=CURVESthen>addCurvecolor(x)>elsexendif;>map(recolor,aplot);>endproc:Tryaddcoloronaplotofsin(x)+cos(x).>p:=plot(sin(x)+cos(x),x=0..2*Pi,>linestyle=2,thickness=3):>addcolor(p); 314¯Chapter5:ProgrammingwithMapleGraphics10.50123456x–0.5–1Ifyouspecifycolorfortwocurvesinthesamedisplay,thetwocoloringsareindependent.>q:=plot(cos(2*x)+sin(x),x=0..2*Pi):>addcolor(plots[display](p,q));10.5x1234560–0.5–1–1.5–2Theaddcolorprocedurealsoworkson3-Dspacecurves.>spc:=plots[spacecurve]([cos(t),sin(t),t],t=0..8*Pi,>numpoints=100,thickness=2,color=black):>addcolor(spc); 5.9ProgrammingwithColor¯315Youcanalterthecoloringofanexistingplotbyusingcoloringfunc-tions.ColoringfunctionsmustbeoftheformCHue:R2![0;1](forHuecoloring)oroftheformCRGB:R2![0;1]¢[0;1]¢[0;1](forRGBcolor-ing).Example3usesthecolorfunctionCHue(x;y)=y=max(yi).CreatingAChessBoardPlotExample4showshowtomakeachessboardtypegridwithredandwhitesquaresina3-Dplot.Note:Donotsimplyassignacoloringfunctionasanargumenttoplot3d.Acoloringfunction,insuchacase,providescolorsfortheverticesofthegridinsteadofthecolorpatches.Example4Youmustßrstconvertthegridormeshtopolygonalform.Theremainderoftheprocedureassignseitheraredorwhitecolortoapolygon,dependingonwhichgridareaitrepresents.>chessplot3d:=proc(f,r1,r2)>localm,n,i,j,plotgrid,p,opts,coloring,size;>>#obtaingridsize>#andgeneratetheplottingdatastructure>ifhasoption([args[4..nargs]],grid,size)then>m:=size[1];>n:=size[2];>else#defaults>m:=25;>n:=25;>endif;>>p:=plot3d(f,r1,r2,args[4..nargs]);>>#convertgriddata(firstoperandofp)>#intopolygondata>plotgrid:=op(convert(op(1,p),POLYGONS));>#makecoloringfunction-alternatingredandwhite>coloring:=(i,j)->ifmodp(i-j,2)=0then>convert(red,colorRGB)>else>convert(white,colorRGB)>endif;>#op(2..-1,p)isalltheoperandsofpbutthefirst>PLOT3D(seq(seq(POLYGONS(plotgrid[j+(i-1)*(n-1)],>coloring(i,j)),>i=1..m-1),j=1..n-1),>op(2..-1,p));>endproc: 316¯Chapter5:ProgrammingwithMapleGraphicsThefollowingisachessboardplotofsin(x)sin(y).>chessplot3d(sin(x)*sin(y),x=-Pi..Pi,y=-Pi..Pi,>style=patch,axes=frame);10.50–0.5–1–3–3–2–2–1–1y00x112233Note:Thechessplot3dprocedureworkswhentheplotstructurefromplot3disofGRIDorMESHoutputtype.TheMESHoutputtypeisusedforparametricsurfacesorsurfacesthatusealternatecoordinatesystems,forexample,>chessplot3d((4/3)^x*sin(y),x=-1..2*Pi,y=0..Pi,>coords=spherical,style=patch,>lightmodel=light4);5.10ConclusionInthischapter,youhavelearnedhowtomakegraphicsproceduresbasedontheplotandplot3dcommands,aswellasthecommandsfoundintheplotsandplottoolspackages.However,forgreatercontrol,youmustcreatePLOTandPLOT3Ddatastructuresdirectly;thesearetheprimitive 5.10Conclusion¯317specißcationsofallMapleplots.InsidePLOTdatastructures,youcanspecify,forexample,point,curve,andpolygonobjects.InsidePLOT3Ddatastructures,youcanspecifytheobjectsusedinPLOTstructuresaswellas,forexample,gridsofvaluesandmeshesofpoints.Youhavealsolearnedhowtohandleplotoptions,createnumericalplottingprocedures,workwithgridsandmeshes,manipulateplotsandanimations,andapplynon-standardcoloringtographics. 318¯Chapter5:ProgrammingwithMapleGraphics 6AdvancedConnectivityInThisChapter¯CodeGeneration¯ExternalCalling:UsingCompiledCodeinMaple¯OpenMaple:UsingMapleinCompiledCodeCodeGenerationTheCodeGenerationpackageprovidesutilitiesfortranslatingMaplecodeintootherprogramminglanguagessuchasC,Fortran,Java,MATLAB,andVisualBasic•r.Theresultingcodecanbecompiledandusedinde-pendentofMaple.ExternalCalling:UsingCompiledCodeinMapleCompiledcodecanbeseamlesslyintegratedintoMaple.Maplecanex-ecutefunctionswritteninC,Fortran,orJava,passingparametersandreturningvaluesasiftheexternalfunctionwereanativeMaplepro-cedure.UsingcompiledcodetrulyextendstheMaplekernel.ThekernelextensionmustbereliablebecauseitcanaÞecttheentireMapleprogram.OpenMaple:UsingMapleinCompiledCodeMaplecanbeusedbycompiledCorC++codeusingOpenMapleTM.TheOpenMapleApplicationProgrammingInterface(API)providesaccesstoMaplealgorithmsanddatastructures.6.1CodeGenerationTheCodeGenerationPackageConversionofMaplecodetootherprogramminglanguagescanbeper-formedusingtheCodeGenerationpackage.Translatorstoseveralpro-319 320¯Chapter6:AdvancedConnectivitygramminglanguagesareavailable.Foracompletelist,referto?Code-Generation.YoucanusetheMaplesymbolicenvironmenttodevelopanumericalgorithm,andthentranslateittoanotherlanguageforinclusioninanexistingprogramorforfasterexecution.Toperformatranslationtooneofthesupportedlanguages,usetheCodeGenerationpackagefunctionofthesamename,orthecontext-sensitivemenuoptionsintheworksheetenvironment.Youcanalsoextendthepredeßnedtranslatorsorcreatetranslatorsforotherprogramminglanguages.Important:YoumaybefamiliarwiththeCandfortranfunctionsinthecodegenpackage.ItisrecommendedthatyouusethenewerCodeGenerationpackageinstead.However,thecodegenpackagealsocontainsanumberofsupportfunctionsnotcurrentlyavailableintheCodeGenerationpackage,whichcanbeusedtopreprocesstheMapleinputbeforetranslationwiththeCodeGenerationfunctions.CallingCodeGenerationFunctionsCalltheCodeGenerationfunctionsusingthefollowingsyntax,whereLisoneofthesupportedlanguages,forexample,C.CodeGeneration[L](expression,options)Theexpressioncantakeoneofthefollowingforms.¯Asinglealgebraicexpression:Maplegeneratesastatementinthetargetlanguageassigningthisexpressiontoavariable.¯Alistofequationsoftheformname=expression:Mapleinterpretsthisasasequenceofassignmentstatements.Maplegeneratestheequivalentsequenceofassignmentstatementsinthetargetlanguage.¯Alist,array,orrtable:Maplegeneratesastatementorsequenceofstatementsassigningtheelementstoanarrayinthetargetlanguage.¯AMapleprocedureormodule:Maplegeneratesanequivalentstruc-tureinthetargetlanguage.Forexample,totranslateaproceduretoC,Maplegeneratesafunctionalongwithanynecessarydirectivesforlibraryinclusion.TotranslateamoduletoJava,Maplegener-atesaJavaclassdeclarationwithexportstranslatedtopublicstaticmethodsandmodulelocalstranslatedtoprivatestaticmethods.Fordetailedinformationontranslationtoaspecißclanguage,refertothehelppagesforthatlanguage,forexample,?CodeGeneration[C]and?CodeGeneration/General/CDetails. 6.1CodeGeneration¯321YoucanusemanyoptionswiththeCodeGenerationfunctions.Fordetailedinformation,refertothe?CodeGenerationOptionshelppage.Someofthemorecommonlyusedoptionsfollow.¯optimize=value:Thisoptionspecißeswhetheroptimizationisper-formed.Thedefaultvalueisfalse.Whenthevalueistrue,thecodegen[optimize]functionisusedtooptimizetheMaplecodebe-foreitistranslated.¯output=value:Thisoptionspecißestheformoftheoutput.Byde-fault,formattedoutputisprintedtotheterminal.Ifaname(diÞerentfromthenamestring)orastringisspecißedasthevalue,theresultisappendedtoaßleofthatname.Ifthevalueisthenamestring,astringcontainingtheresultisreturned.Thisstringcanthenbeassignedandmanipulated.¯reduceanalysis=value:ThisoptionspecißeswhetherareducedformoftypeanalysisisperformedinthecasethattheMaplein-putisalistofequationsrepresentingacomputationsequence.Us-ingthedefaultvalue,reduceanalysis=false,canreducethenum-beroftypemismatchesinthetranslatedcode.However,usingthereduceanalysis=trueoptioncansignißcantlyreducethetimeandmemoryrequiredfortranslation.NotesonCodeTranslationBecausetheMaplelanguagediÞerssub-stantiallyfromthetargetlanguagessupportedbyCodeGeneration,thetranslationcapabilitiesarelimited,andthegeneratedoutputmaynotbetheexactequivalentoftheinputcode.The?CodeGenerationDetailshelppageprovidesmoreinformationonthetranslationprocessandhintsonhowtotakefulladvantageofthefacilities.Inaddition,therearehelppagescontainingnotesrelevanttospecißclanguages.Forde-tailsrefertothehelppagesforthecorrespondinglanguage,forexample,?CodeGeneration/General/CDetails.TranslationProcessTheCodeGenerationfunctionsrecognizeonlyasubsetoftheMapletypes.Thesearelistedonthe?CodeGenerationDetailshelppage.TheMapletypesaretranslatedtoappropriatetypesinthetargetlanguage.Compatibilityoftypesischeckedbeforeoperationsaretranslated,andtypecoercionsareperformedifnecessary.TheCodeGenerationfunc-tionsattempttodeducethetypeofanyuntypedvariable.Youcanexercisegreatercontrolovertypeanalysisanddeductionbyusingthe 322¯Chapter6:AdvancedConnectivitycoercetypes,declare,deducetypesanddefaulttypeoptions,asde-scribedonthe?CodeGenerationOptionshelppage.TheCodeGenerationfunctionscantranslateasubsetoftheMaplefunctions.Thesearelistedonthe?CodeGenerationDetailshelppage.Somefunctionsaretranslatedonlytocertaintargetlanguages.Formoreinformationaboutaspecißclanguage,refertoitsdetailedhelppage,forexample,?CodeGeneration/General/CDetails.Thereturntypeofaprocedureisdeducedifyoudonotdeclareit.Ifmorethanonereturnstatementispresent,thetypesofallobjectsreturnedmustbecompatibleinthetargetlanguage.Ifareturnstatementcontainsasequenceofobjects,thesequenceistranslatedtoanarray.Implicitreturnsarerecognizedinsomesituatiions,buttranslationstoexplicitreturnscanbesuppressedwiththededucereturn=falseoption.Whennecessary,anautomaticallygeneratedreturnvariableisusedtoholdareturnvalue.Lists,Mapleobjectsoftypearray,andrtablesaretranslatedtoarraysinthetargetlanguage.Typeanalysisanddeductioncapabilitieswithrespecttoarraysareverylimited.Itisrecommendedthatyoudeclarethetypeandrangesforallarrays.Insometargetlanguages,arraysarereindexedtobeginatindex0.Example1ThefollowingexampledemonstratesthetranslationofaproceduretoJava.>f:=proc(x)>localy;>y:=ln(x)*exp(-x);>printf("Theresultis%f",y);>endproc:>CodeGeneration[Java](f);importjava.lang.Math;classCodeGenerationClass{publicstaticvoidf(doublex){doubley;y=Math.log(x)*Math.exp(-x);System.out.print("Theresultis"+y);}}Example2ThefollowingexampledemonstratesthetranslationofaproceduretoC.Thedefaulttypeoptionsetsthedefaulttypetointeger, 6.1CodeGeneration¯323andtheoutputoptionspecißesthatastringisreturned.Inthiscase,theoutputisassignedtothevariables.>g:=proc(x,y,z)>returnx*y-y*z+x*z;>endproc:>s:=CodeGeneration[`C`](g,defaulttype=integer,output=string);s:=Õintg(intx,inty,intz)n{nreturn(x*y-y*z+x*z);n}nÔExample3ThefollowingexampledemonstratesthetranslationofaproceduretoFortran.BecauseFortran77iscase-insensitive,thevariableXisrenamedtoavoidaconàictwiththevariablex.>h:=proc(X::numeric,x::Array(numeric,5..7))>returnX+x[5]+x[6]+x[7];>endproc:>CodeGeneration[Fortran](h);Warning,Thefollowingvariablenamereplacementsweremade:[cg]=[X]doubleprecisionfunctionh(cg,x)doubleprecisioncgdoubleprecisionx(5:7)h=cg+x(5)+x(6)+x(7)returnendTheIntermediateCodeAllMapleinputtoCodeGenerationtransla-torsisprocessedandconvertedtoaninertintermediateformknownastheintermediatecode.TheintermediatecodeisthebasicobjectuponwhichallCodeGenerationtranslatorsoperate.Forinformationabouttheinter-mediatecode,referto?CodeGeneration/General/IntermediateCodeStructure.ThenamesappearinginintermediatecodeexpressionsaremembersofthesubpackageCodeGeneration:-Names.ErrorandwarningmessagesissuedfromCodeGenerationpackagefunctionssometimesrefertotheintermediateformoftheMapleexpres-sionthattriggeredthemessage.Whendeterminingthecauseofanerrormessageorwritinganddebug-gingcustomlanguagedeßnitions,itisrecommendedthatyoudetermine 324¯Chapter6:AdvancedConnectivitytheintermediateformofaMapleexpressioninput.Ingeneralyoucande-terminetheintermediateformwiththeCodeGeneration:-IntermediateCodetranslator.However,becausesomeaspectsoftheintermediatecodearespecißctothelanguagetowhichyouaretranslating,itmayhelptoseetheintermediatecodeforaspecißctranslator.Thiscanbedonebysettinginfolevel[CodeGeneration]toavaluegreaterthan3andperformingatranslation.Example4showstheintermediatecodefortheexpression2x21.TheßrstargumentoftheScopestructureisthenameofatypetableusedinternallyduringthetranslationprocess.Example4Thefollowingexampleshowstheintermediateformoftheexpression2x21.>CodeGeneration[IntermediateCode](2*x^2-1);Scope(nametab,StatementSequence(Assignment(GeneratedName("cg"),Sum(Product(Integer(2),Power(Name("x"),Integer(2))),Negation(Integer(1))))))ExtendingtheCodeGenerationTranslationFacilitiesTheCodeGenerationpackageisdistributedwithtranslatorsforsev-eralprogramminglanguages.Inaddition,youcandeßnenewtransla-torstoenableCodeGenerationtogeneratecodeforotherlanguages.ToolsforthistaskareavailableintheLanguageDefinitionsubpack-ageofCodeGeneration.Customtranslatorscandeßnealanguageinitsentirety,orextendex-istinglanguagedeßnitions,overridingandextendingonlythoselanguagecomponentsthatneedtobechanged.ToseealistoflanguagescurrentlyrecognizedbyCodeGeneration,andthusavailableforextending,usetheCodeGeneration:-LanguageDefinition:-ListLanguagescommand.ThePrintingPhaseAsnotedpreviously,theCodeGenerationpackageßrstprocessestheMapleinputandtranslatesittoanintermediateform.Thisisfollowedbytheprintingphase,whichtranslatestheintermediateformtoaMaplestringaccordingtotransformationrulesspecißctothetargetlanguage.Foreachnameusedintheintermediateform,thereisaprinthandlerprocedure.Duringtheprintingphase,Mapletraversestheintermediate 6.1CodeGeneration¯325formrecursively.Foreachsubexpressionoftheintermediateform,Maplecallstheprinthandlerassociatedwiththatclassofexpressions.DeßningaCustomTranslatorThissectionexplainstheprocessofdeßningatranslatorforatargetlanguage.UsingaPrinterModuleWitheachCodeGenerationlanguagedeßni-tionthereisanassociatedMaplemodule,calledaPrintermodule,whichcontainslanguage-specißcprinthandlersanddata.APrintermodulehasanumberoffunctions,whichsetandreferencelanguage-specißcprintingdata.TherearetwowaystoobtainaPrintermodule.TheLanguageDefinition:-GenericPrinter()returnsagenericPrintermodulecontainingnolanguage-specißcdata,andtheLanguageDefinition:-Get(language_name):-PrintercommandreturnsacopyofthePrintermoduleusedforapreviouslydeßnedlanguagelanguage_name.Themostfrequently-usedPrinterpackagefunctionisthePrintcom-mand.Givenastring,PrintprintsthestringtoabuÞer.Givenanintermediate-formexpression,Printinvokestheprinthandlerappro-priatefortheexpression.Inthismanner,PrintrecursesthroughtheintermediateformuntilitisprintedinitsentiretytothebuÞer.Atthispoint,translationiscomplete.Table6.1listsimportantPrinterfunctions.Foracompletelistingandmoredetailedinformation,referto?CodeGeneration/LanguageDefinition/Printer.Example5ThisexampleillustrateshowdataisstoredandretrievedfromaPrintermodule.>with(CodeGeneration:-LanguageDefinition):>Printer:=GenericPrinter(); 326¯Chapter6:AdvancedConnectivityTable6.1SelectPrinterFunctionsAddFunctionDeßneatranslationforafunctionnameandtypesignatureAddOperatorDeßneatranslationforaunaryorbinaryoperatorAddPrintHandlerSetaproceduretobetheprinthandlerforanintermediateformnameGetFunctionGetatranslationforafunctionnameandtypesignatureGetOperatorGetatranslationforaunaryorbinaryoperatorGetPrintHandlerGetthecurrent`printhandler'procedureforanintermediateformnameIndentIndentaprintedlinewhensuppliedasanargumenttoPrintPrintPrintargumentstobuÞerPrintTargetInitiateprintingofanintermediateformPrinter:=module()exportPrintTarget;GetFunctionSignature;AddLibrary;AddOperator;GetOperator;AddType;GetType;AddPrintHandler;GetPrintHandler;SetLanguageAttribute;ApplyLanguageAttribute;GetLanguageAttribute;AddFunction;AddFunctions;GetFunction;SetPrecedence;GetPrecedence;GetIncludes;GetExpressionType;GetScopeName;GetScopeStructure;Indent;PopIndentation;PushIndentation;Endline;Linebreak;Print;PrintBinary;PrintParentheses;PrintStatementBlock;PrintDelimitedList;PrintUnary;:::endmodule>Printer:-AddOperator(Addition="+");Õ+Ô>Printer:-AddFunction("sin",[numeric]::numeric,"sine");[ÕsineÔ;fg] 6.1CodeGeneration¯327>Printer:-GetOperator(Addition);Õ+Ô>Printer:-GetFunction("sin",[numeric]::numeric);[ÕsineÔ;fg]Withinalanguagedeßnition,thePrintermoduleassociatedwiththelanguagedeßnitioncanbereferencedbythenamePrinter.(Note:Thisappliesforbothlanguagedeßnitionmethodsdescribedinthenextsection.)LanguageTranslatorDeßnitionTherearetwodistinctmethodsofdeßningalanguagetranslatorforusebyCodeGeneration:usingtheLanguageDefinition:-Definecommandandcreatingalanguagedeß-nitionmodule.Forsimplelanguagesorsmallextensionsofexistinglanguages,usetheLanguageDefinition:-Definemethod.Toproduceatranslatorthatpreprocessesorpostprocessesthegeneratedoutput,ormakesfrequentuseofautilityfunctionintranslations,createalanguagedeßnitionmodule.Note:ThetranslatorssuppliedwiththeCodeGenerationpackage,forexample,C,VisualBasic,andJava,areimplementedusinglanguagedef-initionmodules.UsingtheDefinecommandTheDefinecommandtakesaseriesoffunctioncallargumentsf1,f2,...wherethefunctionnamesare,forexample,AddFunction,AddFunctions,AddOperator,AddPrintHandler,AddType,andSetLanguageAttribute.ThesefunctioncallsacceptidenticalsyntaxandperformthesameactionsasthePrinterfunctionsofthesamename.Thatis,theydeßneprinthandlersandotherdataspecißctothelanguagetranslationyouaredeßning.Formoreinformationontheirpurposeandacceptedsyntax,referto?CodeGeneration/LanguageDefinition/Printer.Note:TheDefinecommandautomaticallycreatesaPrintermoduleforthelanguage.YoudonotneedtocreateoneusingLanguageDefinition:-GenericPrinterorLanguageDefinition:-Get. 328¯Chapter6:AdvancedConnectivityExample6ThisexampleillustratesaCtranslator,inwhichthetrans-latedcodeusesaspecializedlibraryfunctionmy_multformultiplicationinsteadofthebuilt-in*operator.>CodeGeneration:-LanguageDefinition:-Define("MyNewLanguage",>extend="C",>AddPrintHandler(>CodeGeneration:-Names:-Product=proc(x,y)>Printer:-Print("mymult(",args[1],",",args[2],>")");>endproc>)>):Note:Inthepreviousexample,oneoftheargumentsoftheLanguageDefinition:-DefinecommandisthefunctioncallAddPrintHandler,whichtakesanameandaprocedureasarguments.ThismakesthesuppliedprocedureresponsibleforprintinganyProductsubexpressionoftheintermediateform.ThecalltoPrinter:-Printspec-ißesthatthetranslatorusestheautomatically-generatedPrintermod-ule.Example7ThisexampledeßnesalanguageMyLanguage.Itspecißes,amongotherinstructions,thattheadditionoperationshouldbetrans-latedasplus,themultiplicationoperationastimes,andtheassignmentoperationas:=.Oncedeßned,thetranslatorisusedtoconvertasimpleMapleexpressiontoMyLanguage.>CodeGeneration:-LanguageDefinition:-Define("MyLanguage",>AddOperator(>CodeGeneration:-Names:-Addition="plus",>CodeGeneration:-Names:-Division="dividedby",>CodeGeneration:-Names:-Multiplication="times",>CodeGeneration:-Names:-Negation="-",>CodeGeneration:-Names:-Subtraction="minus">),>SetLanguageAttribute(>"Indent_Char"="","Indent_Base"=2,"Indent_Increment"=2>),>AddOperator(CodeGeneration:-Names:-Assignment=":=")>);>CodeGeneration:-Translate(-x+y*z,language="MyLanguage");cg0:=-xplusytimesz; 6.1CodeGeneration¯329Example8ThisexampleextendstheCtranslatortotranslateMapleprintstatementstoC++-stylecoutcommands.>CodeGeneration:-LanguageDefinition:-Define("MyExtensionLanguage",>extend="C",>AddFunction("print",anything::void,>proc(x)>Printer:-Print("cout<<");>Printer:-PrintDelimitedList([args],"<<");>Printer:-Print("<endproc>)>);>p1:=proc()print("abcde")endproc:>CodeGeneration:-Translate(p1,language="MyExtensionLanguage");voidp1(void){cout<<"abcde"<UppercaseFortran77:='module()>exportPrinter,PrintTarget;>Printer:=eval(CodeGeneration:-LanguageDefinition:-Get(>"Fortran")):-Printer;>PrintTarget:=proc(ic,digits,prec,func_prec,namelist)>Printer:-SetLanguageAttribute("Precision"=prec);>StringTools:-UpperCase(Printer:-PrintTarget(args));>endproc:>endmodule':>CodeGeneration:-LanguageDefinition:-Add("UppercaseFortran",>UppercaseFortran77);UsingaNewTranslatorAfteraddingthedeßnitionofthelanguageus-ingeithertheLanguageDefinition:-DefineorLanguageDefinition:-Addcommands,translatetothenewlanguageusingtheCodeGeneration:-Translatecommand.Example10Thisexampledemonstratestheuseofanewtranslator.ComparetheoutputoftheFortrancommandwiththatofthenewtrans-lator.>p1:=proc()sin(x+y*z)+trunc(x);endproc:>CodeGeneration:-Fortran(p1);doubleprecisionfunctionp1()p1=sin(x+y*z)+dble(int(aint(x)))returnend>CodeGeneration:-Translate(p1,language="UppercaseFortran");DOUBLEPRECISIONFUNCTIONP1()P1=DSIN(X+Y*Z)+DBLE(INT(DINT(X)))RETURNEND6.2ExternalCalling:UsingCompiledCodeinMapleThefollowingthreecallingmethodsarepresentedinthissection. 6.2ExternalCalling:UsingCompiledCodeinMaple¯331¯CallingExternalFunctions¯GeneratingWrappers¯CustomizingWrappersAnyofthefollowingthreemethodscanbeusedtocallanexternalfunction.Typically,method1issuácient.Methods2and3canbeusedwhenmorecontrolovertypeconversionsorgreateraccesstoMapledatastructuresisneeded.Eachmethodbuildsuponthepreviousone.Whenconsideringmethod3,readaboutmethods1and2ßrst.Method1:CallingExternalFunctionsInmostcases,compiledfunc-tionsuseonlystandardhardwaretypeslikeintegers,àoating-pointnum-bers,strings,pointers(tostrings,integers,andàoating-pointnumbers),matrices,andvectors.Inthesecases,theMaplesoftwareautomaticallytranslatesbetweenitsinternalrepresentationandthehardwarerepresen-tation.Thismethodiseácientandeasytousebecauseitdoesnotrequiretheuseofacompiler.Thismethodofdirectlycallingtheexternalcodeallowstheuseofanexternallibrarywithoutmodißcation.Method2:GeneratingWrappersMethod1canuseonlystandarddatatypes.Whendealingwithcomplicatedcompoundtypesorpassingfunc-tionsorrecordsasparameters,acompiledwrapperisneeded.JavaandFortrandonotusethesedatastructures;thismethodappliesonlytoCroutines.ThewrapperperformstheconversionbetweentheMapleinter-nalrepresentationandthehardwarerepresentation.Mapleautomaticallygeneratesandcompileswrappers(basedonyourspecißcations)tointer-facewithlibrariesofcompiledcode.Comparedtodirectlycallingtheexternalfunction,youcanuseamorediversesetofexternallibraries.ExternalcallsthatusethesewrappersrequireaCcompiler.Method3:CustomizingWrappersForàexibilitybeyondtheothermethods,anexternalAPIallowsyoutoaugmentexistingwrappersorwritecustomwrappers.YoucanwritethewrapperinCorFortran.ThispowerfulmethodalsoallowsdirectaccesstoMapledatastructuresfromthewrapper.CallingMethodsSummary¯Anyofthemethods(1-3)canbeusedtocallaCfunction.¯Methods1or3canbeusedtocallaFortranfunction.Method2isnotapplicabletoFortranfunctions. 332¯Chapter6:AdvancedConnectivity¯Onlymethod1isavailableforcallingaJavamethod(Onlystaticmethodscanbecalled).Method1:CallingExternalFunctionsTounderstandtheMapleexternalcallingfacility,considerthefollowingCcodethataddstwonumbersandreturnstheresult.NotethatsuchafunctionwouldneverbeusedbecausetheMaple+operatorexists,butworkingthroughthisexampledemonstratesthestepsrequiredtousecompiledcodeinMaple.intadd(intnum1,intnum2){returnnum1+num2;}Thereare3basicstepsrequiredtocallanexternalfunction.Step1:DLLCreationFirst,thisfunctionmustbecompiledintoaDy-namicLinkLibrary(WindowsXXX.DLL),orSharedLibrary(UNIXlibXXX.soorMacintoshXXX.dylib).Fortherestofthischapter,thecompiledlibraryisreferredtoasaDLL.Ifthesourcesaredownloadedfromtheinternetorpurchased,aDLLmayalreadyhavebeenbuilt.Oth-erwise,consultthecompiler'sdocumentationforhelponhowtobuildaDLL.WhenbuildingtheDLL,ensurethatyouexportthefunctionthatMapleisintendedtobeabletocall.Inthiscase,thefunctionnameisadd.Thisistheonlystepthatrequirestheusertohaveknowledgeofaspecißccompiler.Fortheremainingsteps,itdoesnotmatterifthefunctionwaswritteninC,Fortran,orJava.ForMaple,theexternallibraryfunctionsmustbecompiledbyusingthe_stdcallcallingconvention,whichisthedefaultunderUNIXbutmustbespecißedwhenusingmostWindowscompilers.Step2:FunctionSpecißcationTomaketheappropriateargumentcon-versions,Maplerequiresinformationaboutthefunctionthatitcalls.Ataminimum,Maplerequiresthefollowing.¯Nameofthefunction¯Typeofparametersthefunctionpassesandreturns¯NameoftheDLLcontainingthefunctionThespecißcationoftheparametertypesareindependentofthecom-piler.Thesamespecißcationcanbeusedregardlessofthelanguageused 6.2ExternalCalling:UsingCompiledCodeinMaple¯333tocompiletheDLL.TheexampleusestheCtypeint.InMaple,thisisspecißedasinteger[4].The4inthesquarebracketsdenotesthenumberofbytesusedtorepresenttheinteger.MostCcompilersuse4-byteints,butsomeoldercompilersmayuse2-byteints.TheMapletypespecißca-tionsupportsbothtypesofcompilerintegersizes.Foramapofthemostcommontyperelations,seeTable6.2onpage336.Sincenum1andnum2arebothints,theycanbespecißedasthefol-lowinginMaple.num1::integer[4]num2::integer[4]ThereturntypedoesnothaveanamesothekeywordRETURNisused.RETURN::integer[4]Usingallofthisinformation,thecompletefunctioncanbedeßnedbycallingtheMaplefunctiondefine_external.>myAdd:=define_external(>'add',>'num1'::integer[4],>'num2'::integer[4],>'RETURN'::integer[4],>'LIB'="mylib.dll">);Important:Specifythefunctionexactly,andensurethattheargumentsareinthecorrectorder.FailuretodothismayresultinstrangebehaviororprogramcrasheswhenexecutingStep3.Step3:FunctionInvocationExecutingthedefine_externalcallformyAddreturnsaMapleprocedurethattranslatesMapletypestohardwaretypesthatcanworkwithanexternalfunction.ThisprocedurecanbeusedthesamewayasotherMapleprocedures.>myAdd(1,2);3>a:=33:>b:=22: 334¯Chapter6:AdvancedConnectivity>myAdd(a,b);55>r:=myAdd(a,11);r:=44Important:Proceduresgeneratedinthismannercontainrun-timeinfor-mationandthuscannotbesaved.Thedefine_externalcommandmustbereissuedafterexitingorrestartingMaple.ThefollowingsubsectionsprovideadditionalinformationforStep2,thefunctionspecißcation.ExternalDeßnitionThedefine_externalfunctionconstructsandreturnsanotherfunctionwhichcanbeusedtomaketheactualcall.Thedefine_externalfunctioniscalledasfollows.define_external(functionName,LANGUAGE,arg1::type1,...,argN::typeN,options,`LIB`=dllName)define_external(functionName,`MAPLE`,options,`LIB`=dllName)¯ThefunctionNameparameterspecißesthenameoftheactualexternalfunctiontobecalled.ThisnamecanbespecißedasaMaplestringorname.¯TheLANGUAGEparameterdenotestheprogramminglanguageusedtocompiletheDLL.ThedefaultisC.OtherrecognizedlanguagesareJAVAandFORTRAN.¯Theparametersarg1throughargNdescribetheargumentsofthefunctiontobecalled.Theseshouldbespecißedintheordertheyappearinthedocumentationorsourcecodefortheexternalfunc-tion,withoutregardtoissuessuchasactualpassingorder(lefttorightversusrighttoleft).TheintentisthattheMapleproceduredefine_externalreturnshasthesamecallingsequenceastheactual 6.2ExternalCalling:UsingCompiledCodeinMaple¯335externalfunctionwhenusedinthelanguageforwhichitwaswrit-ten.TheonlyexceptionisthatoneargumentmaybegiventhenameRETURN.Thisspecißesthetypereturnedbythefunctionratherthanaparameterpassedtothefunction.Formoreinformationabouthoweachargiisspecißed,seethefollowingTypeSpecißcationsubsec-tion.¯Theoptionsareusedtospecifyargumentpassingconventions,li-braries,orcallingmethods.Fordetails,seetheappropriatesectionsofthischapter.¯Ifinsteadoftheargparameters,thesinglewordMAPLEisspecißed,theexternalfunctionisassumedtoaccepttherawMapledatastructurespassedwithoutconversion.ThisassumesthatthewrapperhasbeenmanuallygeneratedandcompiledintoaDLL.Varioussupportfunc-tionsforwritingsuchexternalfunctionsaredescribedinMethod3:CustomizingWrappersonpage350.UsingMAPLEinsteadofspecifyingargumentsisthebasisofmethod3.¯ThenameoftheDLLcontainingtheexternalfunctionisspecißedbyusingtheLIBoptiontodefine_external.ThedllNameisastringthatspecißestheßlenameofthelibraryinwhichthefunctionistobefound.Theformatofthisnameishighlysystemdependent.Likewise,whetherafullpathnameisrequireddependsonthesystem.Ingeneral,thenameshouldbeinthesameformataswouldbespecißedtoacompileronthesamesystem.WhencallingaJavamethod,dllNameisthenameoftheclasscontainingthemethod.TypeSpecißcationSteptwooftheintroductoryexampleindicatedhowtospecifytypesusingMaplenotation.Mapleusesitsownnotationtoprovideagenericwell-deßnedinterfaceforcallingcompiledcodeinanylanguage.Theformatofeachargparameterisasfollows.argumentIdentifier::dataDescriptorThereturnvaluedescriptionisalsodescribedbyusingadatade-scriptor,withthenameRETURNastheargumentIdentißer.Ifthefunctionreturnsnovalue,noRETURNparameterisspecißed.Also,ifnoparametersarepassed,noargumentidentißersarerequired. 336¯Chapter6:AdvancedConnectivityTable6.2BasicTypeTranslationsMapleDataCTypeFortranTypeJavaTypeDescriptorinteger[1]charBYTEbyteinteger[2]shortINTEGER*2shortinteger[4]intINTEGERintlong1INTEGER*4integer[8]long1INTEGER*8longlonglongINTEGER*8float[4]floatREALfloatREAL*4float[8]doubleDOUBLEPRECISIONdoubleREAL*8char[1]charCHARACTERcharboolean[1]charLOGICAL*1booleanboolean[2]shortLOGICAL*2boolean[4]intLOGICALlongLOGICAL*4boolean[8]longLOGICAL*8longlongLOGICAL*81TheCtypelongistypically(butnotnecessarily)4-byteson32-bitmachinesand8-byteson64-bitmachines.Usethesizeofoperatororconsultyourcompilermanualtoverifysizeof(long).ScalarDataFormatsExternallibrariesgenerallydealwithscalardatasupporteddirectlybytheunderlyingmachine.Allarray,string,andstructuredformatsarebuiltupfromthese.Thedatadescriptorsusedtorepresentscalarformatsusuallycontainatypenameandsize.Thesizerepresentsthenumberofbytesneededtorepresentthegivenhardwaretype.Table6.2liststhebasictypetranslationsforstandardC,Fortran,andJavacompilers.StructuredDataFormatsInadditiontothebasictypeslistedinTable6.2,Maplealsorecognizessomecompoundtypesthatcanbederivedfromthebasictypes,suchasarraysandpointers.ThesecompoundtypesarelistedinTable6.3onpage393. 6.2ExternalCalling:UsingCompiledCodeinMaple¯337CharacterStringDataFormatsStringsaresimilartobothscalarandarraydata.AstringinCisanarrayofcharacters,butitisoftenmanip-ulatedasifitwereanobject.AstringinMapleisanatomicobject,butitcanbemanipulatedasifitwereanarrayofcharacters.Parameterninstring[n]indicatesthatthecalledfunctionisexpectingaßxedsizestring.Otherwise,apointertoacharacterbuÞer(char*)isused.Stringsareimplicitlypassedbyreference(onlyapointertothestringispassed),butanychangesmadetothestringarenotcopiedbacktoMapleunlessthestringisdeclaredwithasize.DeclaringasizeonastringtobepassedtoaJavamethodhasnoeÞect.Thestringsizewillnotbelimited,andmodißcationsarenotcopiedback.ArrayDataFormatsAnarrayofdataisahomogeneous,n-rectangularstructurematchingtheMaplertableformats.Anydatatypethatisac-ceptedbytheMapleArray,Matrix,orVectorconstructorareaccepted.Theoptionsareusedtospecifyarrayconventions.TheyarethesameoptionalargumentsthatcanbepassedtotheArrayconstructorinMaple.TheonlysignißcantdiÞerenceisthatindexingfunctionsmustbespecißedwithindfn=(andarenotallowedunlessusingcustomwrapperexternalcalling).TheseoptionsoverrideanydefaultsnormallyassumedbytheArrayconstructor.datatype=...Onlyhardwaredatatypesareallowed.Thisßeldisre-quired,buttheequationformofentryisnotnecessary.Forexample,simplyspecifyinginteger[4]issuácient.order=...ThiscanbeunspecißedforvectorsbecauseFortranandCrepresentationisthesame.Otherwise,thisdefaultstoFortran_orderwhencallingaFortranlibraryandC_orderwhencallingaCorJavalibrary.storage=...Ifthisisnotspecißed,thedefaultisfullrectangularstoragesubtype=...ThisisoptionalandrestrictsthesubtypetoArray,Matrix,Vector[row],orVector[column].indfn=(...,...)ThisspecißestheindexingfunctionsoftheArray,Matrix,orVector.OtherCompoundTypesThereareothertypes,includingrecords(structs),andproceduresthataresupportedwhenusingwrappergen-eratedexternallinking.ThesedatadescriptorsaredescribedinMethod2:GeneratingWrappersonpage338. 338¯Chapter6:AdvancedConnectivitySpecifyingArgumentPassingConventionsDiÞerentprogramminglanguageshavediÞerentconventionsforparameterpassing.Calwaysusespass-by-value;pass-by-referencemustbedoneexplicitlybypassinganaddress.Fortranusespass-by-reference.Pascaluseseither,dependingonhowtheparameterwasdeclared.TheMapleexternalcallingmechanismcurrentlysupportsC,For-tran,andJavacallingconventions.AutomaticwrappergenerationisonlysupportedforC.ThereisanexternalAPIforwritingcustomwrap-persforCandFortranbutnotJava.ThedefaultconventionusedisC.TouseFortrancalling,specifythenameFORTRANasaparametertodefine_external.>f:=define_external(`my_func`,`FORTRAN`,...);TouseJavacalling,specifythenameJAVAasaparametertodefine_external.Also,specifytheCLASSPATH=optiontopointtoclassesused.>f:=define_external(`my_func`,`JAVA`,CLASSPATH="...",...);Someothercompilerimplementations(suchasPascalandC++)canworkwithCexternalcallingbyusingthecorrectdeßnitionsandorderofpassedparameters.Method2:GeneratingWrappersSometypesinMaplearenotsuitableforautomaticconversions.Twoofthesetypesareprocedures(callbacks),andrecords(structs).Mapleprovidesanalternatemechanismforhandlingthiskindofdata.ForadescriptionofthestepsrequiredtousecompiledcodeinMaple,seeMethod1:CallingExternalFunctionsonpage332.Thesamethreebasicsteps(DLLcreation,functionspecißcation,andfunctionin-vocationasdescribedonpages332-334)areusedinthismethod.Theinformationinthissectionextendsthebasicinformationbydescribingtheuseofwrappers.SpecifyingthekeywordWRAPPERinthecalltodefine_externalcausesMapletogeneratecodefordatatranslations.MaplecompilesthiscodeintoaDLLanddynamicallylinkstothenewlibrary.Subse-quentlyinvokingtheprocedurereturnedbydefine_externalcallsthenewlygeneratedconversionroutinebeforecallingtheexternalfunctioninthelibraryyouprovided.TheCcodegeneratedbyMaplewrapstheMapledatastructuresbytranslatingthemtohardwareequivalenttypes.Hence,thecodeßleis 6.2ExternalCalling:UsingCompiledCodeinMaple¯339calledthewrapper,andthelibrarygeneratedbythiscodeiscalledthewrapperlibrary.AdditionalTypesandOptionsGeneratingawrapperßleallowsMapletotranslatemorecomplicatedtypesthatarediáculttohandlewithoutcompilationtechnology.Italsoallowsgreateràexibilitywhendealingwithpointersandpasseddatathatdonotexactlymatchtherequiredtype.Table6.4onpage394listsadditionaltypesthataresupportedwhenthekeywordWRAPPERisspecißed.StructuredDataFormatsAstructureisanon-homogeneouscollectionofmembers,correspondingtoastructinC,orarecordinPascal.Aunionissimilar,exceptthatallthemembersstartatthesamememoryaddress.Eachmember::descriptorpairdescribesonememberofthestructureorunion.Thedescriptorisanyofthetypesdescribedinthischapter.Theoptionsareusedtospecifywhatkindofdatatypethewrap-pershouldexpectforconversionpurposes.Thefollowingtwooptionsaresupported.TABLETablesareusedasthecorrespondingMapletype.Usingtablesisthedefaultbehavior,andtheyareeasiertousethanlists.Whentablesareused,themembernamescorrespondtotableindices.LISTListsareusedasthecorrespondingMapletype.Listsareprimarilyusedinaread-onlybasis.Listscannotbemodißedin-place,somakingupdatestoaliststructureinexternalcoderequiresacopytobemade.WhenstructuresmustbepassedbacktoMaple,oriftheycontainpointertypes,itisbettertousetables.Listsandtablescannotbeusedinterchangeably.Oncethewrapperhasbeengenerated,itacceptsonlythedeclaredtype,notboth.EnumeratedTypesTheMapleexternalcallingmechanismdoesnotdirectlysupportenumer-atedtypes(suchasenuminC).Instead,usetheinteger[n]typewithnofanappropriatesizetomatchthesizeoftheenumeratedtypeofthecompilerwithwhichtheexternalfunctionwascompiled(usuallythisisthesamesizeastheinttype). 340¯Chapter6:AdvancedConnectivityProcedureCallFormatsSomelanguages,likeC,supportpassingfunctionsasarguments.AMapleprocedurecanbepassedtoanexternalfunctioninthesameway.ThewrappersetsupaCstyleproceduretocallMapletoexecutethepassedprocedurewiththegivenarguments.ThisCcallbackisgiventotheex-ternalcalltobeusedlikeanyotherCfunction.Eachmember::descriptorpairdescribesoneparameteroftheproce-dure.Thedescriptorisanyofthetypesdescribedinthischapter.Itisnotpermittedtodeclareaprocedurethatitselftakesaprocedureparameter.Inotherwords,acallbackcannotitselfcallbacktotheexternalcode.CallbyReferenceUnlessoverridden,eachargumentispassedbyvalue.TheREFmodißercanbeusedtooverridethis.argumentIdentifer::REF(dataDescriptor,options)TheREFmodißercantakethefollowingoptions.ANYTHINGThisoptionmustbeßrstinthelistofoptions.UsethisoptiontodeclaretheequivalentofaCvoid*parameter.Thewrappercodeattemptstoconvertpassedargumentstosimpletypes,(4-byteinteger,8-byteàoat,complex,orstring),whenencountered.Ifnoconversiontooneofthesetypesispossible,NULLispassedtotheexternalfunction.CALL_ONLYThisoptionspecißesthatalthoughtheobjectistobepassedbyreference,anychangesmadebytheexternalfunctionarenotwrittentotheMaplesymbolthatwaspassed.Thiscanbeusedbothtoprotecttheobjectspassed(seethefollowingArrayOptionssection),andtoreduceoverhead(asnotranslationbacktoMapledatastructuresneedbemade).RETURN_ONLYThisoptionspecißesthatnodataisactuallypassedtotheexternalfunction.Instead,onlyareferencetotheallocatedspaceispassed,andtheexternalfunctionisexpectedtoßllthespacewithdata.TheresultisconvertedintoanappropriateMapleobject.ArrayOptionsIfanARRAYargumentisdeclaredasCALL_ONLYandanArray,Matrix,orVectorwithpropersettingsispassedtotheexternalfunction(sothatno 6.2ExternalCalling:UsingCompiledCodeinMaple¯341copyingisrequired),CALL_ONLYhasnoeÞectandthusdoesnotpreventthecalledfunctionfromoverwritingtheoriginalarray.Topreventthisfromoccurring,includetheoptionCOPYintheARRAYdescriptor.TheARRAYdescriptoracceptsextraoptionswhenusedwithwrappergeneration.Theseoptionscanbespecißedasfollows.ARRAY(dim1,...,dimN,datatype=typename,order=...,...,options)Thedim1throughdimNparametersareintegerranges,specifyingtherangeofeachdimensionofthearray.Anyoftheupperorlowerboundsmaybethenameofanotherargument,inwhichcasethevalueofthatargumentspecißesthecorrespondingarrayboundatruntime.Theoptionsareusedtospecifyhowanarrayispassed.Thefollowingarevalidoptions.COPYDonotoperatein-placeonthegivenarray.Thatis,makeacopyßrst,andusethecopyforpassingtoandfromtheexternalfunction.NO_COPYThisensuresthatacopyofthedataisnevermade.Usually,whenusingawrappergeneratedexternalcall,iftheArray,Matrix,orVectorisofthewrongtype,(saytheorderiswrong),acopyismadewiththecorrectpropertiesbeforepassingittotheexternalfunction.UsingNO_COPYpreventsthis.Also,thereturnedarrayhastheprop-ertiesofthecopy.IfNO_COPYisspecißed,andanArray,Matrix,orVectorwithincorrectoptionsispassed,anexceptionisraised.Ar-raysarealwayspassedbyreference.Ifnooptionsaregiven(viaaREFdescriptor),theyarepassedbyusingtheCALL_ONLYbehaviorofREFwiththenotedexceptiondescribedatthebeginningofthissection.Non-passedArgumentsSometimesitisnecessarytopassadditionalargumentstotheMaplewrap-perthatshouldnotbepassedontotheexternalfunction.Forexample,considerthefollowinghypotheticalCfunction:intsum(int*v1,int*v2)Thisfunctiontakestwointegervectors,v1andv2,andaddstheel-ementsofv2tov1,stoppingwhenitßndsanentrythatiszero.Thegeneratedwrappercanbemadetoverifywhetherthevectorsarethesamesize.TheMapledeßnitionforthisfunctionisasfollows. 342¯Chapter6:AdvancedConnectivity>Sum:=define_external(`sum`,>v1::ARRAY(1..size,integer[4]),>v2::ARRAY(1..size,integer[4]),>size::NO_PASS(integer[4]),>RETURN::integer[4],>LIB="libsum.dll");TheNO_PASSmodißerspecißesthatthesizeargumentshouldnotbepassedtotheexternalfunction.TheSumfunctionisthencalledbythefollowingstatement,>Sum(v1,v2,op(1,v1));wherev1andv2arevectors.Maplepassesthevectordata,oracopyofthevectordata,totheexternalsumfunction.Itdoesnotpassthesizeelementtotheexternalfunction,butsizeisusedforargumentchecking(becausetheNO_CHECKoptionwasnotspecißed).Notethatthisoptioncanonlybeusedfortop-levelarguments.Thatis,itisinvalidtodeclareacallbackprocedure'sargumentsasNO_PASS.ArgumentCheckingandEáciencyConsiderationsItisintendedthatthetimeandspacecostsofcallinganexternalfunctionnotbeanyhigherthanthecostsforcallinganequivalentbuilt-infunctionwiththesamedegreeofargumenttypechecking.TheamountoftypecheckingdonebyageneratedMaplelanguagewrapperexceedsthatdonebymostinternalfunctions,sothereissomeadditionaloverhead.Thedefine_externalfunctionhasanoptionNO_CHECKwhich,ifused,disablesthetypecheckingdonebytheMaple-languagewrapper.Forfrequentlycalledexternalfunctionsthatperformsimpleoperationsthiscansignißcantlyimproveperformance.However,thereisariskasso-ciatedwithusingtheNO_CHECKoption.Ifyoupassanobjectofthewrongtype,thegeneratedC-languagewrappermightmisinterpretwhatithasreceived,resultinginerroneoustranslationstoexternaltypes,andhenceunpredictablebehavioroftheexternalfunction.ConversionsWhentheprocedurereturnedbydefine_externaliscalled,theMapleargumentsthatarepassedareconvertedtothecorrespondingargumentsoftheexternalfunction.Likewise,thevaluereturnedfromtheexternalfunctionisconvertedtothecorrespondingMapletype.ThefollowingtabledescribestheexternaltypesandtheMapletypesthatcanbeconverted.TheßrstlistedMapletypeistheonetowhicharesultofthecorrespondingexternaltypeisconvertedinto. 6.2ExternalCalling:UsingCompiledCodeinMaple¯343ExternalTypeAllowedMapleType(s)boolean[n]booleaninteger[n]integerfloat[n]float,rational,integer,numericcomplex[n]complex,numeric,float,rational,integerchar[n]one-characterstringstring[n]string,symbol,0ARRAY()Array,Vector,Matrix,name,0STRUCT()list,tableUNION()tablePROC()procedureForSTRUCTs,eitherlistsortablesarevalidforaparticulardeclaration.Oncedeclared,onlyoneofthetypes(alistoratable)isacceptable.Theycannotbeusedinterchangeablyunlessthewrapperisregenerated.ForUNIONs,onlytablesarepermitted,andthetablemustcontainexactlyoneentrywhenpassed(correspondingtooneofthemembersoftheunion).Ifanargumentofanincompatibletypeispassed,anerroroccurs,andtheexternalfunctionisnotcalled.Likewise,ifavalueispassedthatisoutofrangeforthespecißedtype(forexample,integertoolarge),anerroroccurs.Whenpassingàoating-pointvalues,precisioninexcessofthatsupportedbytheexternaltypeisdiscarded,providedthemagnitudeofthevalueiswithintherangeoftheexternaltype.ArgumentsthatweredeclaredasREFerences,thatis,passedby-reference,canbepassedeitheraname,azero,orthedeclaredkindofMapleexpression.¯Ifanameispassed,itisevaluated,andthevalueispassedbyrefer-encetotheexternalfunction.Aftertheexternalfunctionreturns,therevisedvalueisconvertedbacktothetypespecißedfortheargumentandassignedbacktothename.¯Ifthenamepassedhasnovalue,theneitherNULLispassed,orapointertonewlyallocatedspaceforthestructureispassed.Thisbe-haviorisdeterminedbythepresenceorabsenceofALLOCintheREFdeclaration.¯Ifazeroispassed,NULLispassedtotheexternalfunction.¯IfanyotherMapleexpressionispassed,itsvalueispassedbyrefer-ence,andtherevisedvalueisdiscarded. 344¯Chapter6:AdvancedConnectivityCompilerOptionsTocompilethewrapperlibrary,MaplerequirestheuseofaCcompilerinstalledonthesamemachinethatisrunningMaple.Maplegeneratesasystemcommandtocallthecompiler.Thecompilermustberecog-nizedbythesystem.ItshouldbeinthesystemPATHandallassociatedenvironmentvariablesmustbeset.Thecompileandlinkcommandsarecompletelycustomizableprovidedthatyourcompilerhasacommand-lineinterface.Defaultconßgurationsareprovided,whichshouldmakemostcasesworkÕoutofthebox.ÔMapleispreprogrammedtousethevendor-suppliedCcompilertocompilewrap-personmostplatforms.1Alldefaultcompileandlinkoptionsarestoredinamodulethatcanbeobtainedbyusingthecommanddefine_external(`COMPILE_OPTIONS`).Whenthemodulereturnedbythiscommandismodißed,themodißca-tionaÞectsallwrappergenerationcommandsviadefine_externalfortheremainderofthesession.Anyofthenamesexportedbythecompileoptionsmodulecanalsobespecißedasaparametertodefine_external.Whenspecißedasaparameter,theeÞectlastsonlyforthedurationofthatcall.ThecompileandlinkcommandsareassembledbycallingtheCOMPILE_COMMANDandLINK_COMMANDproceduresdeßnedinthecompileoptionsmodule.Theseproceduresmakeuseofthedeßnitionsinthecom-pileoptionsmoduletoformulateacommandstringthatisexecutedusingssystem.2Tocustomizethecompileandlinkcommands,youcanmodifythefollowingoptions.AlloptionvaluesmustbestringsorNULL,exceptforCOMPILE_COMMANDandLINK_COMMAND,whichmustbeproceduresorNULL.COMPILERThisspecißesthenameofthecompilerexecutable.CFLAGSThisspecißesmiscellaneousàagspassedtothecompiler.COMPILE_ONLY_FLAGThisàagindicatesthattheßleisonlytobecompiled.OnmostplatformsitisÕ-cÔ,whichcausesthecompilertogenerateanobjectßle,butnotlinkittoformanyexecutableorlibrary.Aseparatecommandperformsthelinking.1InMicrosoftWindows,MapleusestheMicrosoftVisualCCompiler.2IfusingtheMicrosoftCcompiler,theLINK_COMMANDissettoNULLbecausetheCOMPILE_COMMANDdoesboththecompilingandlinking. 6.2ExternalCalling:UsingCompiledCodeinMaple¯345COBJ_FLAGThisistheàagusedbythecompilertospecifytheob-jectßlename.ThecompilercommandusesCOBJ_FLAG||FILE||OBJ_EXTtonametheobjectßle.OnmostplatformsitisÕ-oÔ.LOBJ_FLAGThisistheàagusedbythelinkertospecifythetar-getlibraryname.ThelinkcommandusesLOBJ_FLAG||FILE||DLL_EXTtonamethesharedlibrary.FILEThisisthebasenameoftheßletobecompiled.Theßleextensionmustnotbeincludedinthisname.Forexample,tocompileÕfoo.cÔ,setFILE="foo"andFILE_EXT=".c".WhenFILEissettoNULLthesystemgeneratesaßlenamebasedonthefunctionname.FILE_EXTThisistheprogramßleextension.IfyouwanttocompileÕfoo.cÔ,setFILE_EXT=".c",andFILE="foo".OBJ_EXTThisistheobjectßleextension.CommonextensionsareÕ.oÔandÕ.objÔ.DLL_EXTThisisthedynamiclibraryextension.CommonextensionsareÕ.dllÔandÕ.soÔ.INC_FLAGThisprecedesdirectoriesintheINC_PATH.Onmostplat-formsitisÕ-IÔ.INC_PATHThisspecißesthedirectoriestosearchforheaderßles.Useanexpressionsequencetospecifymorethanonedirectory,forexample,INC_PATH=("/usr/local/maple/extern/include","/users/jdoe/include").COMPILE_COMMANDThisissettotheprocedurethatgeneratesthecompilercommand.Theproceduremustreturnastring.Ingen-eral,itisnotnecessarytochangethedefault.LINKERThisspecißesthenameofthelinkerexecutable.LINK_FLAGSThisspecißesmiscellaneousàagspassedtothelinker,includingthosethatcausethelinkertobuildadynamic(shared)library.LIB_FLAGThisprecedesdirectoriesintheLIB_PATH.Onmostplat-formsitisÕ-LÔ.LIB_PATHThisspecißesthedirectoriestosearchforlibraries.Useanexpressionsequencetospecifymorethanonedirectory,forexample,LIB_PATH=("/usr/local/maple/extern/lib","/users/jdoe/lib"). 346¯Chapter6:AdvancedConnectivityLIBThisnamesthelibrarywhichcontainstheexternalfunctiontocall.Thisoptionmustbespecißedineverycalltodefine_external.LIBSThisspecißesotherlibrariesthatneedtobelinkedwiththewrap-perlibrarytoresolveallexternalsymbols.Useanexpressionsequencetospecifymorethanonelibrary,forexample,LIBS=("/usr/local/maple/extern/lib/libtest.so","/users/jdoe/libdoe.so").SYS_LIBSThisspecißessystemlibrariestolinkwiththewrapperli-brarytoresolveallexternalsymbols.Useanexpressionsequencetospecifymorethanonelibrary,forexample,LIBS=("-lc","-lm").EXPORT_FLAGThisàagisusedincombinationwiththeFUNCTIONoptiontonamethefunctiontobeexportedfromthesharedlibrary.ThisisunassignedorsettoNULLonplatformsthatexportallsymbolsbydefault.FUNCTIONThisisthenameoftheexternalfunctiondeßnedinthewrapperlibrary.ThesystemgeneratesaFUNCTIONnameifthisisleftunassignedorsettoNULL.LINK_COMMANDThisissettotheprocedurethatgeneratesthelinkercommand.Theproceduremustreturnastring.SetthistoNULLifthecompilecommandalsodoesthelinking.Acommonuseoftheseoptionsasparameterstodefine_externalwithastandardcompilerwouldbetospecifytheßlename.Forexample,thefollowinggeneratesawrapperßlenamedÕfoo.cÔ.>f:=define_external(`myfunc`,`WRAPPER`,`FILE`="foo",`LIB`=>"mylib.dll"):Touseanon-standardcompilerortoaltercompileàags,assigndi-rectlytothecompileoptionsmodule.ExampleThefollowingexampleshowshowtosetuptheGNUcompileronamachinerunningSolaris.>p:=define_external(`COMPILE_OPTIONS`):>p:-COMPILER:="gcc";>p:-COBJ_FLAG:="-o":>define_external(`mat_mult`,`WRAPPER`,`LIB`="libcexttest.so"):Thegccrequiresaspacebetween-oandtheobjectname.ModifyingtheCOBJ_FLAGallowsthistobeeasilydone.Allotheroptiondefaultvaluesareacceptable. 6.2ExternalCalling:UsingCompiledCodeinMaple¯347Toviewtheexecutedcommands,settheinfolevelfordefine_externalto3orhigher.Repeatingthepreviousexampleyoumightseethefollow-ing.>p:=define_external(`COMPILE_OPTIONS`):>p:-COMPILER:="gcc";>p:-COBJ_FLAG:="-o":>infolevel[define_external]:=3:>define_external(`mat_mult`,`WRAPPER`,`LIB`="libcexttest.so"):"COMPILE_COMMAND""gcc-g-c-I/user/local/maple/extern/include-omwrap_mat_mult.omwrap_mat_mult.c""LINK_COMMAND""ld-znodefs-G-dy-Bdynamic-L/user/local/maple/bin/bin.SUN_SPARC_SOLARIS-omwrap_mat_mult.somwrap_mat_mult.o-lc-lmaplec"Anotherwaytoviewthecompileandlinkcommandsistocallthecommand-builderproceduresdirectly.Ensuretosetorunassignthevari-ablesthatwillbeassigned,otherwisetheyareblank.>p:=define_external(`COMPILE_OPTIONS`):>p:-COMPILER:="gcc";>p:-COBJ_FLAG:="-o":>p:-COMPILE_COMMAND();"gcc-g-c-I/u/maple/extern/include-o.o.c">unassign('p:-FILE');>p:-COMPILE_COMMAND();"gcc-g-c-I/u/maple/extern/include-oFILE.oFILE.c"ExampleThefollowingexampleshowstwocallstodefine_externalseparatedbytherestartcommand.TheßrstcalldoesnotusetheWRAPLIBoptionandthusgeneratesquad.candcompilesthewrapperlibraryquad.dll.ThesecondcallusestheWRAPLIBoptiontoreusetheexistingquad.dll.Nocompilationorwrappergenerationisdoneinthesecondcall. 348¯Chapter6:AdvancedConnectivity>quadruple_it:=define_external('quadruple_it',>WRAPPER,FILE="quad",>x::float[4],>RETURN::float[4],>LIB="test.dll"):>quadruple_it(2.2);8.80000019073486328>restart;>quadruple_it:=define_external('quadruple_it',>WRAPPER,FILE="quad",>x::float[4],>RETURN::float[4],>WRAPLIB="quad.dll",>LIB="test.dll"):>quadruple_it(2.2);8.80000019073486328WhenDLLsarecreatedandcompiledatruntimeitisimportantnottoduplicatethenameofapreviouslygeneratedDLLwithoutrestartingMaple(eitherbyexitingMapleorissuingtherestartcommand).MaplemaintainsanopenconnectionwiththeßrstDLLopenedwithanygivenname.AttemptingtocreateanewDLLofthesamenamewithoutrestart-ingcanleadtounexpectedresults.TheMaplecommanddlclosecanbeusedtoavoidrestarting,butsubsequentlycallinganyexternalfunctioninthatclosedDLLwithoutreissuingthedefine_externalcommandwilllikelycrashMaple.EvaluationRulesExternalfunctionsfollownormalMapleevaluationrulesinthatthear-gumentsareevaluatedduringafunctioncall.Itthereforemaybenec-essarytoencloseassignednamesinrightsinglequoteswhenpassing-by-reference.Forexample,considerthefollowingfunctionthatmultipliesanumberbytwoin-place.voiddouble_it(int*i){if(i==NULL)return;*i*=2;}InMaple,thewrapperlessdeßnitionofthisfunctionmightappearasfollows. 6.2ExternalCalling:UsingCompiledCodeinMaple¯349>double_it:=define_external('double_it',i::REF(integer[4]),>LIB="libtest.dll");Whenexecutingthisfunction,theargument'i'isconvertedfromtheMapleinternalrepresentationofanintegertoa4-bytehardwareinteger.Apointertothehardwareintegeristhenpassedtotheexternalfunction,'double_it'.Though'i'isdeclaredasapointertoaninteger,itisacceptabletocall'double_it'withnon-pointerinput.>double_it(3);Inthiscase,apointertothehardwareinteger3issentto'double_it'.ThemodißedvalueisnotaccessiblefromMaple.Toaccessthemodißedvalue,theparametermustbenamed.Thenamemustbeenclosedinrightsinglequotestopreventevaluation.>n:=3;>double_it(n);#nisevaluatedfirst,so3ispassed>n;3>double_it('n');#useunevaluationquotestopass'n'>n;6Fornumericdata,thestring"NULL"canbepassedasaparametertorepresenttheaddress0(theCNULL).Forstrings,because"NULL"isavalidstring,theinteger0representsaddress0.>double_it("NULL");>>concat:=define_external('concat',>RETURN::string,a::string,b::string,>LIB="libtest.dll"):>concat("NULL","x");"NULLx" 350¯Chapter6:AdvancedConnectivity>concat(0,0);0Intheconcatexample,theCcodemightlooklikethefollowing.Notethatthisfunctiondoesnotcleanmemoryasitshould.char*concat(char*a,char*b){char*r;if(!a||!b)return(NULL);r=(char*)malloc((strlen(a)+strlen(b)+1)*sizeof(char));strcpy(r,a);strcat(r,b);return(r);}Method3:CustomizingWrappersForcompletecontroloverdataconversions,Mapleallowsmodißcationofexistingwrappersandcreationofcustomwrappers.TherearenumerousCandFortranfunctionsavailablefortranslatingandmanipulatingMapledatastructures.Tousethismethod,youmustbefamiliarwiththestepsrequiredtousecompiledcodeinMaple,describedinMethod1:CallingExternalFunctionsonpage332.Forthismethod,youdonotdeclareafunc-tionspecißcationbecauseMaplepassesonedatastructurecontainingallthepassedinformation.Therefore,thereareonlytwobasicsteps(DLLcreationandfunctioninvocationasdescribedonpages332-333)inad-ditiontowrappergeneration.WrapperswereintroducedinMethod2:GeneratingWrappersonpage338.ExternalFunctionEntryPointMapleßndsthesymbolnamegivenastheßrstargumenttodefine_externalintheDLLspecißedintheLIB=argument.MaplealsoßndstheMWRAP_symbolNameinthewrapperlibrary.ThisMWRAP_symbolNamefunc-tionprototypehasthefollowingformat.ALGEBMWRAP_quadruple_it( 6.2ExternalCalling:UsingCompiledCodeinMaple¯351MKernelVectorkv,FLOAT32(*fn)(FLOAT32a1),ALGEBfn_args);Thisprototypeistakenfromthewrapperquad.cdescribedintheprevioussection.TheßrstargumentkvisahandletotheMaplekernelfunctionvector.ThesecondargumentfnisafunctionpointerassignedthesymbolfoundintheexternalDLL.Inthiscase,fnisassignedthequadruple_itexternalfunction.ThelastargumentisaMapleexpres-sionsequencedatastructurecontainingalltheargumentspassedtothefunctionduringanygivencalltotheMapleproceduregeneratedbythedefine_externalcommand.Theentrypointistheformatusedwhenwrappersareautomaticallygenerated,andwhenWRAPLIBisspecißed.AnalternateexternalentrypointthatexcludesthefunctionpointerisavailablewhentheparameterMAPLEisspecißedinsteadofWRAPPERorWRAPLIB.ALGEBMWRAP_quadruple_it(MKernelVectorkv,ALGEBfn_args);TheAPIfunctionprototypesformanipulatingMapledatastructuresarein$MAPLE/extern/includewhere$MAPLEisthepathoftheMapleinstallation.Theheaderßlemaplec.hshouldbeincludedwhenwrit-ingcustomCwrappers.Oneoftheheaderßles,maplefortran.hformaplefortran64bit.hf,shouldbeincludedwhenwritingcustomFor-tranwrappers.Otherheaderßles,mplshlib.h,andmpltable.hcontainmacros,types,anddatastructuresthatareneededfordirectmanipula-tionofMapledatastructures.Mapleusesdirectedacyclicgraphs(dags)torepresentallobjects,suchasintegers,àoatingpointnumbers,sums,modules,orprocedures.(FormoreinformationaboutMapleinternalrepresentationofobjects,seeAppendixA.)ThesedagshavethetypeALGEBinCwrappers,andINTEGERorINTEGER*8inFortranwrappers.Fortran77hasnousertypedeßnitionsemanticssoALGEBpointersmustbeÕfakedÔbyusingma-chineword-sizedintegers.Ifthemachinewordsizeis64-bit(forexample,asonaDECAlpha),theheadermaplefortran64bit.hfmustbeusedandINTEGER*8mustbeusedasthedagdatatype.ExecutetheMaplecommandkernelopts(wordsize)todeterminewhetheryouneedtouse32-bitor64-bitinteger-dagtypesinFortran.WhenworkingwithC,thedatatypeisALGEBregardlessofthemachinewordsize. 352¯Chapter6:AdvancedConnectivityYoudonothavetoknowtheinternaldetailsofdagstomanipulateandusethem.Theonlyexceptionistheargumentsequencepassedtothewrapperentrypoint.Thisisanexpressionseqence(EXPSEQ)dag,andcanbetreatedasanarrayofdagsstartingatindex1(not0).Thus,fn_args[1]istheßrstparameterpassedtotheexternalfunction.UseMapleNumArgstodeterminethenumberofargumentspassed.NotethattheFortranAPIusesaslightlydiÞerentnamingconvention.Theequiva-lentFortrancallismaple_num_args.TheCAPInamesareusedfortheremainderofthischapter.ToßndequivalentFortrannames,refertotheAPIlisting.InspectingAutomaticallyGeneratedWrappersTheeasiestwaytostartwritingcustomwrappersistoinspectauto-maticallygeneratedwrappers.Considertheaddfunctionthatwasintro-ducedatthebeginningofthischapter.UsetheWRAPPERoptiontotelldefine_externaltogenerateawrapper.AlsousetheNO_COMPILEop-tionwithdefine_externalsoasnottocompilethegeneratedwrapper.Thenameofthegeneratedßleisreturned.>myAdd:=define_external(>'add',>'WRAPPER',>'NO_COMPILE',>'num1'::integer[4],>'num2'::integer[4],>'RETURN'::integer[4]>);myAdd:="mwrap_add.c"Theßlemwrap_add.cresemblesthefollowing./*MWRAP_addWrapperGeneratedautomaticallybyMapleDonoteditthisfile.*/#include#include#include#include#includeMKernelVectormapleKernelVec;typedefvoid*MaplePointer; 6.2ExternalCalling:UsingCompiledCodeinMaple¯353ALGEB*args;/*main-MWRAP_add*/ALGEBMWRAP_add(MKernelVectorkv,INTEGER32(*fn)(INTEGER32a1,INTEGER32a2),ALGEBfn_args){INTEGER32a1;INTEGER32a2;INTEGER32r;ALGEBmr;inti;mapleKernelVec=kv;args=(ALGEB*)fn_args;if(MapleNumArgs(mapleKernelVec,(ALGEB)args)!=2)MapleRaiseError(mapleKernelVec,"Incorrectnumberofarguments");/*integer[4]*/a1=MapleToInteger32(mapleKernelVec,args[1]);/*integer[4]*/a2=MapleToInteger32(mapleKernelVec,args[2]);r=(*fn)(a1,a2);mr=ToMapleInteger(mapleKernelVec,(long)r);return(mr);}Thegeneratedwrapperisagoodstartingpointforcreatingwrappers.Theremaybesomeextravariablesanddeclarationsusedbecausethewrappergenerationisgeneric.Forexample,theuseofargsratherthanfn_argsavoidstheneedforacastwithargs[1],butitalsoisastaticglobalwhichisusefulwhenworkingwithcallbacksthatneedaccesstotheargumentsequenceoutsidethemainentrypoint.Rememberthattheaddfunctionsimplyaddedtheargumentsa1anda2andreturnedtheresult.Thiscanbedonedirectlyinthewrapper.ByremovingthesecondargumentfnsotheMAPLEoptioncanbeused,plusinliningthea1+a2functionalityandcleaningupthecode,thewrapperresemblesthefollowing. 354¯Chapter6:AdvancedConnectivity/*ProgramtoaddtwonumbersfromMaple*/#include#include#include/*mainentrypoint-MWRAP_add*/ALGEBmyAdd(MKernelVectorkv,ALGEBfn_args){INTEGER32a1;/*INTEGER32=>int(definedin*//*mpltable.h)*/INTEGER32a2;INTEGER32r;if(MapleNumArgs(kv,fn_args)!=2)MapleRaiseError(kv,"Incorrectnumberofarguments");/*convertfromMapleintegertoCint*/a1=MapleToInteger32(kv,((ALGEB*)fn_args)[1]);/*convertfromMapleintegertoCint*/a2=MapleToInteger32(kv,((ALGEB*)fn_args)[2]);r=a1+a2;return(ToMapleInteger(kv,(long)r));}ThisprogramßrstverißesiftheMaplefunctioncallpassedexactlytwoarguments.Itthenconvertsthetwoargumentstohardwareintegersandaddsthem.TheresultisconvertedtoaMapleintegerandreturned.ThisprogramcanbecompiledintoaDLLusingyourfavoriteCcom-piler.EnsurethatyoulinkwiththeMapleAPIsharedlibrary.TheDLLcanbeplacedintotheMaplebin.$SYSTEMdirectory,orsomewhereelseinthePATH.WhenusingDLLsoutsideofbin.$SYSTEMdirectory,youmayneedtospecifythefullpathtotheDLLintheLIBargumenttodefine_external.UNIXdevelopersmayneedtosettheirload-library-path.Table6.5onpage395liststheMapleAPILibrariesforCandFortran.AftercompilingtheDLL,thefunctioncanbeusedinMaple.Notypedesciptorsareneededinthedefine_externalcallbecauseMapledoes 6.2ExternalCalling:UsingCompiledCodeinMaple¯355noconversiononargumentspassedtothecustomwrapper.>myAdd:=define_external('myAdd','MAPLE','LIB'=>"myAdd.dll"):>myAdd(2,3);5>myAdd(2.2,1);Error,(inmyAdd)integerexpectedforinteger[4]parameter>myAdd(2^80,2^70);Error,(inmyAdd)integertoolargeincontextTheequivalentFortranwrapperwouldlooklikethefollowing.ProgramtoaddtwonumbersfromMapleINTEGERFUNCTIONmyAdd(kv,args)INCLUDE"maplefortran.hf"INTEGERkvINTEGERargsINTEGERargINTEGERa1,a2,rCHARACTERERRMSG*20INTEGERERRMSGLENERRMSGLEN=20IF(maple_num_args(kv,args).NE.2)THENERRMSG='Incorrectnumberofarguments'CALLmaple_raise_error(kv,ERRMSG,ERRMSGLEN)myAdd=to_maple_null(kv)RETURNENDIF 356¯Chapter6:AdvancedConnectivityarg=maple_extract_arg(kv,args,1)a1=maple_to_integer32(kv,arg)arg=maple_extract_arg(kv,args,2)a2=maple_to_integer32(kv,arg)r=a1+a2myAdd=to_maple_integer(kv,r)ENDOncecompiledintoaDLL,thesamesyntaxcanbeusedinMapletoaccessthefunction.TheonlydiÞerenceistheadditionalkeyword'FORTRAN'inthedefine_externalcall.>myAdd:=define_external('myAdd','MAPLE','FORTRAN','LIB'=>"myAdd.dll"):>myAdd(2,3);5ExternalAPIAnexternalAPIisprovidedforuserswhowanttoaugmentexistingwrappersorwritetheirowncustomwrappers.ThissectiondescribesthefunctionsavailablewhenlinkingwiththeMapleAPIlibrary(seeTable6.5onpage395)andincludingeithermaplec.hormaplefortran.hf.ArgumentCheckingThefollowingCfunctioncanbeusedtoquerythenumberofargumentscontainedintheargumentexpressionsequencepassedasthelastargumenttotheexternalfunctionentrypoint.Theexpressionsequencepassedtothisentrypointcanbequerieddirectly(forexample,((ALGEB*)expr)[1]).Ifn=MapleNumArgs(kv,expr),thelastargumentis((ALGEB*)expr[n].M_INTMapleNumArgs(MKernelVectorkv,ALGEBexpr);TheargumentspassedtotheFortranentrypointcannotbequerieddirectly.Themaple_extract_argfunctionmustbeusedtoaccesstheargumentdata(forexample,arg1=maple_extract_arg(kv,args,1)).Ifn=maple_num_args(kv,s),thenthelastargumentismaple_extract_arg(kv,args,n). 6.2ExternalCalling:UsingCompiledCodeinMaple¯357INTEGERmaple_num_args(kv,s)INTEGERmaple_extract_arg(kv,s,i)ThefollowingfunctionsindicatethetypeofthegivenMapleobject.M_BOOLIsMapleAssignedName(MKernelVectorkv,ALGEBs);M_BOOLIsMapleComplexNumeric(MKernelVectorkv,ALGEBs);M_BOOLIsMapleNumeric(MKernelVectorkv,ALGEBs);M_BOOLIsMapleInteger(MKernelVectorkv,ALGEBs);M_BOOLIsMapleInteger8(MKernelVectorkv,ALGEBs);M_BOOLIsMapleInteger16(MKernelVectorkv,ALGEBs);M_BOOLIsMapleInteger32(MKernelVectorkv,ALGEBs);M_BOOLIsMapleInteger64(MKernelVectorkv,ALGEBs);M_BOOLIsMapleName(MKernelVectorkv,ALGEBs);M_BOOLIsMapleNULL(MKernelVectorkv,ALGEBs);M_BOOLIsMaplePointer(MKernelVectorkv,ALGEBs);M_BOOLIsMaplePointerNULL(MKernelVectorkv,ALGEBs);M_BOOLIsMapleProcedure(MKernelVectorkv,ALGEBs);M_BOOLIsMapleRTable(MKernelVectorkv,ALGEBs);M_BOOLIsMapleString(MKernelVectorkv,ALGEBs);M_BOOLIsMapleTable(MKernelVectorkv,ALGEBs);M_BOOLIsMapleUnassignedName(MKernelVectorkv,ALGEBs);M_BOOLIsMapleUnnamedZero(MKernelVectorkv,ALGEBs);EquivalentFortranfunctionsareasfollows.TheCfunctions,IsMaplePointer,IsMaplePointerNULL,andIsMapleUnnamedZeroarenotavailableintheFortranAPI.INTEGERis_maple_assigned_name(kv,s)INTEGERis_maple_complex_numeric(kv,s)INTEGERis_maple_numeric(kv,s)INTEGERis_maple_integer(kv,s)INTEGERis_maple_integer8(kv,s)INTEGERis_maple_integer16(kv,s)INTEGERis_maple_integer32(kv,s)INTEGERis_maple_integer64(kv,s)INTEGERis_maple_name(kv,s)INTEGERis_maple_null(kv,s)INTEGERis_maple_procedure(kv,s)INTEGERis_maple_rtable(kv,s)INTEGERis_maple_string(kv,s)INTEGERis_maple_table(kv,s)INTEGERis_maple_unassigned_name(kv,s) 358¯Chapter6:AdvancedConnectivityThesefunctionsallreturnTRUE(1)whentheMapledagsßtsthede-scriptiongivenbythefunctionname.Ifsisnotofthecorrecttype,FALSE(0)isreturned.TheMapleNULLisnotthesameasaCPointer-NULL.TheformeristheemptyexpressionsequenceintheMaplelanguage.Thelatterisapointervariablesettotheaddresszero.SincethereisnoconceptofrealpointersintheMapleLanguage,theideaofPointer-NULLinthiscontextmeanstheMapleintegerzero,oranunassignedMaplename.TheIsMaple...NumericroutinesusetheMapletypenumericdeßnition.Allotherchecksusethedagtypedeßnition.Forexample,type(t[1],name)returnstrueinMaple,butIsMapleNamechecksforaNAMEdagandre-turnsFALSEbecauset[1]isinternallyrepresentedasaTABLEREFdag.IntegerqueryroutineswiththebitsizespecißedinthenamechecktoensurethegivenMapleobjectsisaMapleintegerandalsothatitcouldßtintothespecißednumberofbitsifconvertedtoahardwareinteger.ConversionsFromMapleObjectsThefollowingfunctionsreturnthespecißedtypewhengivenadagsthatcanbeconvertedtothattype.COMPLEXF32MapleToComplexFloat32(MKernelVectorkv,ALGEBs);COMPLEXF64MapleToComplexFloat64(MKernelVectorkv,ALGEBs);CXDAGMapleToComplexFloatDAG(MKernelVectorkv,ALGEBs);FLOAT32MapleToFloat32(MKernelVectorkv,ALGEBs);FLOAT64MapleToFloat64(MKernelVectorkv,ALGEBs);INTEGER8MapleToInteger8(MKernelVectorkv,ALGEBs);INTEGER16MapleToInteger16(MKernelVectorkv,ALGEBs);INTEGER32MapleToInteger32(MKernelVectorkv,ALGEBs);INTEGER64MapleToInteger64(MKernelVectorkv,ALGEBs);M_BOOLMapleToM_BOOL(MKernelVectorkv,ALGEBs);M_INTMapleToM_INT(MKernelVectorkv,ALGEBs);void*MapleToPointer(MKernelVectorkv,ALGEBs);char*MapleToString(MKernelVectorkv,ALGEBs);ThefollowingaretheequivalentFortranroutines.Notethatcomplexandstringconversionaredonebyreference.Thatis,thethirdargumentpassedtothefunctionissettotheconvertedvalueratherthanthefunc-tionreturningthevalue.EquivalentfunctionsforMapleToComplexFloatDAGandMapleToPointerarenotavailable.SUBROUTINEmaple_to_complex_float32(kv,s,c)SUBROUTINEmaple_to_complex_float64(kv,s,c)REALmaple_to_float32(kv,s)DOUBLEPRECISIONmaple_to_float64(kv,s) 6.2ExternalCalling:UsingCompiledCodeinMaple¯359INTEGERmaple_to_integer8(kv,s)INTEGERmaple_to_integer16(kv,s)INTEGERmaple_to_integer32(kv,s)INTEGER*8maple_to_integer64(kv,s)INTEGERmaple_to_m_bool(kv,s)INTEGERmaple_to_m_int(kv,s)INTEGERmaple_to_string(kv,s,string)FloatingPointnumbersmayloseprecisionduringtheconversiontohardwaresizedata.ConversionfromaSTRINGdagtoanintegerreturnstheASCIIvalueoftheßrstcharacterinthatstring.ConversionfromaMapleBooleantoanintegerreturns1fortrueor0forfalse.ConversionsfromaSTRINGdagtoastringshouldnotbemodißedin-place.Acopyshouldbemadeifanymodißcationsarenecessary.TheMapleToPointerconversionreturnsthepointervaluestoredinaMapleBINARYdag.ConversionsToMapleObjectsThefollowingfunctionsreturnadagofthespecißeddagtypewhengivenadagthecorrespondinghardwaredata.ALGEBToMapleBoolean(MKernelVectorkv,longb);ALGEBToMapleChar(MKernelVectorkv,longc);ALGEBToMapleComplex(MKernelVectorkv,doublere,doubleim);ALGEBToMapleComplexFloat(MKernelVectorkv,ALGEBre,ALGEBim);ALGEBToMapleExpressionSequence(MKernelVectorkv,intnargs,/*ALGEBarg1,ALGEBarg2,*/...);ALGEBToMapleInteger(MKernelVectorkv,longi);ALGEBToMapleInteger64(MKernelVectorkv,INTEGER64i);ALGEBToMapleFloat(MKernelVectorkv,doublef);ALGEBToMapleName(MKernelVectorkv,char*n,M_BOOLis_global);ALGEBToMapleNULL(MKernelVectorkv);ALGEBToMapleNULLPointer(MKernelVectorkv);ALGEBToMaplePointer(MKernelVectorkv,void*v,M_INTtype);ALGEBToMapleRelation(MKernelVectorkv,constchar*rel,ALGEBlhs,ALGEBrhs);ALGEBToMapleString(MKernelVectorkv,char*s); 360¯Chapter6:AdvancedConnectivityALGEBToMapleUneval(MKernelVectorkv,ALGEBs);TheequivalentFortranroutinesareasfollows.TheFortranAPIdoesnotsupportToMapleExpressionSequence,ToMapleNULLPointer,ToMaplePointer,ToMapleRelation,orToMapleUneval.to_maple_boolean(kv,b)to_maple_char(kv,c)to_maple_complex(kv,re,im)to_maple_complex_float(kv,re,im)to_maple_integer(kv,i)to_maple_integer64(kv,i)to_maple_float(kv,f)to_maple_name(kv,s,s_len)to_maple_null(kv)to_maple_string(kv,s,s_len)ToMapleBooleanisthreevalued.Whenbiszero,itreturnstheMaplefalsedag.Ifnis-1,theMapleFAILdagisreturned.Ifnisnon-zero(andnot-1),theMapletruedagisreturned.ToMapleCharreturnsasinglecharacterMaplestringdag.ToMapleComplexconvertsthepairofdoubles,reandim,totheMapleexpressionre+I*im,andreturnsthisdag.ToMapleComplexFloatconvertsapairofFLOATdagstotheMapleexpressionre+I*im,andreturnsthisdag.ToMapleExpressionSequencecreateandreturnsaMapleexpressionsequenceandßllsitwiththeNalgebraics,arg1,arg2,...,argN.ToMapleNamereturnsaMapleNAMEdagwiththenamen.Ifis_globalissettoTRUE,thenameisglobalintheMaplenamespace.Otherwise,ifis_globalisFALSE,thenameisauniqueexportedlocal.ToMapleNULLreturnstheMapleNULLdag(anemptyEXPSEQ).ToMapleNULLPointerreturnstheMaplezerodag.ThisisthewrapperrepresentationofaNULLpointerpassedtoaprocedure.DonotconfusethiswiththevaluereturnedbyToMapleNULL.ToMapleStringcopiesthecharacterstringstoaMapleSTRINGdagandreturnsit.WhenusingtheFortranAPI,thelengthofthegivenstringmustalsobepassed.RectangularTable(Vector,Matrix,Array)ManipulationRtables3arethecontainerclassofVector,Matrix,andArraydatastructuresinMaple.Thebasicaccessfunctionsareasfollows.3Forinformationonrtables,referto?rtable. 6.2ExternalCalling:UsingCompiledCodeinMaple¯361ALGEBRTableCreate(MKernelVectorkv,RTableSettings*s,void*pdata,M_INT*bounds);void*RTableDataBlock(MKernelVectorkv,ALGEBrt);M_INTRTableNumElements(MKernelVectorkv,ALGEBrt);M_INTRTableNumDimensions(MKernelVectorkv,ALGEBrt);M_INTRTableLowerBound(MKernelVectorkv,ALGEBrt,M_INTdim);M_INTRTableUpperBound(MKernelVectorkv,ALGEBrt,M_INTdim);M_BOOLRTableIsReal(MKernelVectorkv,ALGEBrt);TheFortranAPIcontainsthefollowingfunctions.SUBROUTINEcopy_to_array(kv,rt,a,num_rdims,rbounds,num_fdims,fbounds,data_type)SUBROUTINEcopy_to_rtable(kv,a,rt,num_fdims,fbounds,num_rdims,rbounds,data_type)INTEGERconvert_to_rtable(kv,a,num_rdims,rbounds,num_fdims,fbounds,data_type)INTEGERrtable_num_elements(kv,s)INTEGERrtable_num_dimensions(kv,s)INTEGERrtable_lower_bound(kv,s,dim)INTEGERrtable_upper_bound(kv,s,dim)INTEGERrtable_is_real(kv,s)RtableDataBlockreturnsapointertothedatablockofagivenrtable.Thereturnedvalueshouldbecastedtotheknowndatatypeofthertable.ThedatablockcanbemanipulateddirectlyinsteadofusingRtableAssignorRtableSelect.Userswhodirectlymanipulatethedatablockmustbeawareofthestoragetype,order,datatype,andpresenceofindexingfunctionstodothisproperly.InFortran,thereisnowaytoreturnanARRAYpointer.ToworkwithanarraycreatedinMaple,thedata-blockmustbecopiedtoapre-allocatedFortrandatablockusingthecopy_to_arrayfunction.ItcopiesthecontentsofthertablerttotheARRAY,a.Foracompleteexplanationoftheparametersthatarepassed,refertothemaplefortran.hfßle.TocopyanarraybacktoMaple,thecopy_to_rtablefunctioncanbeused.RtableCreatereturnsanewlycreatedRTABLEasspecißedby:1.ThedeßnitionsgivenintheRtableSettingsstructures.2.Apointertoanexistingblockofdata.IfpdataisNULL,adata-blockisallocatedandinitializedtos->fill.Whenprovidinganalready 362¯Chapter6:AdvancedConnectivitycreatedblockofdata,itisimportantthats->foreignissettoTRUE.Size,storage,datatype,order,andindexingfunctionsshouldallbeconsideredwhenmanagingyourdatablock.Generally,letMaplecre-atethedata-block,thenuseRtableDataBlocktogainaccesstoit.3.Theboundsarray,bounds.Anmxnmatrixmusthavebounds=1,m,1,n(thatis,boththeupperandlowerboundsmustbespecißed).TheFortranequivalentfunctionisconvert_to_rtable.ItcreatesanrtablefromanexistingFortranarray.Thedataisnotcopiedintothetable.Instead,thertablemaintainsapointertotheexternaldata.RtableNumElementsreturnsthenumberofelementsinagivenrtable.ThismaybediÞerentinsparseversusdensertables.1.Fordensertables,returnthenumberofelementsofstorageallocatedforthisrtable.2.IfrtisinNAG-sparseformat,thenthisreturnsthenumberofele-mentsinthedatavectorspecißedforthertable,(whichisthesameasthelengthofeachindexvector).Notethatthenumberreturnedhererepresentsthenumberofdataelementsthatareactuallyßlledin,notthenumberofelementsallocated.Someoftheelementsmayhavethevaluezero.3.ForMaple-sparsertables,thisalwaysreturnszero.RtableNumDimensionsreturnsthenumberofdimensionsinagivenrtable.RtableUpperBoundandRtableLowerBoundgivetheupperandlowerboundofthedimthdimensionoftheRTABLE,rt.Fora2x3matrix,RtableLowerBound(rt,1)returns1becausetheßrstdimensionboundsare1..2,andthelowerboundis1.RtableIsRealcheckstheelementsoftheRTABLErttoverifywhethertheyareallreal.Ifdatatype=complex,itreturnsFALSE.Ifdatatypeisahardwaretypewithnoindexingfunction,forexample,float[8],itreturnsTRUE.Otherwise,itscansthertableandreturnsFALSEwhentheßrstcomplexentryisfoundorTRUEifnocomplexentriesarefound.Inadditiontotheabovefunctions,thereisanextensiveCAPIforworkingwithrtabledatatypes.voidRTableAppendAttribute(MKernelVectorkv,RTableSettings*s,char*name);voidRTableAppendIndFn(MKernelVectorkv,RTableSettings 6.2ExternalCalling:UsingCompiledCodeinMaple¯363*s,ALGEBindfn);voidRTableGetDefaults(MKernelVectorkv,RTableSettings*s);voidRTableGetSettings(MKernelVectorkv,RTableSettings*s,ALGEBrt);M_INTRTableIndFn(MKernelVectorkv,ALGEBrt,M_INTnum);ALGEBRTableIndFnArgs(MKernelVectorkv,ALGEBrt,M_INTnum);voidRTableSetAttribute(MKernelVectorkv,RTableSettings*s,char*name);voidRTableSetIndFn(MKernelVectorkv,RTableSettings*s,ALGEBindfn);voidRTableSetType(MKernelVectorkv,RTableSettings*s,M_INTid,char*name);RTableDataRTableSelect(MKernelVectorkv,ALGEBrt,M_INT*index);RTableDataRTableAssign(MKernelVectorkv,ALGEBrt,M_INT*index,RTableDataval);voidRTableSparseCompact(MKernelVectorkv,ALGEBrt);NAG_INT*RTableSparseIndexRow(MKernelVectorkv,ALGEBrt,M_INTdim);ALGEBRTableSparseIndexSort(MKernelVectorkv,ALGEBrt,M_INTby_dim);voidRTableSparseSetNumElems(MKernelVectorkv,ALGEBrt,M_INTnum);M_INTRTableSparseSize(MKernelVectorkv,ALGEBrt);ALGEBRTableCopy(MKernelVectorkv,RTableSettings*s,ALGEBrt);ALGEBRTableCopyImPart(MKernelVectorkv,RTableSettings*s,ALGEBrt);ALGEBRTableCopyRealPart(MKernelVectorkv,RTableSettings*s,ALGEBrt);ALGEBRTableZipReIm(MKernelVectorkv,RTableSettings*s,ALGEBrt_re,ALGEBrt_im);MostRtableaccessfunctionsusetheRtableSettingsstructurede-ßnedinmpltable.h.Thisstructcorrespondsdirectlytotheoptionsavail-abletothertableconstructorinMaple.RtableAppendAttributeappendsthenameattributetothelistofattributesintheRtableSettingsstructure. 364¯Chapter6:AdvancedConnectivityRtableAppendIndFnappendstheindexingfunction,infntothelistofindexingfunctionsintheRtableSettingsstructure.NotethatinfnmustbeavalidMaplenameortablereference.Forexample,RTableAppendIndFn(kv,&settings,ToMapleName(kv,"symmetric",TRUE));RTableAppendIndFn(kv,&settings,EvalMapleStatement(kv,"triangular[upper]"));RtableGetDefaultsßllstheRtableSettingsstructureswithstan-darddefaultvalues.Thesedefaultsareasfollows.data_type=RTABLE_DAGmaple_type='anything'(Maplename'anything')subtype=RTABLE_ARRAYstorage=RTABLE_RECTp1=-1,p2=-1order=RTABLE_FORTRANread_only=FALSEforeign=FALSEnum_dimensions=-1index_functions='NULL'(MapleNULL)attributes='NULL'(MapleNULL)transpose=FALSEfill=0RtableGetSettingsßllstheRtableSettingsstructureswiththesettingsheldbytheRTABLE,rt.RtableIndFnreturnstheithindexingfunctioncode.Theindexingcodesaredeßnedinmpltable.hintheformRTABLE_INDEX_XXXX.Iftherearenoindexingfunctions,thisgivesanerrorforanyvalueofi.Ifthereisoneindexingfunction,thenrtableIndFun(rt,1)returnsthecodefortheonlyindexingfunction.UseMapleNumArgstodeterminethenumberofindexingfunctions.RtableIndFnArgsreturnstheargumentexpressionsequenceforin-dexingfunction'num'inrtable'rt'.Iftherearenoarguments,Maple'NULL'isreturned.TheresultcanbefurtherconvertedtoahardwaretypeusingtheMapleToXXXfunction(s).ThenumberofargumentsreturnedcanbedeterminedusingMapleNumArgs.Notethatsomeknowledgeabouttheindexingfunctionsisrequiredtoconvertthereturnvaluetotheap-propriatehardwaretype.Forexample,RTableIndFnArgs(kv,rt,1)ofaband[b1,b2]rtablereturnstheb1partoftheexpressionsequence 6.2ExternalCalling:UsingCompiledCodeinMaple¯365(b1,b2).Theusermustknowthatb1andb2arealwaysintegers.Conversely,cinconstant[c]isalwaysthesametypeasthertable'sdatatype.Thusforfloat[8]rtables,toconverttoahardwaretypeuseMapleToFloat64.RtableSetAttributesetsalltheattributesoftheRtableSettingsstructurestothesingleNAMEattribute,name.RtableSetIndFnsetsalltheindexingfunctionsoftheRtableSettingsstructuresandresetsittothesingleindexingfunctioninfn.RtableSetTypesetsthedata_typeßeldinthegivenRtableSettingsstructurestoid,andwhenid=RTABLE_DAG,setsthemaple_typetoname.Forexample,tosetthedatatypetofloat[8],RTableSetType(kv,&s,RTABLE_FLOAT,NULL)iscalled.Tosetthetypetonumeric,RTableSetType(kv,&s,RTABLE_DAG,"numeric")iscalled.Basictypeidsaredeßnedinmpltable.h.Tosetcompoundtypes,theRtableSettingsdatastructurecanbemanipulateddirectlyasfollows.settings.data_type=RTABLE_DAG;settings.maple_type=EvalMapleStatement(kv,"complex(numeric)");RtableSelectreturnsthevaluert[index],wherertisanRTABLE,andindexisanintegerarray.RtableAssignassignsthevaluevaltort[index].Thisfunctionmustbeusedinsteadofassigningdirectlytothertabledata-blockwheneverthegivenrtablehasanindexingfunctionorunusualstorageformat(forexample,sparse).Theindexisanintegerarray.Forexample,thefol-lowingcodeassignsthevalue3.14tothe[2,1]elementofthegivendatatype=float[8]rtable.RTableDataval;M_INT*index;index[0]=2;index[1]=1;val.float64=3.14;RTableAssign(kv,rt,index,val);RtableSparseCompactremovesanyzerosinthesparsertabledatablock.Thisshouldbecalledafteranexternalroutinethatmodißesthesparsedatablockdirectly.RtableSparseIndexRowreturnsthevectorofindicesfortheithdi-mensionofrt.ThertmustbeaNAGsparsertable. 366¯Chapter6:AdvancedConnectivityRtableSparseIndexSortsortstheNthindexvectorfortheNAGsparsertablert.Thisisdonein-place,andtheotherindexvectorsareadjustedaccordinglysothattheindex/valuemappingispreserved.RtableSparseSetNumElemssetsthenumberofnon-zeroentriesintheNAGsparsertablerttoN.Thisshouldbedoneonlyifthenumberofelementshaschanged.RtableSparseSizereturnsthenumberofentriesallocatedtostoredataintheNAGsparsertablert.ThisisnotnecessarilythesameasRtableNumElems.RtableCopyreturnsacopyofthertablertwithnewsettingsasgivenbytheRtableSettingsstructures.RtableCopyImPartreturnsacopyoftheimaginarypartofthertablertwithnewsettingsasgivenbytheRtableSettingsstructures.Thecopyreturnedispurelyreal,butcontainsonlytheimaginarypartsofthegivenrtable.RtableCopyRealPartreturnsacopyoftherealpartofthertablertwithnewsettingsasgivenbytheRtableSettingsstructures.RtableZipReImcombinestworealRTABLEs,rt_reandrt_im,intoacomplexrtableoftheformrt_re+I*rt_im.ThesettingsofthenewrtablethatisreturnedaredeterminedbytheRtableSettingsstructures.ListManipulationToworkwithMaplelists,thefollowingAPIfunctionscanbeused.ThesefunctionsareonlyavailableusingtheCAPI.ALGEBMapleListAlloc(MKernelVectorkv,M_INTnum_members);voidMapleListAssign(MKernelVectorkv,ALGEBlist,M_INTi,ALGEBval);ALGEBMapleListSelect(MKernelVectorkv,ALGEBlist,M_INTi);MapleListAlloccreatesaLISTdagwithspacefornum_membersele-ments.ThislistmustbeßlledbeforeitcanbepassedtoMaple.MapleListAssignsetstheithelementofthegivenlisttothevalueval.Thatis,list[i]:=val.MapleListSelectreturnstheithelementofthegivenlist.TableManipulationTouseMapletables,thefollowingAPIfunctionscanbeused.ThesefunctionsareonlyavailableusingtheCAPI.ALGEBMapleTableAlloc(MKernelVectorkv);voidMapleTableAssign(MKernelVectorkv,ALGEBtable,ALGEBind,ALGEBval); 6.2ExternalCalling:UsingCompiledCodeinMaple¯367ALGEBMapleTableSelect(MKernelVectorkv,ALGEBtable,ALGEBind);voidMapleTableDelete(MKernelVectorkv,ALGEBtable,ALGEBind);M_BOOLMapleTableHasEntry(MKernelVectorkv,ALGEBtable,ALGEBind);MapleTableAlloccreatesaTABLEdag.Thetableisinitiallyempty.MapleTableAssignsetstheindelementofthegiventabletothevalueval.Thatis,table[ind]:=val,whereindcanbeaNAMEoranexpressionsequenceofnumbers,oranyothervalidindexintoaMapletable.MapleTableSelectreturnstheindelementofthegiventable.MapleTableDeleteremovestheindelementfromthetable.MapleTableHasEntryqueriesthetabletodeterminewhetheritcon-tainsanelementatindexind.Ifitdoes,TRUEisreturned;otherwise,FALSEisreturned.DataSelectionThefollowingfunctionsareavailablewhenusingtheCAPIonlyanddealwithselectingfromvariouskindsofMapledatastructures.ALGEBMapleSelectImaginaryPart(MKernelVectorkv,ALGEBs);ALGEBMapleSelectRealPart(MKernelVectorkv,ALGEBs);ALGEBMapleSelectIndexed(MKernelVectorkv,ALGEBs,M_INTdim,M_INT*ind);MapleSelectImaginaryPartandMapleSelectRealPartreturntheimaginaryandrealpartsofacomplexnumberdag,respectively.MapleSelectIndexedreturnsavaluefromanyindexableobjectinMaple,suchaslist,array,orset.Theindexisspecißedbyßllingtheindarraywiththedesiredindex.Thesecondparameterdimisthenumberofdimensionsinthearrays(alsothenumberofelementsinind).Forexample,tolookupa[1,2,3],thefollowingcodecouldbeused(assumingarg1pointstothearraya).ALGEBval;M_INTind[3];ind[0]=1;ind[1]=2;ind[2]=3; 368¯Chapter6:AdvancedConnectivityval=k->selectIndexed(arg1,3,ind);UniqueDataThefollowingfunctionisavailableonlyintheCAPI.ALGEBMapleUnique(MKernelVectorkv,ALGEBs);ThisfunctionprocessesthegivenMapleexpressions,andreturnstheuniquecopyofthatexpressionfromtheMaplesimpltable.Forexample,ifyoucreatethenumbernum=one-billion,thenyoucom-putethenumberval=2*500-million.Anaddresscomparisonofnumandvaldoesnotindicateequality.Aftercallingsimplifyasinnum=MapleUnique(kv,num),bothnumandvalpointtothesamememory.ErrorHandlingThefollowingfunctionsraiseaMaplesoftware-styleer-rormessage.voidMapleRaiseError(MKernelVectorkv,char*msg);voidMapleRaiseError1(MKernelVectorkv,char*msg,ALGEBarg1);voidMapleRaiseError2(MKernelVectorkv,char*msg,ALGEBarg1,ALGEBarg2);TheFortranequivalentis:SUBROUTINEmaple_raise_error(kv,msg,len)Thesefunctionsdisplaythemessagemsg,stopexecution,andreturntotheMapleinputloop.AcalltoMapleRaiseErrordoesnotreturn.Thecharacterstringmsgcancontainwildcardsoftheform%N,whereNisanon-zerointeger.Thesewildcardsarereplacedbytheextraargument,arg1orarg2,beforedisplayingthemessage.If%-Nisspecißed,thentheoptionalargumentisdisplayedwithst,nd,rd,orthappendedtoit.Forexample:MapleRaiseError2(kv,"the%-1argument,'%2',isnotvalid",ToMapleInteger(i),args[i]);This,ifinvoked,raisestheerror,"the4thargument,'foo',isnotvalid",assumingi=4,andargs[i]issettotheMaplenamefoo.4Theonlyoptionnotallowedis%0becausethefunctioncannotdeter-minethenumberofunparsedoptionalarguments.TheCAPIalsoprovidesamechanismfortrappingerrorsraisedbyMaple.4Formoreinformation,referto?error. 6.2ExternalCalling:UsingCompiledCodeinMaple¯369void*MapleTrapError(MKernelVectorkv,void*(*proc)P((void*data)),void*data,M_BOOL*errorflag);MapleTrapErrorexecutestheCfunctionproc,passingitthedata,data.Ifanerroroccurs,errorflagissettoTRUEandtraperrorreturnsimmediately.Ifnoerroroccurs,theresultofproc(data)isreturnedanderrorflagisFALSE.Forexample,thefollowingcodeattemptstoexecuteaMapleproce-dure.Ifanerroroccurs,aseparatebranchofcodeistaken.typedefstruct{MKernelVectork;ALGEBfn,arg1,arg2;}CallbackArgs;void*tryCallback(void*data){/*callsthemapleprocedure'fn'witharguments'arg1'*//*and'arg2'*/return(void*)EvalMapleProc(((CallbackArgs*)data)->k,((CallbackArgs*)data)->fn,2,((CallbackArgs*)data)->arg1,((CallbackArgs*)data)->arg2);}voidMainProc(MKernelVectork,ALGEBfn){M_BOOLerrorflag;ALGEBresult;CallbackArgsa;a.k=k;a.fn=fn;a.arg1=ToMapleFloat(k,3.14);a.arg2=ToMapleInteger(k,44);result=(ALGEB)MapleTrapError(k,tryCallback,&a,&errorflag);if(errorflag){/*dosomething*/}else{ 370¯Chapter6:AdvancedConnectivity/*dosomethingelse*/}}HardwareFloatEvaluationThefollowingproceduresevaluateaMapleprocedureorstatementusinghardwareàoats.doubleMapleEvalhf(MKernelVectorkv,ALGEBs);doubleEvalhfMapleProc(MKernelVectorkv,ALGEBfn,intnargs,double*args);TheequivalentFortranfunctionsareasfollows.DOUBLEPRECISIONmaple_evalhf(kv,s)DOUBLEPRECISIONevalhf_maple_proc(kv,fn,nargs,args)MapleEvalhfappliesevalhftothegivendags.Thenevalhfeitherevaluatesanexpression,usinghardwareàoatstoproduceahardwareàoatresult,orreturnsthehandletoanevalhfablertablethatcanbeusedasaparametertoEvalhfMapleProc.EvalhfMapleProccallstheevalhfcomputationenginedirectlytoevaluatethegivenprocedurefnwithoutconvertingthehardwareàoatparameterstosoftwareàoats.TheprocedurefnisavalidMaplePROCdag,nargsisthenumberofparameterstopasstofn,andargsisthelistofparameters.Notethatargsstartsat1;args[1]istheßrstparameter,args[nargs]isthelast,andargs[0]isnotused.Settingupacallbackmayrequirestaticlocalvariablesinthewrappermodulesothatthecallbackhasaccesstothekernelvector(unlessitispassedviaadataparameterthatthecallbackreceives).ThefollowingisanexampleofawrapperthatusesEvalhfMapleProctoevaluateafunctionthattakesanhfarrayandsomenumericvalues.#include"maplec.h"staticMKernelVectorkv;/*kernelvector*/staticALGEBfn;/*functionhandle*/staticdoublehfparams[HF_MAX_PARAMS+1];/*parameters*/voidcallback(intN,doubleX,doubleY[]){hfparams[1]=(double)N;hfparams[2]=X;/*hfparams[3]isalreadyset*/ 6.2ExternalCalling:UsingCompiledCodeinMaple¯371EvalhfMapleProc(kv,fn,3,hfparams);}/*mainwrapperfunctioncalledfromMaple*/ALGEBtest(MKernelVectork,ALGEBargs){/*skipargcheckingforthesakeofbrevity*/kv=k;/*savekernelvector*//*getthehfarrayhandle*/hfparams[3]=MapleEvalhf(DAG(args[1]));fn=DAG(args[2]);/*savethefunctionhandle*/do_stuff(callback);/*starttheroutinethat*//*callscallback()*/return(k->toMapleNULL());}InMaple,theexternalroutineisaccessedlikeanyother,exceptanerrorisraisedifthegivenprocedureisnotabletouseevalhf.>f:=proc(n,x,y)y[1]:=n*sin(x);end:>y:=Vector([1,2],datatype=float[8]):>p:=define_external('test',MAPLE,LIB="libtest.so"):>p(y,f):GeneralEvaluationThefollowingproceduresevaluateMapleproce-duresorstatements.TheseroutinesarenotavailableintheFortranAPI.ALGEBMapleEval(MKernelVectorkv,ALGEBs);ALGEBEvalMapleProc(MKernelVectorkv,ALGEBfn,intnargs,/*ALGEBarg1,ALGEBarg2,*/...);ALGEBEvalMapleStatement(MKernelVectorkv,char*statement);EvalMapleProcisacallbacktoMaple.TheßrstargumentfnisaMaplePROCorFUNCTIONdag,whichisevaluatedwiththearguments,arg1..argN.Forexample,considerthefollowingMaplefunction.>f:=proc(x)x^2;end:Ifthisfunctionispassedtotheexternalfunctionasargs[1],thefollowingcodeexecutesthegivenfunctionatx:=3.14. 372¯Chapter6:AdvancedConnectivityALGEBa1,MapleResult;doubleCResult;a1=ToMapleFloat(kv,3.14);MapleResult=EvalMapleProc(kv,args[1],1,a1);CResult=MapleToFloat64(kv,MapleResult);EvalMapleStatementenablesyoutoenterasingleparsableMaplestatementandevaluateit.Forexample,thefollowingcallevaluatestheintegralofx3intherangex=0..1.ALGEBMapleResult;doubleCResult;MapleResult=EvalMapleStatement(kv,"int(x^3,x=0..1)");CResult=mapleToFloat64(kv,MapleResult);MapleEvalevaluatesaMapleexpression.Itisespeciallyusefulfordeterminingthevalueofanassignedname.AssignmenttoMapleVariablesThefollowingassignmentfunctionsareavailableonlywhenusingtheCAPI.ALGEBMapleAssign(MKernelVectorkv,ALGEBlhs,ALGEBrhs);ALGEBMapleAssignIndexed(MKernelVectorkv,ALGEBlhs,M_INTdim,M_INT*ind,ALGEBrhs);MapleAssignsetsthevaluedagrhstothenamedaglhs.ThisisequivalenttotheMaplestatement>lhs:=rhs;MapleAssignIndexedsetsthevaluerhstotheindexedvariablelhs.Thesecondparameterdimindicatesthenumberofdimensionsinthearray(or1iflhsisatable).Thethirdparameterindisahardwarearrayofindices.Forexample,tomaketheassignmenta[1][2][3]=3.14,thefol-lowingcodecouldbeused(assumingarg1pointstothearraya).ALGEBrhs;M_INTind[3];ind[0]=1;ind[1]=2; 6.2ExternalCalling:UsingCompiledCodeinMaple¯373ind[3]=3;rhs=ToMapleFloat(kv,3.14);MapleAssignIndexed(kv,arg1,3,ind,rhs);UserInformationTheMapleUserInfocommanddisplays"msg"wheninfolevel['name']issettolevel.ThiscommandisonlyavailableintheCAPI.voidMapleUserInfo(MKernelVectorkv,intlevel,char*name,char*msg);MemoryManagementThefollowingfunctionsareavailableonlywhenusingtheCAPI.void*MapleAlloc(MKernelVectorkv,M_INTnbytes);voidMapleDispose(MKernelVectorkv,ALGEBs);voidMapleGcAllow(MKernelVectorkv,ALGEBa);voidMapleGcProtect(MKernelVectorkv,ALGEBa);MapleAllocallocatesnbytesbytesofmemoryandreturnsapointertoit.GarbagecollectionofthismemoryishandledbyMaple.Notethattoallocatethismemory,anewBINARYdagstructureiscreated,andapointertothedatapartofthedagisreturned.Thefollowingcodesnapshotmightbeseeninawrapperthatconvertsanintegerreference(aname)inMapletoC.ALGEBarg1;INTEGER32*i;i=MapleAlloc(kv,sizeof(INTEGER32));*i=MapleToInteger32(kv,arg1);MapleDisposefreesthememoryallocatedtothestructures.ThisshouldonlybeusedondatastructurescreatedusingMapleAlloc,orthosethatwerecreatedexternallyandareguaranteednottobepointedtobyanyotherMaplestructure.TheMaplegarbagecollectorreclaimsanymemorynotpointedtobyanyotherdatastructure,sointypicalcasesitisnotnecessarytouseMapleDispose.MapleGcProtectpreventsthealgebraicafrombeingcollectedbytheMaplegarbagecollector.Thememorypointedto(bya)isnotfreeduntilMapleexits,oracalltoMapleGcAllowisissued.Anydagsthatmustpersistbetweenexternalfunctioninvocationsmustbeprotected.This 374¯Chapter6:AdvancedConnectivityincludesanyexternalglobalorstaticALGEBvariablesthatwillbereferredtoinalaterexternalcall.FailuretoprotectsuchapersistentvariableleadstounexpectedresultsiftheMaplegarbagecollectorremovesitbetweenfunctioncalls.MapleGcAllowallowsthealgebraicstructureatobecollectedbytheMaplegarbagecollector.Anyalgebraicstructurethatisnotreferencedbyanotheralgebraicstructureisautomaticallydestroyedanditsmemoryreclaimed.Algebraicsareprotectedfromgarbagecollectioniftheyareusedsomewhere(thatis,thevalueofaglobalnameorpartofanarray'sdata).Thenormalstateofanalgebraicistohavegarbagecollectionenabledonit.SystemIntegrityTheMaplekernelhasnocontroloverthequalityorreliabilityofexternalfunctions.Ifanexternalfunctionperformsanillegaloperation,suchasaccessingmemoryoutsideofitsaddressspace,thatoperationcanresultinasegmentationfaultorsystemerror.Theexternalroutinecrashes,causingMapletocrashtoo.IfanexternalroutineaccessesmemoryoutsideofitsaddressspacebutinsidetheMapleaddressspace,theexternalroutinewilllikelynotcrash,butMaplewillbecomecorrupted,resultingininexplicablebehaviororacrashlaterintheMaplesession.Similarly,anexternalroutinethatdealsdirectlywithMapledatastructurescancorruptMaplebymisusingthedatastructuremanipulationfacilities.Therefore,useexternalcallingatyourownrisk.Whetheranexternalroutineisonethatyouhavewritten,orisonesuppliedbyathirdpartytowhichyouhavedeclaredaninterface(viadefine_external),Maplemustrelyontheintegrityoftheexternalroutinewhenitiscalled.6.3OpenMaple:UsingMapleinCompiledCodeThissectiondescribestheApplicationProgrammingInterface(API)totheOpenMaplekernel.OpenMapleisasuiteoffunctionsthatallowsyoutoaccessMaplealgorithmsanddatastructuresinyourcompiledCorC++program.Torunyourapplication,Maple9mustbeinstalled.YoucandistributeyourapplicationtoanylicensedMaple9user.Theinformationinthisdocumentishardwareindependent.Unlessotherwisenoted,theinformationisalsooperatingsystemarchitectureindependent. 6.3OpenMaple:UsingMapleinCompiledCode¯375InterfaceOverviewTheprogramminginterface(API)isbuiltontheexistingexternalcall-ingmechanism.UsingOpenMapleprovidesdirectaccesstomanyoftheMapleinternaldatatypes.Thisissimilartotheaccessdefine_externalprovidestotheauthorofanexternalwrapper.Formoreinformationonexternalcalling,see6.2ExternalCalling:UsingCompiledCodeinMapleorreferto?external_callingand?CustomWrapper.OpenMapleprovidestheabilitytostarttheMaplekernelandcontroloutput.Bydefault,outputissenttostdout.Settingupcall-backfunctionsallowsyoutodirectoutputto,forexample,atextboxorastring.Formoreinformationoncall-backfunctions,seeCall-backFunctionsonpage380.DataTypesMapledeßnesafewlow-leveldatatypestoimproveporta-bilitybetweenarchitectures.SometypesareusedasparametersorreturnvaluesforOpenMapleAPIfunctions.M_INTAnintegerthatisthesamesizeasapointeronthearchitecture.Onmostarchitectures,forexample,Windows,thisisequivalenttoint.Onsomearchitectures,thisisequivalenttolongint.M_BOOLAnintegerthatcantakeoneoftwovalues,TRUEorFALSE.ThesizeofthistypeisthesameasM_INT.ALGEBAMapleexpressioninnativeinternalformat.Theformatisnotdocumented,butsomefunctions(suchasMapleEval)usesuchanexpressionforfurtherprocessingbyotherAPIfunctions.Thedatatypedeßnitionsareinmplshlib.handmpltable.h.INTEGER8,INTEGER16,INTEGER32,INTEGER64,FLOAT32,FLOAT64Thesemacrosaidindevelopingplatform-independentcode.Themacrore-solvestothecorrectbyte-sizedintegertyperecognizedbytheunder-lyingcompiler.AllAPIfunctionsaredeclaredwiththemodißerM_DECLandEXT_DECL.WhenusingMicrosoftVisualC/C++(MSVC),M_DECLisdeßnedus-ing#defineas__stdcallandEXT_DECLisdeßnedusing#defineas__declspec(dllimport)(tospecifycallingconventionsanddllsymbolexports).Forothercompilers,thesearedeßnedusing#defineasnoth-ing.WhennotusingMSVConWindows,ensurethatyoudeßnethemappropriately. 376¯Chapter6:AdvancedConnectivityBasicAPIFunctionsTheOpenMapleAPIconsistsofallthestandardfunctionsavailableintheexternalcallAPI,plusStartMaple,StopMaple,andRestartMaplefunctions.Formoreinformationonexternalcalling,see6.2ExternalCalling:UsingCompiledCodeinMapleorreferto?external_calling.ThesequenceforcallingthebasicAPIfunctionsisasfollows.1.CallStartMaple.Formoreinformation,seethefollowingInitializingMaplesubsection.2.ExecuteastringcommandinMaplebycallingEvalMapleStatementoruseanyoftheotherfunctionslistedinmaplec.h.Formoreinfor-mation,seeEvaluatingMapleInputonpage377.3.ResetMaplebycallingRestartMaple(ifnecessary).Toexecutead-ditionalcommandsinthissession,returntostep2.Formoreinfor-mationonrestartingMaple,seeReinitializingMapleonpage379.4.CallStopMaple.OnceyoustoptheMaplekernel,youcannotrestartit.FormoreinformationonstoppingMaple,seeTerminatingMapleonpage379.Thecall-backfunctionsaredeclaredinmaplec.handdeßnedinthefollowingsubsections.InitializingMapleTheStartMaplefunction:¯CreatesaMaplekernel¯Passescommand-lineparameterstothiskernel(asubsetofthosethatcanbepassedtothestand-aloneversionofMaple)¯PreparesthekernelforcomputationThecallingsequenceisasfollows.MKernelVectorStartMaple(intargc,char*argv[],MCallBackVectorcb,void*user_data,void*info,char*errstr);¯Theargcparameterindicatesthenumberofcommand-lineargumentspassedinargv. 6.3OpenMaple:UsingMapleinCompiledCode¯377¯Theargvparameterisanarrayofstringpointersgivingthecommand-lineparameters.Thisarraymusthaveatleastargc+1elements,theßrstofwhich(argv[0])mustbethenameoftheapplicationorthestring"maple".IfargvisNULL,argcandargvareignored.TheOpenMaplekernelsupportsasubsetofthecommand-lineoptionssupportedbythecommand-lineversionofMaple.Optionsthattakearguments(suchas"-b")canbepassedaseither:ÛAsingleparameter,inwhichtheargumentimmediatelyfollowstheoptionwithnointerveningspace,forexample,"-b/usr/maple/lib"ÛApairofparameters,forexample,"-b"and"/usr/maple/lib"Optionsthatarenotsupportedincludepreprocessordirectives(-D,-I,-U)andßltermodes(-F,-l,-P).Optionsspecißctoonlythegraphicalinterfacearealsonotsupported.¯ThecbparameterspecißesacollectionoffunctionsthatMapleusestoreturnresultstoyourapplication.Formoreinformationoncall-backfunctions,seeCall-backFunctionsonpage380.¯Theuser_dataparameterisanarbitraryuser-suppliedvalue.Itistheßrstargumentpassedtothecall-backfunctions.¯Theinfoparameteriscurrentlyusedonlyforinternalpurposes.ItmustbesettoNULL.¯TheerrstrparameterisapreallocatedstringbuÞer.Theerrorpa-rameterpointstoamemoryareawhereanerroriswrittenifini-tializationfails.Theerrormessagewillnotexceed2048characters(includingthenulterminator).TheStartMaplefunctionreturnsaMaplekernelhandleifsuccessful.Thishandleisneededasanargumenttoallotherfunctionslistedinmaplec.h.IfMapleInitializefails(forexample,ifincorrectargumentsarepassed),itreturnsazeroandanerrormessageiswritteninthememorypointedtobytheerrstrparameter.Currently,multiplekernelsarenotsupported.EvaluatingMapleInputThemostgeneralevaluationfunction,EvalMapleStatementtakesaninputstring,parsesit,andthenexecutesitasifitwereenteredinstand-aloneMaple.Theresultandinterme-diateoutputcanbedisplayedusingthecall-backfunctionssuppliedtoStartMaple. 378¯Chapter6:AdvancedConnectivityThestructurerepresentingtheßnalresultisalsoreturnedandcanbemanipulatedbyotherfunctionsthatworkwithALGEBtypes.TheEvalMapleStatementfunctionisdeßnedasfollows.ALGEBM_DECLEvalMapleStatement(MKernelVectorkv,char*statement);¯ThekvparameterspecißesthehandletotheMaplekernel.ThisisthehandlereturnedbyStartMaple.¯Thestatementparameterspecißesthestatementtobeevaluated,expressedinMaplesyntax.Iftheexpressioncontainsasyntaxerror,EvalMapleStatementcallstheerrorCallBackwithtwoparameters:asyntaxerrormessageandtheoÞsetintostatementatwhichtheerroroccurred.FormoreinformationontheerrorCallBackfunc-tion,seeErrorCall-backFunctiononpage382.Asinstand-aloneMaple,statementsendinginacolon(:)donotgenerateoutput.Out-putcausedbyprintorlprintcommands,byerrors,orbyhelprequestsisalwaysdisplayed.RaisingaMapleExceptionTheMapleRaiseErrorfunctioncanbecalledfromanycall-backfunctiontocauseaMapleerror,asiftheMapleerrorstatementhadbeencalled.IfaMapletry-catch5isineÞect,itcatchestheerror,andMaplecodecontinuestoexecuteafterthetry-catchcall.Otherwise,computationstops,andaMapleerrormessageisgeneratedandsenttoerrorCallBackfunction.Formoreinfor-mationontheerrorCallBackfunction,seeErrorCall-backFunctiononpage382.TheMapleRaiseErrorfamilyoffunctionsisdeßnedasfollows.voidMapleRaiseError(MKernelVectorkv,char*msg);voidMapleRaiseError1(MKernelVectorkv,char*msg,ALGEBarg1);voidMapleRaiseError2(MKernelVectorkv,char*msg,ALGEBarg1,ALGEBarg2);¯ThekvparameterspecißesthehandletotheMaplekernel.¯Themsgparameteristhetextoftheerrormessagetoproduce(unlesstheexceptioniscaught).5Formoreinformationonthetry-catchstatement,refertochapter6oftheIntro-ductoryProgrammingGuideor?try. 6.3OpenMaple:UsingMapleinCompiledCode¯379¯TheargparametersareoneormorearbitraryMapleobjectsthataresubstitutedintonumberedparameterlocationsinthemsgstringwhentheexceptionisdisplayed.Forinformationonusingoptionalarguments,referto?error.ReinitializingMapleTheRestartMaplefunctioncanbecalledanytimetoreinitializethestateofaMaplekernel.Reinitializingthekernelisequivalenttorestartingtheapplication,exceptthatanyexistingallocatedmemoryisallocatedtothekernelinternalfreestoragelists;thememoryisnotreturnedtotheoperatingsystem.CallingRestartMaplewhennocomputationisactiveisequivalenttosendingthestatement"restart;"totheEvalMapleStatementfunction.TheRestartMaplefunctionisdeßnedasfollows.M_BOOLRestartMaple(MKernelVectorkv,char*errstr);¯ThekvparameterspecißesthehandletotheMaplekerneltoberestarted.¯TheerrstrparameterisapreallocatedstringbuÞer.Theerrorpa-rameterpointstoamemoryareawhereanerroriswrittenifreini-tializationfails.Theerrormessagewillnotexceed2048characters,includingthenulterminator.¯IfanerroroccurswhentheRestartMaplefunctioniscalledandnocomputationisactive,RestartMaplereturnsFALSE,andanerrormes-sageiswritteninthememorypointedtobytheerrstrparameter.Ifnoerroroccurs,itreturnsTRUE.TerminatingMapleToterminatetheMaplekernel(forexample,priortoexitingyourapplication),calltheStopMaplefunctiontofreememorythathasbeenallocatedbyMaple.TheStopMaplefunctionalsoclosesopenßlesandperformsothercleanupoperations.TheStopMaplefunctionisdeßnedasfollows.voidStopMaple(MKernelVectorkv);ThekvparameterspecißesthehandletotheMaplekerneltotermi-nate.Note:AftercallingtheStopMaplefunction,youcannotcallOpenMapleAPIfunctions(includingStartMaple). 380¯Chapter6:AdvancedConnectivityCall-backFunctionsResultsarereturnedfromaMaplecomputationusingyourcall-backfunc-tions.Theoutputispassedtoacall-backfunction.Otherwise,theresultsgotostandardoutput,stdout.Youmustpassthecall-backfunctionstotheStartMaplefunctioninastructureoftypeMCallBackVector.TheMCallBackVectortypeisdeßnedasfollows.typedefstruct{void(M_DECL*textCallBack)(void*data,inttag,char*output);void(M_DECL*errorCallBack)(void*data,M_INToffset,char*msg);void(M_DECL*statusCallBack)(void*data,longkilobytesUsed,longkilobytesAlloc,doublecpuTime);char*(M_DECL*readLineCallBack)(void*data,M_BOOLdebug);M_BOOL(M_DECL*redirectCallBack)(void*data,char*name,char*mode);char*(M_DECL*streamCallBack)(void*data,char*name,M_INTnargs,char**args);M_BOOL(M_DECL*queryInterrupt)(void*data);char*(M_DECL*callBackCallBack)(void*data,char*output);}MCallBackVector,*MCallBack;Eachfunctiontakesoneormoreparameters.Alltakeagenericdataparameter.ThedataparameterispassedthevalueofthedataparameteroftheStartMaplefunction.Ifacall-backfunctionneedstheMKernelVectorofthekernelfromwhichitwascalled,yourapplicationcanusethedataparametertopassthisinformation.Forexample,thedataparametercanpassapointertoanobjectorstructurecontainingtheMKernelVector.Note:AlltheAPIfunctions,includingthecall-backfunctions,arede-claredwiththeM_DECLmodißer.Thefunctionsassignedtothecall-backvectormustalsobedeclaredwiththeM_DECLmodißer.Thecall-backfunctionsaredeßnedinmaplec.handdescribedinthefollowingsubsections. 6.3OpenMaple:UsingMapleinCompiledCode¯381TextCall-backFunctionItisrecommendedthatyouspecifyatextCallBackfunction.ThetextCallBackfunctioniscalledwithtypical(non-exceptional)Mapleoutput.TheoutputthatMaplegenerates,forexample,aninter-mediateresultortheoutputfromaprintfstatement,ispassedtothetextCallBackfunction.void(M_DECL*textCallBack)(void*data,inttag,char*output)¯ThetagparameterindicatesthetypeofMapleoutput.Thetagpa-rametercantakeoneofthefollowingvalues(asdeßnedinmoemapi.h).MAPLE_TEXT_OUTPUTAline-printed(1-D)Mapleexpres-sionorstatement.MAPLE_TEXT_DIAGDiagnosticoutput(highprintlevelortraceoutput).MAPLE_TEXT_MISCMiscellaneousoutput,forexample,fromtheMapleprintffunction.MAPLE_TEXT_HELPTexthelpoutput.Thisisgeneratedinresponsetoahelprequest.Foramorecomprehensivehelpfacility,see6.3MapleOnlineHelpDatabase.MAPLE_TEXT_QUITResponsetoaMaplequit,done,orstopcommand.MAPLE_TEXT_WARNINGAwarningmessagegenerateddur-ingacomputation.MAPLE_TEXT_ERRORAnerrormessagegeneratedduringparsingorprocessing.ThisisgeneratedonlyifyoudonotspecifyanerrorCallBackfunction.FormoreinformationontheerrorCallBackfunction,seethefollowingErrorCall-backFunctionsubsection.MAPLE_TEXT_STATUSKernelresourceusagestatus(a"bytesused"message).Thisisgeneratedonlyifyoudonotspec-ifyastatusCallBackfunction.FormoreinformationonthestatusCallBackfunction,seethefollowingStatusCall-backFunctionsubsection.MAPLE_TEXT_DEBUGOutputfromtheMapledebugger.¯Theoutputparametercontainstheoutputofthetypeindicatedbythetagparameter.Eachoutputstringcanbearbitrarilylong. 382¯Chapter6:AdvancedConnectivityErrorCall-backFunctionTheerrorCallBackfunctioniscalledwhenanerroroccursduringparsingorprocessing.void(M_DECL*errorCallBack)(void*data,M_INToffset,char*msg)¯Theoffsetparameterindicatesthelocationofaparsingerror.ÛIfoffsetµ0,theerrorwasdetectedatthespecißedoÞsetinthestringpassedtoEvalMapleStatement.ÛIfoffset<0,theerrorisnotaparsingerror;itisacomputationerror.¯Themsgparametercontainsthetextoftheerrormessage.IfanerrorCallBackfunctionisnotspecißed,errormessagesaresenttothetextCallBackfunction,withtheMAPLE_TEXT_ERRORtag.FormoreinformationonthetextCallBackfunction,seetheprevioussubsectionTextCall-backFunction.StatusCall-backFunctionThestatusCallBackfunctioniscalledwhenMaplereportsresourceusageinformation(equivalenttothe"bytesused"messagesinstand-aloneMaple).void(M_DECL*statusCallBack)(void*data,longkilobytesUsed,longkilobytesAlloc,doublecpuTime)¯ThecpuTimeparameteristhenumberofsecondsofCPUtimecon-sumedsincetheMaplekernelwasstarted.Thisincludestimespentinanycall-backfunctions.¯ThebytesUsedparameterindicateshowmanybytesofstoragehavebeenallocatedbytheMapleinternalstoragemanager.¯ThebytesAllocparameterindicateshowmanybytesofstoragehavebeenallocatedbytheoperatingsystembytheMapleinternalstoragemanager.IfnostatusCallBackfunctionisspecißed,statusinformationissenttothetextCallBackfunctionintheform"bytesused=%ld,alloc=%ld,time=%1.2f",withtheMAPLE_TEXT_STATUStag.FormoreinformationonthetextCallBackfunction,seeTextCall-backFunc-tiononpage380. 6.3OpenMaple:UsingMapleinCompiledCode¯383ReadLineCall-backFunctionThereadLineCallBackfunctioniscalledwhenthekernelexecutestheMaplereadline6function(whichisalsousedbyreadstatandhistory)toobtainalineofinputfromtheuser.Inmostapplications,thisisnotused.char*(M_DECL*readLineCallBack)(void*data,M_BOOLdebug)¯ThedebugparameterindicatesthatthecalltoreadlinewasmadebytheMapledebugger(theMapledebuggerusesreadlinetogetdebuggercommandsfromtheuser).ÛIfdebugisTRUE,thereadlinecallisfromthedebugger.ÛIfdebugisFALSE,thereadlinecallisfromhistory,readstat,oranothernon-debuggercall.IfnoreadLineCallBackfunctionisprovided,anyattempttoexe-cutetheMaplereadlinefunctionproducesanerror(reportedusingtheerrorCallBackortextCallBackfunction).FormoreinformationontheerrorCallBackfunction,seeErrorCall-backFunctiononpage382.FormoreinformationonthetextCallBackfunction,seeTextCall-backFunctiononpage380.RedirectCall-backFunctionTheredirectCallBackfunctioniscalledwhenthekernelexecutestheMaplewriteto7orappendtofunction.Theintentistoredirectsubsequentoutput.M_BOOL(M_DECL*redirectCallBack)(void*data,char*name,char*mode)¯Thenameparameterspecißesthenameoftheßletowhichoutputisappended.¯Themodeparameterspecißestheßleaccessmodetouse:"wt"forwriteor"at"forappend.ThenameandmodeparametersarecompatiblewiththeClibraryfunctionfopen.6Formoreinformationonthereadlinefunction,refertochapter7oftheIntroduc-toryProgrammingGuideor?readline.7Formoreinformationonthewritetoandappendtofunctions,seeRedirectingthedefaultOutputStreamonpage217. 384¯Chapter6:AdvancedConnectivityIfthenameparameterisNULL(inwhichcasetheparametersarenotcompatiblewithfopen),Mapleissignallingthatredirectionisterminated.Subsequentoutputissenttothemainoutputstream.Again,thisisuser-dependent.IfnoredirectCallBackfunctionisprovided,anyattempttoexe-cutetheMaplewritetofunctionorappendtofunctionproducesanerror(reportedusingtheerrorCallBackfunctionortextCallBackfunction).CallBackCall-backFunctionThecallBackCallBackfunctioniscalledwhenMaplecodecallstheMaplecallbackfunction.char*(M_DECL*callBackCallBack)(void*data,char*output)¯TheoutputparametercontainsthetextversionoftheparameterspassedtotheMaplecallbackfunction.Onreturn,thecallBackCallBackfunctionreturnseitheraNULLpointerorastringcontainingavalidMapleexpression.¯IftheMaplecallbackfunctionreturnsnothing,thecallbackCallBackfunctionreturnsNULL.¯IfaMapleexpressionisreturned,itisparsed,andtheMaplecallbackfunctionreturnsthe(unevaluated)expression,orthecallbackCallBackfunctionreturnsaparsedMapleexpression.ThisfunctioncanbeusedtoexplicitlypassintermediatevaluesofacomputationtoyourcodeandtoreturnavaluetoMaple.IfnocallBackCallBackfunctionisprovided,anyattempttoexe-cutetheMaplecallbackfunctionproducesanerror(reportedusingtheerrorCallBackfunctionortextCallBackfunction).QueryInterruptCall-backFunctionThequeryInterruptcall-backfunctioniscalledtoallowtheusertohaltthecomputation.ThisfunctioniscalledbeforeeachMaplestatementisexecuted.Ingeneral,thisoccurshundredsoftimespersecond.Forsomeoperations(notablylargeintegermanipulations),thequeryInterruptfunctioniscalledeveryfewseconds.M_BOOL(M_DECL*queryInterrupt)(void*data)Tohaltthecomputation,thefunctionmustreturnTRUE.Tocontinuethecomputation,thefunctionmustreturnFALSE. 6.3OpenMaple:UsingMapleinCompiledCode¯385IfnoqueryInterruptfunctionisprovided,computationscannotbeinterrupted.StreamCall-backFunctionTheMaplemathengineandtheOpen-MapleAPIcommunicateusinglogicalstreams.TheMapleenginein-terpretsastreamasanunevaluatedcalltoafunctionwithanamethatbeginswith"INTERFACE_".Dataissentonastreameitherimplicitlybyvariousoperations(forexample,theMapleprintfunctionsendsitsdataontheINTERFACE_PRINTstream),orexplicitlybyacalltotheMaplestreamcallfunction.Thereareseveralpredeßnedstreams.InOpen-Maple,moststreamsmaptooneofthecall-backfunctionsdescribedinthissubsection.Streamsareusuallyusedtooutputinformation(asisdonebytheINTERFACE_PRINTstream),butsomestreamscanbeusedtorequestin-formationaswell.Forexample,theINTERFACE_READLINEstreamisusedtorequestuserinputduringexecutionofaMapleprocedure.InOpen-Maple,INTERFACE_READLINEismappedtothereadLineCallBack.Inadditiontothepredeßnedstreams,aMapleuser,oranOpenMapledeveloper,cancreatestreamsbypassingaMapleexpressionoftheform,INTERFACE_streamName(arguments)tothestreamcallfunction.Ifthestreamreturnsaresult,thestreamcallfunctionreturnsthatresult.(YoucanalsosendtoastreambypassingsuchanexpressiontotheMapleprintfunction,orbyallowingsuchanexpressiontobetheresultofacomputation,butinthatcase,noresultcanbepassedonthestreambacktoMaple).ThestreamCallBackfunctioniscalledwhenMaplesendsoutputasastreamthatisnotexplicitlyhandledbytheOpenMapleAPI.char*(M_DECL*streamCallBack)(void*data,char*name,M_INTnargs,char**args)¯Thenameparameterspecißesthenameofthestreamwithoutthe"INTERFACE_"preßx.¯Thenargsparameterindicatesthenumberofargumentspassed.Ifnoargumentsarepassed,nargsiszero.¯Theargsparameterpointstoanarrayofstringpointers,oneforeachargumentpassed.Eachstringisaline-printed(1-D)Mapleexpressioncorrespondingtothatargument. 386¯Chapter6:AdvancedConnectivityThestreamCallBackfunctionmustreturnastringinvalidMaplesyntax.Ifnoresultistobereturned,itmustreturntheNULLpointer.User-deßnedstreamsareanalternativetousingthecallBackCallBackfunction.FormoreinformationonthecallBackCallBackfunction,seeCallBackCall-backFunctiononpage384.Streamshaveseveralad-vantages:¯Thestreamnameispassed.YoucanusemultiplestreamsinMaplecode,andquicklydeterminewhichoperationtoperformbyexaminingthestreamnameinthestreamCallBackfunction.¯Multipleargumentsarepassedasseparatestrings,unlikethecallBackCallBackfunctiontowhichmultipleargumentsarepassedasasinglecomma-separatedstring.ThisreducesparsingrequirementsintheOpenMapleapplication.¯Thenumberofargumentsispassed,makingiteasiertocheckthatthecorrectargumentsarepassed.IfnostreamCallBackfunctionisspecißedandoutputissenttoanunknownstream,theargumentstothestreamaresenttothecall-backfunctiontowhichMapleresultsaresent,thatis,thetextCallBackfunc-tion.MapleOnlineHelpDatabaseTheMapleonlinehelpsystemisalsoavailabletoyourapplication.Al-thoughhelpoutputcanbegeneratedbypassingaMaplehelpcommandtoakernel(inwhichcasetheoutputisreturnedtothetextCallBackfunctionwithaMAPLE_TEXT_HELPtag),suchoutputdoesnotreàectanymarkupinthehelpßle.Bycallingthehelpsystemdirectly,formattedhelppagescanberetrieved.SettingtheHelpDatabaseSearchPathThehelpsystemisaccessedusingtheMapleHelpfunction.Aswithstand-aloneMaple,thehelpsearchpathisdeßnedbythevalueoflibname8.TheMapleLibNamefunctioncanbeusedtoqueryorchangethispath.FormoreinformationontheMapleLibNamefunction,refertomaplec.h.RetrievingaHelpPageToretrieveanddisplayahelppage,usetheMapleHelpfunction.Thefollowingßgureillustratestextmodehelpoutput.8Formoreinformationonlibname,referto?libname. 6.3OpenMaple:UsingMapleinCompiledCode¯387TheMapleHelpfunctionretrievesanddisplaysahelppage,orasec-tionofahelppage,basedonthespecißedtopic.Theresultsarepassedasastreamofcharactersandattributestothespecißedcall-backfunctions.char*M_DECLMapleHelp(MKernelVectorkv,char*topic,char*section,M_BOOL(M_DECL*writeChar)(void*data,intc),M_BOOL(M_DECL*writeAttrib)(void*data,inta),intwidth,void*data)¯ThekvparameterspecißesthehandletotheMaplekernel.Thishan-dleisreturnedbyStartMaple.¯Thetopicparameterspecißesthehelppage.ThetopicisgenerallyaMaplekeyword,functionname,symbol,oracombinationthereofseparatedbycommas.Forexample,torefertoafunctioninapackage,use"package_name,function_name". 388¯Chapter6:AdvancedConnectivity¯Thesectionparameterindicateswhichsectionofthepagetodisplay.Ifthisispassedas""orNULL,theentirepageisdisplayed.Torestrictdisplaytoaparticularsectionofthepage,passoneofthefollowingvalues."usage"Displaysthefunctionname(one-linedescription)andcall-ingsequence"description"Displaysthedetaileddescriptionofthefunction"examples"Displaysexamplesofthefunctionusage"seealso"Displaysalistofrelatedtopics¯ThewriteCharparameterdeßnesacall-backfunctiontowhichthecharactersarepassed.Thecharactersareallprintable.Leadingspacesareaddedtoachievetheappropriatealignment.Notrailingspacesaregenerated.Anewline('nn')characterissentattheendofeachline.ThewriteCharfunctionterminatesrenderingbyreturningTRUE.¯ThewriteAttribparameterdeßnesacall-backfunctiontowhichattributeinformationispassed.TheattributepassedtowriteAttribappliestoallcharacterspassedtowriteCharuntilanotherattributeispassedtowriteAttrib.Thepossibleattributevaluesare:FN_NORMALNormaltextmode.FN_BOLDBoldfacedtextmode.ThiscanbeusedforkeywordsinMapleproceduresinexampleoutputandforsectionheadings.FN_ITALItalictextmode.Thiscanbeusedforcallingsequenceparameternames.FN_UNDERUnderlinedtextmode.Thisisusedforlinkstoothertopics.Theformatofthistextis"linkReference##linkText",wherelinkReferenceisthetopictowhichthelinkrefersandlink-Textisthelinktextdisplayedinthehelppage.ItisequivalenttotheHTMLcode:linkTextThewriteAttribfunctioncanbeomittedbypassingNULLforthewriteAttribparameter.¯Thewidthparameterindicatesthewidth,incharacters,towhichthehelpinformationisformatted.¯Thedataparameterisanarbitraryuser-suppliedvalue.Itistheßrstargumentpassedtothecall-backfunctions. 6.3OpenMaple:UsingMapleinCompiledCode¯389TheMapleHelpfunctionreturnsNULLifsuccessful,oritreturnsapointertoanerrormessageifunsuccessful.Itmayreturnthesamepointerinallcasesoffailure.Tosavethemessage,makeacopyofitimmediately.TechnicalIssuesThissubsectiondiscussestechnicalissuesrelatedtousingOpenMaple.MemoryUsageMapleallocatesmemoryfromtheoperatingsystem(throughtheCmallocfunctiononmostarchitectures)inlargechunks(64KBonmostarchitectures).Thismemoryisnotreturnedtotheop-eratingsystem(thatis,byfree)untilMapleterminates.WhenMaplenolongerrequiresapieceofmemory,thememoryisaddedtooneoftheMapleinternalfreestoragelists.Maplemaintainsseveralstoragelists,fordiÞerentsizesofmemoryblocks,soitcanquicklyßndblocksofthere-quiredsize.Forexample,Maplemakesextensiveuseofthree-wordblocks,soitmaintainsalistoffreeblocksofthatsize.Mapleallocatesadditionalmemoryfromtheoperatingsystemonlywhenitisunabletosatisfyarequestusingitsstoragelists.Mapleappearstoleakmemorybecausetheamountofmemoryallo-catedtoMapleonlyincreases.ThemorememoryMapleisallocatedbytheoperatingsystem,thelessitisallocatedinfuturebecauseitreusesmemory.Formostapplications,4MBofmemorymustbeavailableforMapletoallocate.UnderMicrosoftWindows,theMaplekerneliscompiledusing4-bytestructurealignment.Yourapplicationmustbecompiledthisway.ThisisageneralrequirementforWindowsapplications.FileStructureOÞthemainMapleinstallationpath,thefollowingsubdirectoriescontainßlesrelatedtoOpenMaple.bin.$SYSLocationofmaplec.dllandmaplec.lib.AlsoholdsvariousdynamiclibrariesusedbytheOpenMaplekernel.Todetermine$SYSforyourplatform,seeTable6.5onpage395.samples/OpenMapleLocationoftheC/C++#includeßlesforusewithexternalcallingandOpenMaple.libLocationoftheMaplemathlibrariesandhelpdatabase.extern/examplesLocationofplatform-independentsamplecode. 390¯Chapter6:AdvancedConnectivityTheOpenMapleßlesinstalledareplatformdependent.9UNIXOnUNIXplatforms,theOpenMapleengineconsistsofasharedobjectlibrary(libmaplec.so,libmaplec.sl(HP),orlibmaplec.a(AIX))whichexportsthefunctionsdescribedinthisdocument.MicrosoftWindowsUnderMicrosoftWindows,theOpenMapleengineconsistsofaDLL(maplec.dll)whichexportsthefunctionsdescribedinthisdocument.Animportlibraryisalsoprovided.Theßlemaplec.libinthebin.$SYSdirectoryisanimportlibraryinCOFFformat.MacOSXUnderMacOSX,theOpenMapleengineconsistsoftwodynamiclibraries(libmaplec.dylibandlibmaple.dylib),whichexportthefunctionsdescribedinthisdocument.BuildingtheSampleProgramThecodeforonesimpleexampleofhowtouseOpenMapleisintheßlesamples/OpenMaple/cmaple/omexample.c.Theexampleprogramillus-trateshowtoevaluateexpressions,accesshelp,andinterruptcomputa-tions.ThefollowingassumesthecurrentdirectoryistherootoftheMapleinstallation,andthatthecompilerissetuptoworkincommand-linemode,thatis,itisinthePATHandrelevantenvironmentvariablesaresetup.AIXsetenvLIBPATHbin.IBM_RISC_UNIXccsamples/OpenMaple/cmaple/omexample.c-obin.IBM_RISC_UNIX/omexample-Lbin.IBM_RISC_UNIX-Iinclude-lmaplecbin.IBM_RISC_UNIX/omexampleDigitalUNIX/CompaqTru64setenvLD_LIBRARY_PATHbin.DEC_ALPHA_UNIXccsamples/OpenMaple/cmaple/omexample.c-obin.DEC_ALPHA_UNIX/omexample-Lbin.DEC_ALPHA_UNIX-Iinclude-lmaplecbin.DEC_ALPHA_UNIX/omexample9Foralistofcurrentlysupportedoperatingsystemversions,refertotheinstallationinstructions. 6.3OpenMaple:UsingMapleinCompiledCode¯391HP-UXsetenvSHLIB_PATHbin.HP_RISC_UNIXccsamples/OpenMaple/cmaple/omexample.c-obin.HP_RISC_UNIX/omexample-Lbin.HP_RISC_UNIX-Iinclude-lmaplec-lCsupbin.HP_RISC_UNIX/omexampleIRIXsetenvLD_LIBRARY_PATHbin.SGI_MIPS_UNIXccsamples/OpenMaple/cmaple/omexample.c-obin.SGI_MIPS_UNIX/omexample-Lbin.SGI_MIPS_UNIX-Iinclude-lmaplecbin.SGI_MIPS_UNIX/omexampleLinuxsetenvLD_LIBRARY_PATHbin.IBM_INTEL_LINUXgccsamples/OpenMaple/cmaple/omexample.c-obin.IBM_INTEL_LINUX/omexample-Lbin.IBM_INTEL_LINUX-Iinclude-lmaplecbin.IBM_INTEL_LINUX/omexampleMacOSXsetenvDYLD_LIBRARY_PATHbin.APPLE_PPC_OSXgccsamples/OpenMaple/cmaple/omexample.c-obin.APPLE_PPC_OSX/omexample-Lbin.APPLE_PPC_OSX-Iinclude-lmaplec-lmaplebin.APPLE_PPC_OSX/omexampleMicrosoftWindowswithMicrosoftVisualC/C++(MSVC)cdbin.IBM_INTEL_NTcl-Gz../samples/OpenMaple/cmaple/omexample.c-I../includemaplec.libomexampleSolarissetenvLD_LIBRARY_PATHbin.SUN_SPARC_SOLARISccsamples/OpenMaple/cmaple/omexample.c-obin.SUN_SPARC_SOLARIS/omexample-Lbin.SUN_SPARC_SOLARIS-Iinclude-lmaplecbin.SUN_SPARC_SOLARIS/omexample 392¯Chapter6:AdvancedConnectivity6.4ConclusionThischapteroutlinedhowtheCodeGenerationpackageprovidesutilitiesfortranslatingMaplecodetootherprogramminglanguages.Additionally,thischapterdiscussedhowtheMaplekernelcanbeextendedbyintegrat-ingcompiledcodeusingtheExternalCallingpackageandhowMaplecanbeusedbycompiledcodeusingOpenMaple. 6.4Conclusion¯393JavaTypetype[]AstringNANANAFortranTypetype*ACHARACTER*2COMPLEXCOMPLEX*8DOUBLECOMPLEXCOMPLEX*16NACompoundTypesCTypetype*Acharx[n]struct{floatr,i;}struct{doubler,i;}TYPENAME*Table6.3order=...,etc.)MapleDataDescriptorARRAY(datatype=typename,string[n]complex[4]complex[8]REF(typename) 394¯Chapter6:AdvancedConnectivityRETURN::descriptorR)PROC(member1::descriptor1,...,UNION(member1::descriptor1,...,memberN::descriptorN,options)STRUCT(member1::descriptor1,...,MapleDataDescriptormemberN::descriptorN,memberN::descriptorN,options)Table6.4typeR(*proc)(type1member1,...,union{type1member1;...,struct{type1member1;...,CTypetypeN,memberN);typeNmemberN;}typeNmemberN;}WrapperCompoundTypesNANANAFortranTypeNANANAJavaType 6.4Conclusion¯395FortranMapleAPILibrarymaplefortran.lib(maplefortran.dll)maplefortran.dyliblibmaplefortran.solibmaplefortran.sllibmaplefortran.solibmaplefortran.alibmaplefortran.solibmaplefortran.so(Windows98),CMapleAPILibrarymaplec.lib(maplec.dll)maplec.dyliblibmaplec.solibmaplec.sllibmaplec.solibmaplec.alibmaplec.solibmaplec.sobin.w9xLoadLibraryEnvironmentVariablePATHDYLD_LIBRARY_PATHLD_LIBRARY_PATHSHLIB_PATHLD_LIBRARY_PATHLIBPATHLD_LIBRARY_PATHLD_LIBRARY_PATHMapleAPILibrariesforCandFortranTable6.5(otherWindowsplatforms).1bin.winBinaryDirectorybin.wXXNAbin.SUN_SPARC_SOLARISbin.HP_RISC_UNIXbin.SGI_MIPS_UNIXbin.IBM_RISC_UNIXbin.DEC_ALPHA_UNIXbin.IBM_INTEL_LINUX(WindowsNT),andForMicrosoftWindows,thebinarydirectorynamedependsontheplatform.Itisoneof:OperatingSystemMicrosoftWindowsMacOSXSolarisHP-UXIRIXAIXOSF1/True64Linux1bin.wnt 396¯Chapter6:AdvancedConnectivity TableA.1MapleStructuresANDASSIGNBINARYBREAKCATENATECOMPLEXCONTROLDCOLONDEBUGEQUATIONERROREXPSEQFLOATFORFOREIGNFUNCTIONGARBAGEHASHHASHTABHFLOATIFIMPLIESINEQUATINTNEGINTPOSLESSEQLESSTHANLEXICALLISTLOCALMEMBERMODDEFMODULENAMENEXTNOTORPARAMPOWERPROCPRODRANGERATIONALREADRETURNRTABLESAVESERIESSETSTATSEQSTOPSTRINGSUMTABLETABLEREFTRYUNEVALUSEXORZPPOLYAInternalRepresentationandManipulationTableA.1liststhestructurescurrentlyimplementedinMaple.Eachofstructure,alongwiththeconstraintsonitslengthandcon-tents,isdescribedinthefollowingsections.A.1InternalOrganizationMapleappearstotheuserasaninteractivecalculator.Theuserinterfacereadsinput,parsesit,andthencallsthemathengineforeachcompletestatementencountered.Maplecanreadandevaluateanunlimitednumberofstatementsuntilaquitstatementisevaluated,ortheuserinterfaceisshutdown.397 398¯AppendixA:InternalRepresentationandManipulationComponentsMapleconsistsofthreemaincomponents:akernel,alibrary,andauserinterface.Thekernelandlibrarytogetherareknownasthemathengine.KernelThekerneliswrittenintheClanguageandisresponsibleforlow-leveloperationssuchasarbitraryprecisionarithmetic,ßleI/O,execu-tionoftheMaplelanguage,andtheperformanceofsimplemathematicaloperationssuchasdiÞerentiationofpolynomials.LibraryMostoftheMaplemathematicalfunctionalityisintheMaplelibrary,whichiswrittenintheMaplelanguage.Thelibraryisstoredinanarchive,andpiecesofitareloadedandinterpretedbythekernelondemand.UserInterfaceTheuserinterfaceisthepartofMaplethattheusersees,andisconceptuallyseparatefromthemathengine.ThesamemathenginecanbeusedwithdiÞerentuserinterfaces.Usually,Mapleisprovidedwithagraphicaluserinterface(GUI)andacommand-lineinterface.TheGUIismoreusefulforinteractiveuse,especiallywhenworkingwithplotsorlargematrices.Thecommand-lineinterfaceispracticalforbatchprocessing,orsolvinglargeproblemswhereyouwanttodevotealltheresourcesofyourcomputertocomputation.Mapletapplicationsprovideanalternateuserinterface,whichisbuiltfromadescriptiongeneratedintheMathEnginebyaseriesofusercom-mands.FormoreinformationontheMapletspackage,refertotheIntro-ductoryProgrammingGuide.InternalFunctionsTheinternalfunctionsinMaplearedividedintoßvedistinctgroups:1.EvaluatorsTheevaluatorsarethemainfunctionsresponsibleforevaluation.Therearesixtypesofevaluations:statements,algebraicexpressions,booleanexpressions,nameforming,arbitraryprecisionàoating-pointarithmetic,andhardwareàoating-pointarithmetic.Theuserinterfacecallsonlythestatementevaluator,butthereafter,therearemanyinteractionsbetweenevaluators.Forexample,thestatement,ifa>0thenb||i:=3.14/aendifisßrstanalyzedbythestatementevaluator,whichcallstheBooleanevaluatortoresolvetheifcondition.Oncecompleted(forexample, A.1InternalOrganization¯399withatrueresult),thestatementevaluatorisinvokedagaintodotheassignment,forwhichthename-formingevaluatorisinvokedwiththeleftsideoftheassignment,andtheexpressionevaluatorwiththerightside.Sincetherightsideinvolvesàoating-pointvalues,theexpressionevaluatorcallsthearbitraryprecisionàoating-pointevaluator.Normally,theuserdoesnotspecißcallyinvokeanyoftheevaluators,butinsomecircumstances,whenanon-defaulttypeofevaluationisneeded,theusercandirectlycallevalb(theBooleanevaluator),evaln(thename-formingevaluator),evalf(thearbitraryprecisionàoating-pointevaluator),orevalhf(thehardwareàoating-pointeval-uator).2.AlgebraicFunctionsThesearecommonlycalledbasicfunctions.Someexamplesare:takingderivatives(diff),dividingpolynomi-als(divide),ßndingcoeácientsofpolynomials(coeff),comput-ingseries(series),mappingafunction(map),expandingexpressions(expand),andßndingindeterminates(indets).3.AlgebraicServiceFunctionsThesefunctionsarealgebraicinnature,butserveassubordinatesofthefunctionsinthepreviousgroup.Inmostcases,thesefunctionscannotbeexplicitlycalledbytheuser.Examplesofsuchfunctionsaretheinternalarithmeticpackages,thebasicsimplißer,andretrievaloflibraryfunctions.4.DataStructureManipulationFunctionsThesearelikethealge-braicfunctions,butinsteadofworkingonmathematicalobjects,suchaspolynomialsorsets,theyworkondatastructures,suchasexpres-sionsequences,sums,products,orlists.Examplesofsuchfunctionsareoperandselection(op),operandsubstitution(subsop),searching(has),andlengthdetermination(length),5.GeneralServiceFunctionsFunctionsinthisgroupareatthelowesthierarchicallevel.Thatis,theymaybecalledbyanyotherfunctioninthesystem.Theyaregeneralpurpose,andnotnecessar-ilyspecißctosymbolicornumericcomputation.Someexamplesare:storageallocationandgarbagecollection,tablemanipulation,internalI/O,andexceptionhandling.FlowofControlTheàowofcontrolneednotremaininternaltotheMaplekernel.Inmanycases,whereappropriate,adecisionismadetocallfunctionswritteninMapleandresidinginthelibrary.Forexample,manyusesoftheexpand 400¯AppendixA:InternalRepresentationandManipulationfunctionarehandledinthekernel.However,ifanexpansionofasumtoalargepowerisrequired,thentheinternalexpandcallstheexternalMaplelibraryfunction`expand/bigpow`toresolveit.Functionssuchasdiff,evalf,series,andtypemakeextensiveuseofthisfeature.Thus,forexample,thebasicfunctiondiffcannotdiÞerentiateanyfunction.AllofthatfunctionalityresidesintheMaplelibraryinpro-ceduresnamed`diff/functionName`.ThisisafundamentalfeatureofMaplesinceitpermits:¯Flexibility(changingthelibrary)¯Personaltailoring(bydeßningyourreßnedhandlingfunctions)¯Readability(muchoftheMaplefunctionalityisvisibleattheuserlevel)Mapleallowsthekerneltoremainsmallbyunloadingnon-essentialfunc-tionstothelibrary.A.2InternalRepresentationsofDataTypesTheparserandsomeinternalfunctionsareresponsibleforbuildingallthedatastructuresusedinternallybyMaple.Alltheinternaldatastructureshavethesamegeneralformat:HeaderData1...DatanTheheaderßeld,storedinoneormoremachinewords,encodesthelengthofthestructureanditstype.Additionalbitsareusedtorecordsimplißcationstatus,garbagecollectioninformation,persistentstoresta-tus,andvariousinformationaboutspecißcdatastructures(forexample,whetherornotaforloopcontainsabreakornext).Thelengthisencodedin26bitson32-bitarchitectures,resultinginamaximumsingleobjectsizeof67;108;863words(268;435;452bytes,or256megabytes).On64-bitarchitectures,thelengthisstoredin32bits,foramaximumobjectsizeof4;294;967;295words(34;359;738;360bytes,or32gigabytes).Everystructureiscreatedwithitsownlength,andthatlengthdoesnotchangeduringtheexistenceofthestructure.Furthermore,thecon-tentsofmostdatastructuresareneverchangedduringexecution,becauseitisunpredictablehowmanyotherdatastructuresmaybereferringto A.2InternalRepresentationsofDataTypes¯401it,andrelyingonitnottochange.Thenormalproceduretomodifyastructureistocopyit,andthentomodifythecopy.Structuresthatarenolongerusedareeventuallyreclaimedbythegarbagecollector.Thefollowingßguresdescribeeachofthe60structurescurrentlyim-plementedinMaple,alongwiththeconstraintsontheirlengthandcon-tents.The6-bitnumericvalueidentifyingthetypeofstructureisoflittleinterest,sosymbolicnameswillbeused.LogicalANDAND^expr1^expr2Maplesyntax:expr1andexpr2Length:3AssignmentStatementASSIGN^nameseq^exprseqMaplesyntax:name1,name2,...:=expr1,expr2,...Length:3Theleft-handsidenameentriesmustevaluatetoassignableobjects:NAME,FUNCTION,orTABLEREFstructures.Theright-handsidemustbeanexpressionsequenceofthesamelengthastheleft-handside.BinaryObjectBINARYdata...Maplesyntax:noneLength:arbitraryTheBINARYstructurecanholdanyarbitrarydata.ItisnotuseddirectlyasaMapleobject,butisusedasstorageforlargeblocksofdatainsideotherMapleobjects(currentlyonlyRTABLEs).Itisalsosometimesusedastemporarystoragespaceduringvariouskerneloperations.BreakStatementBREAKMaplesyntax:breakLength:1 402¯AppendixA:InternalRepresentationandManipulationNameConcatenationCATENATE^name^exprMaplesyntax:name||exprLength:3¯IfthenameentryisoneofNAME,CATENATE,LOCAL,orPARAM,andiftheexprentryevaluatestoaninteger,NAME,orSTRING,thentheresultisaNAME.¯IfthenameentryisaSTRINGorCATENATEthatresolvestoaSTRING,andiftheexprentryevaluatestoaninteger,NAME,orSTRING,thentheresultisaSTRING.¯IfexprisaRANGE,thentheresultistogenerateanEXPSEQofNAMEsorSTRINGs.ComplexValueCOMPLEX^re^imCOMPLEX^imMaplesyntax:Complex(re,im)orre+im*ILength:2or3ThereandimßeldsmustpointtoINTPOS,INTNEG,RATIONAL,orFLOATstructures,oneoftheNAMEsinfinityorundefined,oraSUMstructurerepresenting-infinity.Inthelength3case,ifeitherreorimisaFLOAT,theothermustbeaFLOATaswell.CommunicationsControlStructureCONTROL^integerMaplesyntax:noneLength:2Thisisaninternalstructureusedinkerneltouser-interfacecom-munication.Suchastructureneverreachestheuserlevel,oreventhemathematicalpartsofthekernel. A.2InternalRepresentationsofDataTypes¯403TypeSpecißcationorTestDCOLON^expr^typeexprMaplesyntax:expr::typeExprLength:3Thisstructurehasthreeinterpretationsdependingonthecontextinwhichitisused.Whenitappearsintheheaderofaproceduredeßnition,itisatypedparameterdeclaration.Whenitappearsinthelocalsectionofaprocedureorontheleftsideofanassignment,itisatypeassertion.Whenitappearselsewhere(specißcallyinaconditionalexpression),itisatypetest.DebugDEBUG^expr1^expr2...Maplesyntax:noneLength:2ormoreThisisanotherinternal-onlystructure.Itisusedbythekernelwhenprintingerrortracebackinformationtotransmitthatinformationupthecallstack.EquationorTestforEqualityEQUATION^expr1^expr2Maplesyntax:expr1=expr2Length:3Thisstructurehastwointerpretationsdependingonthecontextinwhichitisused.Itcanbeeitheratestforequality,orastatementofequality(nottobeconfusedwithanassignment).ErrorStatementERROR^exprMaplesyntax:error"msg",arg,...argLength:2 404¯AppendixA:InternalRepresentationandManipulationThisrepresentstheMapleerrorstatement.Theexpriseitherasingleexpression(ifonlyamessagewasspecißedintheerrorstatement),oranexpressionsequence(ifargumentswerealsospecißed).TheactualinternaltagusedfortheERRORstructureisMERROR,topreventcollisionwithamacrodeßnedbysomeCcompilers.ExpressionSequenceEXPSEQ^expr1^expr2...Maplesyntax:expr1,expr2,...Length:1ormoreExpressionsequencesareavailabletotheuserasadatastructure,andarealsousedtopassargumentstoprocedures.EÞectively,procedurestakeasingleargumentthatisanexpressionsequence.Anexpressionsequencemaybeoflength1(thatis,anemptysequence),whichisrepresentedbytheMaplesymbolNULL,orinsomecontexts(suchasparameterstoafunctioncall)asnothingatall.Floating-PointNumberFLOAT^integer1^integer2^attribexprMaplesyntax:1.2,1.2e3,Float(12,34),Float(infinity)Length:2(or3withattributes)Aàoating-pointnumberisinterpretedasinteger1£10integer2.Aàoating-pointnumbermayoptionallyhaveattributes,inwhichcasethelengthofthestructureis3,andthethirdwordpointstoaMapleex-pression.Thissuggeststhatseveralàoating-pointnumberswiththesamevaluebutdiÞerentattributescanexistsimultaneously.Theinteger2ßeldcanoptionallybeoneofthenamesundefinedorinfinity,inwhichcasetheFLOATstructurerepresentsanundeßnedàoating-pointvalue(not-a-number,orNaN,inIEEEterminology),oraàoating-pointinßnity.Wheninteger2isundefined,integer1cantakeondiÞerentsmallintegervalues,allowingtheexistenceofdiÞerentNaNs.Wheninteger2isinfinity,integer1mustbe1or1.For/WhileLoopStatementFOR^name^from^by^to^cond^statexprexprexprexprseq A.2InternalRepresentationsofDataTypes¯405FOR^name^inexpr^condexpr^statseqMaplesyntax:fornamefromfromExprbybyExprtotoExprwhilecondExprdostatSeqenddoMaplesyntax:fornameininExprwhilecondExprdostatSeqenddoLength:7or5ThenamefollowsthesamerulesasinASSIGN,exceptthatitcanalsobetheemptyexpressionsequence(NULL),indicatingthatthereisnocontrollingvariablefortheloop.Thefrom-expr,by-expr,to-expr,andcond-exprentriesaregeneralexpressions.Allareoptionalinthesyntaxofforloopsandcanthusbeßlledinwithdefaultvalues(1,1,NULL,andtruerespectively)bytheparser.Thestat-seqentrycanbeasingleMaplestatementorexpression,aSTATSEQstructure,orNULLindicatinganemptyloopbody.AnadditionalbitintheFORstructure'sheaderisusedtoindicatewhetherthestat-seqcontainsanybreakornextstatements.ForeignDataFOREIGN...Maplesyntax:noneLength:1ormoreThisissimilartotheBINARYstructure,exceptthatitisforusebycomponentsofMapleoutsidethekernel,suchastheuserinterface.AFOREIGNstructureisexemptfromgarbagecollection,anditisthere-sponsibilityoftheexternalcomponenttofreeitwhenitisßnishedusingit. 406¯AppendixA:InternalRepresentationandManipulationFOREIGNdatastructurescanbecreatedandmanagedinexternalcodeviatheMaplePointerAPIfunctions.Formoreinformation,referto?MaplePointer.FunctionCallFUNCTION^name^exprseq^attribexprMaplesyntax:name(exprSeq)Length:2(or3withattributes)Thisstructurerepresentsafunctioninvocation(asdistinctfromaproceduredeßnitionthatisrepresentedbythePROCstructure).ThenameentryfollowsthesamerulesasinASSIGN,oritmaybeaPROCstructure.Theexpr-seqentrygivesthelistofactualparameters,andisalwaysanexpressionsequence(possiblyoflength1,indicatingnoparameters).GarbageGARBAGE...Maplesyntax:noneLength:1ormoreThisstructureisusedinternallybytheMaplegarbagecollectorasatemporaryobjecttypeforfreespace.HardwareFloatHFLOATàoatwordHFLOATàoatwordàoatwordMaplesyntax:noneLength:2on64-bitarchitectures,3on32-bitarchitecturesThisstructureisusedtoholdahardwareàoating-pointvalue.Theoneortwowords(always8bytes)aftertheheaderholdtheactualdouble-precisionàoating-pointvalue.HFLOATobjectsarecurrentlynotavailabledirectlytotheuser,buttheyareusedinternallytomoreeácientlytrans-ferhardwareàoating-pointvaluesbetweenRTABLEsofsuchvalues,andtheMapleI/Ofacilities(forexample,theprintfandscanffamiliesoffunctions). A.2InternalRepresentationsofDataTypes¯407IfStatementIF^cond^stat^cond^stat......^statexpr1seq1expr2seq2......seqNMaplesyntax:ifcondExpr1thenstatSeq1elifcondExpr2thenstatSeq2...elsestatSeqNendifLength:3ormoreThisstructurerepresentstheif...then...elif...else...endifstatementinMaple.Ifthelengthiseven,thelastentryisthebodyofanelseclause.Theremainingentriesareinterpretedinpairs,whereeachpairisaconditionoftheiforelifclause,followedbytheassociatedbody.LogicalIMPLIESIMPLIES^expr1^expr2Maplesyntax:expr1impliesexpr2Length:3NotEqualorTestforInequalityINEQUAT^expr1^expr2Maplesyntax:expr1<>expr2Length:3Thisstructurehastwointerpretations,dependingonthecontextinwhichitisused.Itcanbeeitheratestforinequalityoraninequalitystatement(nottobeconfusedwithanassignment).NegativeIntegerINTNEGintegerinteger... 408¯AppendixA:InternalRepresentationandManipulationMaplesyntax:123Length:2ormoreThisdatastructurerepresentsanegativeintegerofarbitrarypreci-sion.Forpositiveintegerrepresentationinformation,seethefollowingsection.PositiveIntegerINTPOSintegerinteger...Maplesyntax:123Length:2ormoreThisdatastructurerepresentsapositiveintegerofarbitraryprecision.Integersgreaterthanorequaltothethreshold10kernelopts(gmpthreshold)arerepresentedinternallyinabaseequaltothefullwordsizeofthehostmachine.On32-bitarchitectures,thisbaseis232.On64-bitarchitectures,thebaseis264.IntegersinthisrangeusetheGNUMultiplePrecisionArithmetic(GMP)libraryforintegerarithmetic.Integerslessthanthethreshold10kernelopts(gmpthreshold)arerepre-sentedinternallyinasmallerbasethatisalsodependentonthehostmachine.On32-bitarchitectures,thisbaseis10;000.On64-bitarchitec-tures,thebaseis1;000;000;000.Thebaseischosensuchthatthesquareofthebaseisstillrepresentableinamachineinteger.Eachintegerßeldrepresentseither4or9digits.Theleastsignißcantdigitsarerepresentedßrst.Forexample,ona32-bitplatform,theinteger123;456;789;638;747isrepresentedas:INTPOS874789634567123Smallintegersarenotrepresentedbydatastructuresatall.InsteadofapointertoanINTPOSorINTNEGstructure,asmallintegerisrepresentedbythebitsofwhatwouldnormallybeapointer.Theleastsignißcantbitis1,whichmakesthevalueaninvalidpointer(sincepointersmustbeword-aligned).Suchanintegeriscalledanimmediateinteger.Therangeofintegersrepresentableinthiswayis1;073;741;823to1;073;741;823(thatis,about¦109)on32-bitarchitectures,and4;611;686;018;427;387;903to4;611;686;018;427;387;903(thatis,about¦4£1018)on64-bitarchitectures.(Thesenumbersmaynotseemsmall,butconsiderthattheMaplemaximumintegermagnitudeisabout22;147;483;488on32-bitarchitecturesand2274;877;906;688on64-bitarchitec-tures.) A.2InternalRepresentationsofDataTypes¯409LessThanorEqualLESSEQ^expr1^expr2Maplesyntax:expr1<=expr2,expr2>=expr1Length:3Thisstructurehastwointerpretations,dependingonthecontext.Itcanbeinterpretedasarelation(thatis,aninequation),orasacomparison(forexample,intheconditionofanifstatement,ortheargumenttoacalltoevalb).Mapledoesnothaveagreater-than-or-equalstructure.AnyinputofthatformisstoredasaLESSEQstructure.LessThanLESSTHAN^expr1^expr2Maplesyntax:expr1expr1Length:3LiketheLESSEQstructureabove,thisstructurehastwointerpreta-tions,dependingonthecontext.Itcanbeinterpretedasarelation(thatis,aninequation),orasacomparison(forexample,intheconditionofanifstatement,ortheargumenttoacalltoevalb).Mapledoesnothaveagreater-thanstructure.AnyinputofthatformisstoredasaLESSstructure.LexicallyScopedVariablewithinanExpressionLEXICALintegerMaplesyntax:nameLength:2Thisrepresentsanidentißerwithinanexpressioninaprocedureormodulethatisnotlocaltothatprocedure,butisinsteaddeclaredinasurroundingprocedureormodulescope.Theintegerßeldidentißeswhichlexicallyscopedvariableofthecurrentprocedureisbeingreferredto.Theinteger,multipliedby2,isanindexintothelexical-seqstructurereferredtobythePROCDAGoftheprocedure.Specißcally,|integer|*2-1istheindextotheNAMEoftheidentißer,and|integer|*2istheindextoadescription(LOCAL,PARAM,orLEXICAL)relativetothesurroundingscope.Thevalueofintegercanbepositiveornegative.Ifpositive,theoriginalidentißerisalocalvariableofasurroundingprocedure;ifnega-tive,itisaparameterofasurroundingprocedure. 410¯AppendixA:InternalRepresentationandManipulationListLIST^exprseq^attribexprMaplesyntax:[expr,expr,...]Length:2(or3withattributes)Theelementsoftheexpr-seqaretheelementsofthelist.Thelistcanoptionallyhaveattributes.LocalVariablewithinanExpressionLOCALintegerMaplesyntax:nameLength:2Thisindicatesalocalvariablewhenitappearswithinanexpressioninaprocedureormodule.Theintegerisanindexintotheprocedurelocal-seq.Atprocedureexecutiontime,itisalsoanindexintotheinternaldatastructureholdingtheactivelocalsontheprocedureactivationstack,andholdsprivatecopiesoftheNAMEsofthelocalvariables(privatecopiesinthesensethattheseNAMEsarenotthesameastheglobalNAMEsofthesamename).MemberMEMBER^module^nameMaplesyntax:module:-nameLength:3Thisstructurerepresentsamodulememberaccessinanexpression.MEMBERobjectstypicallydonotpersistwhenastatementissimplißed.Instead,theyarereplacedbytheactualmemberthattheyreferto(aninstanceofaNAME).ModuleDeßnitionMODDEFparam-local-option-export-stat-desc-:::seqseqseqseqseqseqglobal-lexical-mod-seqseqnameMaplesyntax: A.2InternalRepresentationsofDataTypes¯411modulemodName()descriptiondescSeq;locallocalSeq;exportexportSeq;globalglobalSeq;optionoptionSeq;statSeqendmoduleLength:10Theparam-seqpointstoanexpressionsequencedescribingtheformalparametersofthemodule.Currently,Mapledoesnotsupportparameter-izedmodules,sothisßeldalwayspointstothesequencecontainingjustaninstanceofthenamethismodule.Thelocal-seqpointstoanexpressionsequencelistingtheexplicitlyandimplicitlydeclaredlocalvariables.EachentryisaNAME.Theexplicitlydeclaredvariablesappearßrst.Withinthemodule,localsarereferredtobyLOCALstructures,thelocalvariablenumberbeingtheindexintothelocal-seq.Theexport-seqpointstoanexpressionsequencelistingtheexportedmodulemembers.EachentryisaNAME.Withinthemodule,exportsarereferredtobyLOCALstructures,thelocalvariablenumberbeingthenum-berofelementsinthelocal-seq,plustheindexintotheexport-seq.Theoption-seqpointstoanexpressionsequenceofoptionstothemodule(formodules,optionsarethesamethingasattributes).EachentryisaNAMEorEQUATIONspecifyinganoption.Typicaloptionsareload=...andunload=...Thestat-seqßeldpointstoasinglestatementorastatementsequence(STATSEQ).Ifthemodulehasanemptybody,thisisapointertoNULLinstead.Thedesc-seqßeldpointstoanexpressionsequenceofNAMEsorSTRINGs.ThesearemeanttoprovideabriefdescriptionofwhattheMod-uledoes,andaredisplayedevenwheninterface(verboseproc)islessthan2.Theglobal-seqßeldpointstoalistoftheexplicitlydeclaredglobalvariablesinthemodule(thosethatappearedintheglobalstatement).Thisinformationisneverusedatruntime,butitisusedwhensimplify-ingnestedmodulesandprocedurestodeterminethebindingoflexicallyscopedidentißers(forexample,anidentißerontheleftsideofanassign-mentinanestedprocedurecanbeglobalifitappearsintheglobalstatementofasurroundingcontext).Thisinformationisalsousedat 412¯AppendixA:InternalRepresentationandManipulationprintingtime,sothattheglobalstatementcontainsexactlytheglobalidentißersthatweredeclaredintheßrstplace.Thelexical-seqßeldpointstoanexpressionsequenceoflinkstoiden-tißersinthesurroundingscope,ifany.Thesequenceconsistsofpairsofpointers.TheßrstpointerofeachpairistothegloballyuniqueNAMEoftheidentißer;thisisneededatsimplißcationandprintingtime.Thesec-ondpointerisapointertoaLOCAL,PARAM,orLEXICALstructurewhichisunderstoodtoberelativetothesurroundingscope.Whenamoduledef-initionisevaluated,thelexical-seqisupdatedbyreplacingeachofthesecondpointerswithapointertotheactualobjectrepresented.Thenamepointersarenottouched,sothattheactualidentißernamesarestillavail-able.Thelexical-seqforamodulecontainsentriesforanysurrounding-scopeidentißersusedbythatmoduleorbyanyproceduresormodulescontainedwithinit.Themod-nameßeldpointstotheoptionalnameofthemodule.Ifamodulenamewasspecißedwhenthemodulewasdeclared,thenamewillappearthere.Ifnomodulenamewasspecißed,thisßeldwillcontainNULL.ModuleInstanceMODULE^exportseq^moddef^localseqMaplesyntax:noneLength:4Executingamoduledeßnition(MODDEF)resultsinamoduleinstance.Eachlocalorexportedmemberofthemoduleisinstantiatedandbe-longstothatinstanceofthemodule.Theexport-seqßeldpointstoanexpressionsequenceofnamesoftheinstantiatedexports(asopposedtotheglobalnames,asstoredinthemoduledeßnition).Themod-defßeldpointsbacktotheoriginalmoduledeßnition.Thelocal-seqßeldpointstoanexpressionsequenceofnamesoftheinstantiatedlocalvariablesofthemodule.IdentißerNAME^assigned^attribcharacterscharacters...exprexprMaplesyntax:nameLength:4ormore A.2InternalRepresentationsofDataTypes¯413Theassigned-exprßeldpointstotheassignedvalueofthename.Ifthenamehasnoassignedvalue,thisßeldisanullpointer(notapointertoNULL).Thenextßeldpointstoanexpressionsequenceofattributesofthename.Iftherearenoattributes,thisßeldpointstotheemptyexpressionsequence(NULL).Theremainingßeldscontainthecharactersmakingupthename,stored4or8permachineword(for32-bitand64-bitarchitecturesrespectively).Thelastcharacterisfollowedbyazero-byte.Anyunusedbytesinthelastmachinewordarealsozero.Themaximumlengthofanameis268,435,447characterson32-bitarchitecturesand34,359,738,351characterson64-bitarchitectures.NextStatementNEXTMaplesyntax:nextLength:1LogicalNOTNOT^exprMaplesyntax:notexprLength:2LogicalOROR^expr1^expr2Maplesyntax:expr1orexpr2Length:3ProcedureParameterwithinanExpressionPARAMintegerMaplesyntax:nameLength:2Thisindicatesaparameterwhenitappearswithinaprocedure.Theintegerisanindexintotheprocedureparam-seq.SeveralspecialPARAMstructuresexist: 414¯AppendixA:InternalRepresentationandManipulationPARAM0ThisrepresentstheMaplesymbolnargs,thenumberofargumentspassedwhentheprocedurewascalled.PARAM1ThisrepresentstheMaplesymbolargs,theentiresequenceofargumentspassedwhentheprocedurewascalled.PARAM2ThisrepresentstheMaplesymbolprocname,referringtothecurrentlyactiveprocedure.Atprocedureexecutiontime,theinteger(ifpositive)isusedasanindexintotheinternaldatastructureActvparamswhichispartoftheMapleprocedureactivationstack,andholdspointerstothevalues(whicharealsoMaplestructures,ofcourse)oftheactualparameterspassedtotheprocedure.PowerPOWER^expr1^expr2Maplesyntax:expr1^expr2Length:3Thisstructureisusedtorepresentapowerwhentheexponentisnotaninteger,rational,oràoating-pointvalue.Whentheexponentisnumeric,thePOWERstructureisconvertedtoalength3PRODstructure.ProcedureDeßnitionPROC^param^local^option^rem^stat^desc:::seqseqseqtableseqseq^global^lexicalseqseqMaplesyntax:proc(paramSeq)descriptiondescSeq; A.2InternalRepresentationsofDataTypes¯415locallocalSeq;exportexportSeq;globalglobalSeq;optionoptionSeq;statSeqendprocLength:9Theparam-seqpointstoanexpressionsequencedescribingtheformalparametersoftheprocedure.EachentryiseitheraNAMEoraDCOLON(whichinturncontainsaNAMEandanexpressionspecifyingatype).Withintheprocedure,parametersarereferredtobyPARAMstructures,theparameternumberbeingtheindexintotheparam-seq.Thelocal-seqpointstoanexpressionsequencelistingtheexplicitlyandimplicitlydeclaredlocalvariables.EachentryisaNAME.Theexplicitlydeclaredvariablesappearßrst.Withintheprocedure,localsarereferredtobyLOCALstructures,thelocalvariablenumberbeingtheindexintothelocal-seq.Theoption-seqßeldpointstoanexpressionsequenceofoptionstotheprocedure(forprocedures,optionsarethesamethingasattributes).EachentryisaNAMEorEQUATIONspecifyinganoption.Typicaloptionsareremember,operator,and`Copyright...`.Therem-tableßeldpointstoahashtablecontainingrememberedvaluesoftheprocedure.Entriesinthetableareindexedbytheprocedurearguments,andcontaintheresultingvalue.Ifthereisnoremembertable,thisßeldcontainsapointertoNULL,theemptyexpressionsequence.Thestat-seqßeldpointstoasinglestatementorastatementsequence(STATSEQ).Iftheprocedurehasanemptybody,thisisapointertoNULLinstead.Foreachprocedurethatisbuiltintothekernel,thereisawrapperPROCthathastheoptionbuiltininitsoption-seq,andasingleMapleintegerpointedtobyitsstat-seq.Theintegergivesthebuilt-infunctionnumber.Thedesc-seqßeldpointstoanexpressionsequenceofNAMEsorSTRINGs.Thesearemeanttoprovideabriefdescriptionofwhatthepro-ceduredoes,andaredisplayedevenwheninterface(verboseproc)islessthan2.Theglobal-seqßeldpointstoalistoftheexplicitlydeclaredglobalvariablesintheprocedure(thosethatappearedintheglobalstatement).Thisinformationisneverusedatruntime,butitisusedwhensimplifyingnestedprocedurestodeterminethebindingoflexicallyscopedidentißers.Forexample,anidentißerontheleftsideofanassignmentinanested 416¯AppendixA:InternalRepresentationandManipulationprocedurecanbeglobalifitappearsintheglobalstatementofasur-roundingprocedure.Thisinformationisalsousedatprocedureprintingtime,sothattheglobalstatementwillcontainexactlythesameglobalidentißersthatweredeclaredintheßrstplace.Thelexical-seqßeldpointstoanexpressionsequenceoflinkstoiden-tißersinthesurroundingscope,ifany.Thesequenceconsistsofpairsofpointers.TheßrstpointerofeachpairistothegloballyuniqueNAMEoftheidentißer;thisisneededatsimplißcationandprintingtime.Thesec-ondpointerisapointertoaLOCAL,PARAM,orLEXICALstructurewhichisunderstoodtoberelativetothesurroundingscope.Whenaprocedureisevaluated(notnecessarilycalled),thelexical-seqisupdatedbyreplacingeachofthesecondpointerswithapointertotheactualobjectrepre-sented.Thenamepointersarenottouched,sothattheactualidentißernamesarestillavailable.Thelexical-seqforaprocedurecontainsentriesforanysurrounding-scopeidentißersusedbythatprocedureorbyanyprocedurescontainedwithinit.Product,Quotient,PowerPROD^expr1^expon1^expr2^expon2......Maplesyntax:expr1^expon1*expr2^expon2...Length:2n+1Thisstructureisinterpretedaspairsoffactorsandtheirnumericex-ponents.Rationalorintegerexpressionstoanintegerpowerareexpanded.Ifthereisarationalconstantintheproduct,thisconstantismovedtotheßrstentrybythesimplißer.Asimplepower,suchasa^2,isrepresentedasaPRODstructure.Morecomplexpowersinvolvingnon-numericexponentsarerepresentedasPOWERstructures.RangeRANGE^expr1^expr2Maplesyntax:expr1..expr2Length:3RationalRATIONAL^integer^posinteger A.2InternalRepresentationsofDataTypes¯417Maplesyntax:1/2Length:3ThisstructureisoneofthebasicnumericobjectsinMaple.Notethatthisisnotadivisionoperation,butonlyarepresentationforrationalnumbers.Bothßeldsmustbeintegers(INTPOS,INTNEG,oranimmediateinteger)andthesecondmustbepositive.ReadStatementREAD^exprMaplesyntax:readexprLength:2TheMaplereadstatement.Theexpressionmustevaluatetoeitherastringorsymbol(STRINGorNAMEstructure),andspecißesthenameoftheßletoread.ReturnStatementRETURN^exprseqMaplesyntax:returnexpr1,expr2,...Length:2TheMaplereturnstatement.Theexpressionsequenceisevaluated,givingthevalue(s)toreturn.RectangularTableRTABLE^data^maple^ind^attribàagsnum-:::typefnelemsL1U1......LNUNP1P2Maplesyntax:rtable(...)Length:2n+pwherenisthenumberofdimensions(0to63),andpis0,1,or2,dependingonthenumberofPiparameters.Thedataßeldpointstoeitherablockofmemory(fordenseandNAG-sparseRTABLEs),ortoaHASHTABstructure(forMaple-sparseRTABLEs).ThedatablockiseitheranobjectoftypeBINARY,ormemoryallocated 418¯AppendixA:InternalRepresentationandManipulationdirectlyfromtheoperatingsystem'sstoragemanagerwhentheblockwouldbetoolargetobeallocatedasaMapledatastructure.IfthedatablockisaBINARYobject,thedatapointerpointstotheßrstdataword,nottotheobjectheader.Themaple-typeßeldpointstoaMaplestructurespecifyingthedatatypeoftheelementsofanRTABLEofMapleobjects.IftheRTABLEcon-tainshardwareobjects,themaple-typeßeldpointstotheMapleNAMEanything.Theind-fnpointerpointstoeitheranemptyexpressionsequence(NULL),oranexpressionsequencecontainingatleastoneindexingfunc-tionandapointertoacopyoftheRTABLEstructure.ThecopyoftheRTABLEisidenticaltotheoriginal,exceptthatitsind-fnßeldreferstoonelessindexingfunction(eitherNULL,oranotherexpressionsequencecontainingatleastoneindexingfunctionandapointertoanothercopyoftheRTABLEwithonelessindexingfunctionagain).Theattribpointerpointstoanexpressionsequenceofzeroormorearbitraryattributes,whichcanbesetbythesetattributefunction,andqueriedbyattributes.Theàagsßeldisabitßeldcontainingthefollowingsubßelds.¯datatype-5bits-indicatesoneofseveralhardwaredatatypesorthataMapledatatype(asspecißedbymaple-type)isbeingused.¯subtype-2bits-indicatesiftheRTABLEisanArray,Matrix,orVector.¯storage-4bits-describesthestoragelayout(e.g.sparse,uppertri-angular,etc.)¯order-1bit-indicatesCorFortranorderingofRTABLEelements.¯readonly-1bit-indicatestheRTABLEistoberead-onlyoncecreated.¯foreign-1bit-indicatesthatthespacepointedtobythedataßelddoesnotbelongtoMaple,soMapleshouldnotgarbagecollectit.¯eval-1bit-indicatesiffullevaluationshouldoccuronlookup.Formoreinformation,referto?rtable_eval.¯literal-1bit-optimizationforinternaltypecheckingofdatacon-tainedinanRTABLE.¯numberofdimensions-6bits-thenumberofdimensionsoftheRTABLE,from0to63. A.2InternalRepresentationsofDataTypes¯419Thenum-elemsßeldindicatesthetotalnumberofelementsofstor-ageallocatedforthedata.ForaMaple-sparseRTABLE,num-elemsisnotused.ForaNAG-sparseRTABLE,num-elemsspecißesthenumberofelementscurrentlyallocated,someofwhichmightnotbeinuse.Theremainingßeldsspecifytheupperandlowerboundsofeachdi-mension,andarestoreddirectlyassignedmachineintegers.Thelimitsonboundsare2;147;483;648to2;147;483;647for32-bitarchitecturesand9;223;372;036;854;775;808to9;223;372;036;854;775;807for64-bitarchitectures.Thetotalnumberofelementscannotexceedtheupperlimitnumberseither.SaveStatementSAVE^exprseqMaplesyntax:saveexpr,expr,...Length:2TheMaplesavestatement.Theexpressionsequencegivesalistofnamesofobjectstosave,andeitheraßlenameorrepositorynameinwhichtosavethem.TheßleorrepositorynamecanbespecißedasaNAMEorSTRING.SeriesSERIES^expr1^expr2integer^expr3integer......Maplesyntax:noneLength:2n+2ThisistheinternalrepresentationofaseriesinMaple.Thereisnoinputsyntaxforaseries;onecanonlyarisefromacomputation.Theßrstexpressionhasthegeneralformx-a,wherexdenotesthevariableoftheseriesusedtodothatexpansion,andadenotesthepointofexpansion.Theremainingentriesareinterpretedaspairsofcoeácientsandexpo-nents.Theexponentsareintegers,notpointerstointegersorimmediateintegers.Theexponentsappearinincreasingorder.AcoeácientO(1)(afunctioncalltothefunctionO,withparameter1)isinterpretedspeciallybyMapleasanorderterm.SetSET^exprseq^attribexpr 420¯AppendixA:InternalRepresentationandManipulationMaplesyntax:fexpr;expr;:::gLength:2(or3withattributes)Theentriesintheset'sexpressionsequencearesortedinorderofincreasingmemoryaddress.Thisisanarbitrarybutconsistentorder,necessaryforeácientlyworkingwithsets.StatementSequenceSTATSEQ^stat1^stat2...Maplesyntax:stat1;stat2;...Length:3ormoreThisstructurerepresentsasequenceoftwoormorestatements,andcanbeusedwhereverasinglestatement(forexample,ASSIGN,IF,FOR)canappear.Astatementsequence,containingonlyasinglestatement,isreplacedbythatstatement.Astatementsequencecontainingnostate-mentsisreplacedbytheemptyexpressionsequence(NULL).NestedSTATSEQstructuresareàattened.Alloftheabovetransformationsaremadebythesimplißer.StopMapleSTOPMaplesyntax:quit,done,orstopLength:1StringSTRINGreserved^attribexprcharacterscharacters...Maplesyntax:"Thisisastring"Length:4ormoreAMaplestringisstructurallysimilartoaNAME,exceptthatithasnoassigned-valueßeld.Theattrib-exprßeldpointstoanexpressionsequenceofattributesofthestring.Iftherearenoattributes,thisßeldpointstotheemptyexpressionsequence(NULL).Theremainingßeldscontainthecharactersmakingupthestring,stored4or8permachineword(for32-bitand64-bitarchitecturesrespectively).Thelastcharacter A.2InternalRepresentationsofDataTypes¯421isfollowedbyazero-byte.Anyunusedbytesinthelastmachinewordarealsozero.Themaximumlengthofastringis268;435;447characterson32-bitarchitecturesand34;359;738;351characterson64-bitarchitectures.Sum,DiÞerenceSUM^expr1^factor1^expr2^factor2......Maplesyntax:expr1*factor1+expr2*factor2...Length:2n+1Thisstructureisinterpretedaspairsofexpressionsandtheirnumericfactors.Rationalorintegerexpressionswithanintegerfactorareex-pandedandthefactorreplacedwith1.Ifthereisarationalconstantinthesum,thisconstantismovedtotheßrstentrybythesimplißer.Simpleproducts,suchasa*2,arerepresentedasSUMs.Morecomplexproductsinvolvingnon-numericfactorsarerepresentedasPRODstructures.TableTABLE^indexfunc^arraybounds^hashtabMaplesyntax:N/ALength:4Thisisageneraltabletype,ascreatedbythetableandarrayfunc-tionsinMaple.Theindex-funcwillpointtoeitheraNAMEoraPROC.Forgeneraltables,thearray-boundsßeldpointstotheemptyexpressionsequence(NULL).Forarrays(nottobeconfusedwithArrays,whichareimplementedasRTABLEs),thearray-boundsßeldreferstoanexpressionsequenceofRANGEsofintegers.Thehash-tabßeldpointstoaHASHTABstructurecontainingtheelements.TableReferenceTABLEREF^name^exprseq^attribexprMaplesyntax:name[expr]Length:3(or4withattributes)Thisdatastructurerepresentsatablereference,orindexedname.ThenameentryfollowsthesamerulesasforASSIGN,oritmaybeaTABLE 422¯AppendixA:InternalRepresentationandManipulationorMODULEstructure.(TheparserwillnotgenerateaTABLEREFwithaTABLEstructureforthenameentry,butthiscanariseinternally.)Theexpressionsequencecontainstheindices.TryStatementTRY^try^catch^catch......^finalstatstrstatstatseqseqseqMaplesyntax:trytryStatcatch"catchStr":catchStat...ßnallyßnalStat;endtryLength:3ormoreThisstructurerepresentsatrystatement,andcanhaveanarbitrarylength,dependingonhowmanycatchblockstherearewithinit,andwhetherornotithasafinallyblock.Thecatch-strspointtothecatchstringofthecorrespondingcatchblock.Ifnocatchstringwasspecißed,thecatch-strpointstoNULL.Emptycatch-stat-seqsarealsorepresentedbypointerstoNULL,asisanempty(butpresent)finallyblock.TheactualinternaltagusedfortheTRYstructureisMTRY,topreventcollisionwithamacrodeßnedbysomeCexceptionhandlinglibraries.UnevaluatedExpressionUNEVAL^exprMaplesyntax:'expr'Length:2UseStatementUSE^bindings^statseqMapleSyntax: A.2InternalRepresentationsofDataTypes¯423usebindingsinstatseqenduseLength:3Thebindingscomponentpointstoanexpressionsequenceofequa-tionswhoseleftsidesaresymbols,andthestatseqcomponentpointstoasequenceofstatementsthatformthebodyoftheusestatement.Therightsidesofthebindingequationscanbearbitaryexpressions.Theusestatementintroducesanewbindingcontourandbindsthenamesthatappearontheleftsideoftheequationsinbindings.Forcon-venience,oninput,amodule`m'canappearamongthebindings,andistreatedasifitwerethesequencee1=m:-e1,e2=m:-e2,...,wheretheeiaretheexportsof`m'.Withinthesequencestatseqofstatements,thesymbolsappearingontheleftsideoftheequationsinbindingsareboundtothecorrespondingrightsides.Thepreviousbindingsofthosesymbolsarerestoreduponexitfromtheusestatement.Bindingsarere-solvedduringautomaticsimplißcation.LogicalXORXOR^expr1^expr2Maplesyntax:expr1xorexpr2Length:3PolynomialswithIntegerCoeácientsmodulonZPPOLY^indetmodcoef0coef1:::ZPPOLY^indet_seqmod^zppoly0^zppoly1:::MapleSyntax:modp1(ConvertIn(expr,indet),n);MapleSyntax:modp2(ConvertIn(expr,indet1,indet2),n);Length:degree(zppoly)+2(forthezeropolynomial)Length:degree(zppoly)+3(otherwise)Thisistheinternalrepresentationofunivariateandbivariatepolyno-mialsmodulosomeinteger.Themodp1()andmodp2()frontendsprovideasuiteoffunctionstoworkonthisdatastructureoperatinginthedomain 424¯AppendixA:InternalRepresentationandManipulationofpolynomialsinoneortwovariableswithintegercoeácientsmodulon,writtenZn[x]orZn[x;y],respectively.indet_seqisanexpressionse-quenceoftheindeterminatesofthepolynomial(x),or(x,y).modistheintegermodulusoftheintegerdomain.Inaunivariatepolynomialthecoeácientsarestoredinthefollowingorder.(coef0*indet^0+coef1*indet^1+...+coefi*indet^i)modnAbivariatepolynomialcontainspointerstounivariateZPPOLYstruc-turesrepresentingthecoeácientsoftheßrstindeterminate.(coef0(indet2)*indet1^0+coef1(indet2)*indet1^1+...)modnwhereeachcoefiisaunivariatepolynomialinindet1modn.Allcoeácientsarestoredincludingzerocoeácients.Theleadingco-eácientisalwaysnon-zero.A.3TheUseofHashinginMapleAnimportantfactorinachievingtheoveralleácientperformanceofMapleistheuseofhash-table-basedalgorithmsforcriticalfunctions.Tablesareusedinbothsimplißcationandevaluation,aswellasforlesscriticalfunctions.Forsimplißcation,Maplekeepsasinglecopyofeachexpression,orsubexpression,duringasession.Thisisdonebykeepingallobjectsinatable.Inprocedures,therememberoptionspecißesthattheresultofeachcomputationoftheprocedureistobestoredinaremembertableassociatedwiththeprocedure.Finally,tablesareavailabletotheuserasoneoftheMapledatatypes.Alltablesearchingisdonebyhashing.Thearetwotypesofhashtables,basicanddynamic.BasichashtablesareusedformostMaplehashing.However,basichashtablesareineácientwhenaverylargenum-berofelementsisstored.Dynamichashtablesaredesignedtoworkwithalargenumberofelements.Thetwotypesofhashtablesarenotexposed.Whenabasichashtablebecomesfull,itisautomaticallyconvertedtoadynamichashtable.BasicHashTablesThealgorithmusedforthebasichashtablesisdirectchaining,exceptthatthechainsaredynamicvectorsinsteadofthetypicallinkedlists.ThetwodatastructuresusedtoimplementhashtablesareHASHTABandHASH. A.3TheUseofHashinginMaple¯425HashTableHASHTAB^hashchain1^hashchain2...Maplesyntax:noneLength:2n+1ThisisaninternaldatastructurewithnoMaplesyntaxequivalent.ItisusedintherepresentationoftableswithinMaple.Eachentrypointstoahashchain(aHASHstructure),orisanullpointerifnoentryhasbeencreatedinthatbucketyet.ThesizeofaHASHTABstructuredependsonthetypeoftableandtheplatform,butisalwaysapowerof2plusone.HashChainHASHkey^expr1key^expr2......Maplesyntax:noneLength:2n+1Eachtableelementisstoredasapairofconsecutiveentriesinahashbucketvector.Theßrstentryofthispairisthehashkey,andthesecondisapointertoastoredvalue.Insomecases(forexample,procedureremembertables,userdeßnedtables),thekeyisalsoapointer.Inothercases,thekeyisahashedvalue(forexample,thesimplißcationtable,thesymboltable).Thekeycannothavethevaluezero(orthenullpointer)sincethisisusedtoindicatethebottomofthebucket.DynamicHashTablesTheMapledynamichashtableisacomplexdatastructure.Acompletedescriptionofthealgorithmsisnotgiven.Thefollowingisabriefdescrip-tionofthestructure.Insteadofusingaàat,ßxedlengthdirectory,Mapledynamichashtablesuseatreestructurewithcontiguousbitsfromthehashkeytoselectachild.Achildofadirectorycanbeasubdirectoryorahashchain.Forexample,atop-leveldirectorymayusetheßrst10bitstoindex1024children.Oneofitschildrenmaybeadirectorythatuses,say,thenext8bitsofthekeytoindex256children.Ahashchaininadynamictablestoreselementsusingkeyvaluepairs(inthesamewaythatahashchaindoesinabasichashtable).Theßrstnbitsofthekeysinahashchainareidentical,wherenisthenumberofbitsrequiredtolocatethehashchain.Theremainingbitsarearbitrary.Usingtheexampleinthepreviousparagraph,theelementsofahashchain 426¯AppendixA:InternalRepresentationandManipulationthatisachildofthedirectorywith256childrenhavehashkeysthatareidenticalintheßrst18bits.Whenahashchainwithunusedbitsoveràows,itissplitintotwo.Thismayrequirecreatingasubdirectorywithtwochildrenordoublingthesizeofthehashchain'sparentdirectory.Ineithercase,anotherbitfromthehashkeyisintroducedforindexing.Thisbitisusedtodividetheelementsoftheoldchainintothetwonewchains.Ifthehashchainhasnounusedbitsforindexing,thechaingrowsasneeded.Thisgrowthoccursonlyifmanyelementsareinsertedwithidenticalhashkeys.TheSimplißcationTableByfar,themostimportanttablemaintainedbytheMaplekernelisthesimplißcationtable.Allsimplißedexpressionsandsubexpressionsarestoredinthesimplißcationtable.Themainpurposeofthistableistoen-surethatsimplißedexpressionshaveauniqueinstanceinmemory.Everyexpression,whichisenteredintoMapleorgeneratedinternally,ischeckedagainstthesimplißcationtableand,iffound,thenewexpressionisdis-cardedandtheoldoneisused.Thistaskisdonebythesimplißerwhichrecursivelysimplißes(appliesallthebasicsimplißcationrules)andchecksagainstthetable.Garbagecollectiondeletestheentriesinthesimplißca-tiontablethatcannotbereachedfromaglobalnameorfromalivelocalvariable.Thetaskofcheckingforequivalentexpressionswithinthousandsofsubexpressionswouldnotbefeasibleifitwerenotdonewiththeaidofhashing.Everyexpressionisenteredinthesimplißcationtableusingitssignatureasakey.Thesignatureofanexpressionisahashingfunctionitself,withoneveryimportantattribute:signaturesoftriviallyequivalentexpressionsareequal.Forexample,thesignaturesoftheexpressionsa+b+candc+a+bareidentical;thesignaturesofa£bandb£aarealsoidentical.Iftwoexpressions'signaturesdisagreethentheexpressionscannotbeequalatthebasiclevelofsimplißcation.Searchingforanexpressioninthesimplißcationtableisdoneby:¯Simplifyingrecursivelyallofitscomponents¯Applyingthebasicsimplißcationrules¯ComputingitssignatureandsearchingforthissignatureinthetableIfthesignatureisfound,thenafullcomparisonisperformed(tak-ingintoaccountthatadditionsandmultiplicationsarecommutative)toverifythatitisthesameexpression.Iftheexpressionisfound,theone A.3TheUseofHashinginMaple¯427inthetableisusedandthesearchedoneisdiscarded.Afullcompari-sonofexpressionshastobeperformedonlywhenthereisacollisionofsignatures.Sincesimplißedexpressionsareguaranteedtohaveauniqueoccur-rence,itispossibletotestforequalityofsimplißedexpressionsusingasinglepointercomparison.Uniquerepresentationofidenticalexpressionsisacrucialingredienttotheeáciencyoftables,hencealsotherememberoption.Also,sincetherelativeorderofobjectsispreservedduringgarbagecollection,thismeansthatsequencesofobjectscanbeorderedbyma-chineaddress.Forexample,setsinMaplearerepresentedthisway.Thesetoperations,suchasunionorintersection,canbedoneinlineartimebymergingsortedsequences.Sortingbymachineaddressisalsoavailabletotheuserwiththesortcommand.TheNameTableThesimplestuseofhashingintheMaplekernelisthenametable.Thisisasymboltableforallglobalnames.Eachkeyiscomputedfromthename'scharacterstringandtheentryisapointertothedatastructureforthename.Thenametableisusedtolocateglobalnamesformedbythelexicalscannerorbynameconcatenation.Itisalsousedbyfunctionsthatperformoperationsonallglobalnames.Theseoperationsinclude:1.Markingforgarbagecollection2.SavingaMaplesessionenvironmentinaßle3.Maplefunctionsanamesandunameswhichreturnallassignedandunassignedglobalnames,respectivelyRememberTablesAremembertableisahashtableinwhichtheargument(s)toaprocedurecallarestoredasthetableindex,andtheresultoftheprocedurecallisstoredasthetablevalue.BecauseasimplißedexpressioninMaplehasauniqueinstanceinmemory,theaddressoftheargumentscanbeusedasthehashfunction.Hence,searchingaremembertableisveryfast.Thereareseveralkernelfunctionswhichuseremembertablesin-cluding,evalf,series,divide,normal,expand,diff,readlib,andfrontend.Thefunctionsevalf,series,anddividearehandledinter-nallyinaspecialwayforthefollowingreasons:¯evalfandseriesneedtostoresomeadditionalenvironmentinfor-mation('Digits'forevalfand'Order'forseries).Consequently, 428¯AppendixA:InternalRepresentationandManipulationtheentriesfortheseareextendedwiththeprecisioninformation.Ifaresultisrequestedwiththesameorlessprecisionthanwhatisstoredinthetable,itisretrievedandrounded.Ifaresultisproducedwithmoreprecisionthanwhatisstored,itisreplacedinthetable.¯evalfremembersonlyfunctioncalls(thisincludesnamedconstants);itdoesnotremembertheresultsofarithmeticoperations.¯Ifadivisionoperationsucceedsandthedivisorisanontrivialpoly-nomial,thedividefunctionstoresthequotientinitsremembertable.Otherwisenothingisstoredintheremembertable.Ifoptionrememberisspecißedtogetherwithoptionsystem,atgarbagecollectiontimetheremembertableentrieswhichrefertoex-pressionsnolongerinuseelsewhereinthesystemareremoved.Thisprovidesarelativelyeácientuseofrememberingthatdoesnotwastestorageforexpressionsthathavedisappearedfromtheexpressionspace.MapleLanguageArraysandTablesTablesandarraysareprovidedasdatatypesintheMaplelanguageviathetableandarray1functions.Anarrayisatableforwhichthecom-ponentindicesmustbeintegerslyingwithinspecißedbounds.TablesandarraysareimplementedusingtheMapleinternalhashtables.Becauseofthis,sparsearraysareequallyaseácientasdensearrays.Atableobjectconsistsofthefollowing.1.Indexbounds(forarraysonly)2.Ahashtableofcomponents3.AnindexingfunctionThecomponentsofatableTareaccessedusingasubscriptsyntax(forexample,T[a,b*cos(x)]).Sinceasimplißedexpressionisguaranteedtohaveauniqueinstanceinmemory,theaddressofthesimplißedindexisusedasthehashkeyforacomponent.Ifnocomponentexistsforagivenindex,thentheindexedexpressionisreturned.Thesemanticsofindexingintoatablearedescribedbyitsindexingfunction.Asidefromthedefault,generalindexing,someindexingfunc-tionsareprovidedbytheMaplekernel.Otherindexingfunctionsareloadedfromthelibraryoraresuppliedbytheuser.1Note:Unlikethearraycommand,theArraycommandcreatesarectangulartable,whichisdescribedinthefollowingsubsection. A.4Portability¯429TableA.2SelectSupportedMaplePlatformsHardwareOperatingSystemIntelPentiumBasedPCMicrosoftWindowsLinuxApplePowerMacintoshMacOSSunSPARCSunOS/SolarisSiliconGraphicsIrisIRIXHewlettPackardPA-RISCHP-UXIBMRS/6000AIXDECAlphaDigitalUNIX/CompaqTru64MapleLanguageRectangularTablesRectangulartables(asimplementedbytheRTABLEstructure),canuseavarietyofstorageformats.Oneformat,Maple-sparse,isidenticaltothatusedintablesandarrays,namelyahashtable.Thereisanothersparseformat,NAG-sparse,whichusesonevectorforeachdimensiontorecordindices,andathirdvectortorecordthevaluesoftheentries.ThemajorityofRTABLEstorageformatsaredense,thesimplestbeingtherectangular.Otherdenseformatsincludeupper-triangularandband,wherestorageisallocatedonlyfortheuppertriangleorabandofelementsrespectively.Totheuser,rectangulartablesmanifestthemselvesasobjectsoftypeArray,Matrix,Vector[row],andVector[column].NotethatanArrayisnotthesamethingasanarray.Fordeßnitions,referto?Arrayand?array.A.4PortabilityTheMaplekernelandthecommand-lineinterfacearenottiedtoanyoneoperatingsystemorhardwarearchitecture.TheMaplekernelisdesignedtobeportabletoanysystemwhichsupportsaCcompiler,aàataddressspace,anda32-bitor64-bitwordsize.TableA.2listssomeplatformsonwhichMapleissupported(refertotheinstallationinstructionsforalistofcurrentlysupportedoperatingsystemversions).Themajorityofthesourcecodecomprisingthekernelisthesameacrossallplatforms.Extensiveuseofmacrosandconditionalcompila-tiontakecareofplatformdependencies,suchaswordsize,byteordering, 430¯AppendixA:InternalRepresentationandManipulationstoragealignmentrequirements,diÞerencesinhardwareàoatingpointsupport,andsometimes,Ccompilerbugs.TheMaplelibraryisinterpretedbytheMaplekernel.Therefore,otherthanissuessuchasmaximumobjectsize,itiscompletelyindependentoftheunderlyingarchitecture.TheMaplegraphicaluserinterfacehastwoversions,thestandardworksheetandtheclassicworksheet(notavailableonMacintosh).ThestandardworksheetisimplementedinJava,whichisplatformindepen-dent.TheclassicworksheetisimplementedinCandC++,andmakesuseofaplatformindependentuserinterfaceclasslibrarytoachieveportabil-ity.TheMapletUserInterfaceCustomizationSystem(availableinbothworksheetversions)iswritteninJavawithsomenativelibraries.TheJavaportionisidenticalonallplatforms. Index%,204backdrops,304&,33BesselJ,232Beta,226accuracy,223,225,229,297binary,401algebraicfunctions,399BINARYinternaldatastructure,anames,427401and,401bindinglist,105ANDinternaldatastructure,401break,48,401animations,301BREAKinternaldatastructure,datastructuresof,301401staticformof,302buÞeredßles,190withbackdrops,304àushing,216withdisplay,303,306appendto,217,383,384Cargs,18,48notes,221arguments,251callbyreference,340notpassed,341ANYTHING,340sequenceof,18CALL_ONLY,340Array,234RETURN_ONLY,340array,428callbackfunction,384Arrays,232Cartesianproductarrays,22,214,232sequenceofsets,22andhardwareàoats,232CATENATEinternaldatastruc-hardwareàoating-point,234ture,402initializing,23classicworksheet,2sorting,8close,194assign,20CodeGeneration,319Û330ASSIGNinternaldatastructure,callingfunctions,320401Definecommand,327assignmentextensibility,324Û330multiple,288intermediatecode,323assignmentstatements,401intermediateform,324assume,21,37languagedeßnition,327assumptions,21languagedeßnitionmodel,329atomic,60Printermodule,325audience,1translationprocess,321automaticsimplißcation,20usinganewlanguage,330431 432¯Indexcoeff,399meshestopolygons,273,284,COLOR,308315HUE,259stringstobytes,218POLYGONS,308stringstoexpressions,30,218RGB,262toformattedstrings,220color,255,308toPLOToptions,267,286adding,312,315CopyFile,198,211colortables,309,310Copyright,57grayscale,311coverage,87HUE,310customerfeedback,3columnsprinting,187,215datareading,204fromotherapplications,185command-lineversion,2readingfromßles,187commandssavingtoßle,186longnamesof,252datastructures,39compiledcodeforanimations,301usinginMaple,330Û374forplotting,254Û256,262usingMaplein,374Û391internal,seeinternaldatastruc-Complex,402turesCOMPLEXinternaldatastruc-manipulation,399ture,402DCOLONinternaldatastructure,complexnumbers,236403imaginaryunit,35DEBUGinternaldatastructure,computing403areas,95debugopts,87circumferences,95define_external,334concatenation,70,402description,50constantsdiff,70,399deßningnumeric,238extending,39constructors,108Digits,12,224,235,237CONTROLinternaldatastruc-evalhf,228ture,402digits,numberof,224control,àowof,399displayconversions,342insequence,303convertingdivide,399expressionstostrings,275,done,381,420310dsolve,14gridstopolygons,315eáciency,22,223,229,234,239,integerstostring,218297,298 Index¯433embedding2-Dgraphicsin3-D,vs.localvariables,118268,269,277exports,52encapsulation,43,66expressionsend,47convertingfromstrings,30endmodule,47readingfromterminal,28enumeratedtypes,339EXPSEQinternaldatastructure,equality,403404EQUATIONinternaldatastruc-extendingture,403commands,39error,403convert,289ERRORinternaldatastructure,diff,39403evalf,238errorssimplify,40catastrophiccancellation,238,type,31241extensibility,66roundoÞ,236extensionmechanism,70eval,16,31externalcalling,330Û374evalb,20,399argumentpassingconventions,evalf,12,224,227,399,427338extending,238arraydataformats,337newconstants,238customwrapper,331,350newfunctions,240directcalling,331,332evalhf,227,399Maple-generatedwrapper,331,arrays,232Û234338Digits,228otherdataformats,337structuredobjects,232,233scalardataformats,336var,234stringdataformats,337evaln,399structureddataformats,336evaluatingtypes,335parsedstrings,218evaluationfclose,194full,16feof,195numerical,224fflush,216usinghardwareàoats,227ßledescriptors,192,194usingsoftwareàoats,224filepos,194evaluators,398ßles,190event,numeric,236appendingto,193expand,399,400binary,190export,44,52buÞered,190,216exportedlocalvariables,45,52closing,187,194exportedvariablescreating,187,193 434¯Indexcurrentpositionin,194limitations,235default,191,197modelsof,235deleting,196precision,235descriptorsof,192,194representationofzero,236detectingendof,195roundoÞerrors,236àushing,216software,224,235,297lengthof,195zero,236opening,187,192,193àowofcontrol,399printingbytesto,210fopen,193printingcolumnsto,187,215fopenCfunction,383,384printingformatted,186,211forloop,405printingstringsto,210FORinternaldatastructure,405RAW,190foreigndata,405READ,191FOREIGNinternaldatastruc-readingbytesfrom,197ture,405readingcolumnsfrom,189,formatstrings,187,189,199,211204fprintf,186,211readingformatted,189free,389readinglinesfrom,197fremove,196readingremainderof,198fscanf,189,198redirectingdefault,217functioncall,406removing,196FUNCTIONinternaldatastruc-scanning,189,198ture,406statusof,195functiontable,65STREAM,190functionsterminal,191algebraic,399text,190deßningnumeric,240truncating,193numericandsymbolic,242unbuÞered,190WRITE,191garbagecollection,401,405,406,FLOATinternaldatastructure,426,428404GARBAGEinternaldatastruc-àoating-pointnumbers,223,404ture,406n-digitmachine,224genericprogramming,117,124,accuracyof,225125,129andnewconstants,238genericprograms,44andnewfunctions,240GettingStartedGuide,2basesof,225global,51digitsof,224,225globaloptions,258,272hardware,227,236,297globalvariables,21hardwareorsoftware,229interactivesession,20 Index¯435referencing,51signpreservation,236graphicalinterfaceimmediateinteger,408versions,2immutablestate,110graphics,programmingwith,245implementationsGRID,255vs.interfaces,118convertingtopolygons,273implicitscopingrules,58gridpoints,291,296implies,407group,78IMPLIESinternaldatastructure,407Hamiltonians,34,35,40indets,399associativityof,40inequality,407inverseof,37INEQUATinternaldatastruc-hardwareàoat,406ture,407hardwareàoating-pointnumbers,inßniterecursion,35227,235,236,297infinity,236andarrays,232inßx,34andstructuredobjects,232infolevelbaseof,228all,41digitsof,228,232simplify,41has,399inputHASHinternaldatastructure,formatted,198425fromaßle,27hashtables,424fromtheterminal,27,28basic,424interactive,27dynamic,425promptingfor,27hashing,427Int,227HASHTABinternaldatastruc-int,227ture,425integers,408help,386immediate,408hfarray,214negative,408structuredobjects,232positive,408HFLOATinternaldatastructure,integration406numerical,225,227histograms,258,263interactivehistory,383input,27session,20I,35interface,35,206IEEEstandard,224,236indentamount,208if,407labelling,208IFinternaldatastructure,407labelwidth,208imaginarypartprettyprint,208 436¯Indexscreenwidth,207,208NEXT,413verboseproc,208NOT,413interfaces,118OR,413manipulation,119PARAM,413vs.implementations,118POWER,414internaldatastructures,400PROC,414AND,401PROD,416ASSIGN,401RANGE,416BINARY,401RATIONAL,416BREAK,401READ,417CATENATE,402RETURN,417COMPLEX,402RTABLE,417,429CONTROL,402SAVE,419DCOLON,403SERIES,419DEBUG,403SET,420EQUATION,403STATSEQ,420ERROR,403STOP,420EXPSEQ,404STRING,420FLOAT,404SUM,421FOR,405TABLE,421,428FOREIGN,405TABLEREF,421FUNCTION,406TRY,422GARBAGE,406UNEVAL,422HASH,425USE,422HASHTAB,425XOR,423HFLOAT,406ZPPOLY,423IF,407internalfunctions,398IMPLIES,407internalorganization,397INEQUAT,407internalrepresentationsofdataINTNEG,408types,400INTPOS,408INTNEGinternaldatastructure,length,400408LESSEQ,409INTPOSinternaldatastructure,LESSTHAN,409408LEXICAL,409IntroductoryProgrammingGuide,LIST,4102LOCAL,410iostatus,195MEMBER,410MODDEF,410kernel,398MODULE,412supportedplatforms,429NAME,412Kleinbottle,284 Index¯437last_name_eval,60logicalAND,401LearningGuide,2logicalIMPLIES,407length,399logicalXOR,423LESSEQinternaldatastructure,lprint,206409LESSTHANinternaldatastruc-MakeIteration,15ture,409MakeZn,59LEXICALinternaldatastruc-mallocCfunction,389ture,409Mandelbrotset,248lexicalscoping,6manualrules,7,58audience,1lexicallyscopedvariable,409conventions,3libmaple.dylibßle,390set,2libmaplec.aßle,390map,399libmaplec.dylibßle,390inprocedures,6libmaplec.slßle,390Maplelibmaplec.soßle,390usingCompiledCodein,330Ûlibname,386374library,398usingincompiledcode,374ÛLimit,227391limit,227MapleGettingStartedGuide,limits2numerical,227MapleIntroductoryProgram-LinearAlgebra,78mingGuide,2LinkedList,80MapleLearningGuide,2LISTinternaldatastructure,410Maple_floats,236lists,410maplec.dllßle,389,390appendingelementsto,250maplec.hßle,376,377,380,386load,57maplec.libßle,389,390local,52MapletLOCALinternaldatastructure,applications,2410UserInterfaceCustomizationlocaloptions,258,271,286System,2,430localvariables,26,410Mapletspackage,398escaped,19mathengine,398exported,45,52MATLAB,243invokingprocedures,19Matrices,214outsidetheirprocedure,19reading,215referencing,52writing,215returning,22member,56,100vs.exportedvariables,118 438¯IndexMEMBERinternaldatastruc-mpltable.hßle,375ture,410multipleassignments,288MEMBERobjects,410memoryusage,389name,413MESH,256NAMEinternaldatastructure,convertingtopolygons,273412messages,110nametable,427microwavecircuitanalysis,280namedmodules,49MODDEFinternaldatastruc-namesture,410withatilde,21modelingobjects,108nargs,48module,44,47,60,410negativeinteger,408MODULEinternaldatastruc-nestedmodules,58ture,412nestedprocedures,5,17moduledefinition,60neutraloperators,33modules,43deßning,34andtypes,60inßx,34declarations,50newlinecharacter,190deßnition,44,47,51Newton'smethod,14,230deßnitionsyntax,47next,48,413description,50NEXTinternaldatastructure,errorreporting,50413exports,110nops,23implicitscopingrules,58not,413lexicalscopingrules,58NOTinternaldatastructure,413manipulation,87numericestimate,14membersof,52numericevent,236membershiptests,56numericalintegration,225,227named,49numericallimits,227nested,58numericalprogramming,223options,57numericalsums,227parameterized,59numerics,236referencingglobalvariables,objects,44,10851modeling,108referencinglocalvariables,52omexample.cßle,390referringto,48op,399typesofvariablesin,118open,193usefornewpackages,78OpenMaple,374Û391versusprocedures,44Û46ALGEBdatatype,375,378moemapi.hßle,381basicAPIfunctions,376Û379mplshlib.hßle,375 Index¯439call-backfunctions,380Û386sampleprogram,390Û391callBackCallBackfunction,StartMapleAPIfunction,376,380,384,386377,379,380,387datatypes,375statusCallBackfunction,380ÛerrorCallBackfunction,378,382380Û384StopMapleAPIfunction,376,EvalMapleStatementAPIfunc-379tion,376,377,379,382streamCallBackfunction,380,EXT_DECLmodißer,375385ßlestructure,389Û390streams,384Û387MacOSX,390advantages,386UNIX,390technicalissues,389Windows,390textCallBackfunction,380,FLOAT32datatype,375382Û384,386FLOAT64datatype,375usingMicrosoftVisualC/CC++,helpdatabase,386Û389375retrievingahelppage,386operatorrebinding,106settingthepath,386operators,33INTEGER16datatype,375*,35INTEGER32datatype,375custom,33INTEGER64datatype,375neutral,33INTEGER8datatype,375optionsinterfaceoverview,375convertingtoPLOToptions,M_BOOLdatatype,375267,286M_DECLmodißer,375,380global,258,272M_INTdatatype,375local,258,271,286MapleHelpfunction,386,389processing,252MapleLibNamefunction,386typeequalsnumeric,14MapleRaiseErrorAPIfunc-or,413tion,378ORinternaldatastructure,413MCallBackfunction,380organizationMCallBackVectorfunction,380internal,397MKernelVector,380outputqueryInterruptfunction,380,controlling,206384rounding,187readLineCallBackfunction,380,383,385package,57redirectCallBackfunction,packages,43,78380,383exports,78RestartMapleAPIfunction,inthestandardlibrary,78376,379table-based,78 440¯Indexusemodulesfor,78convertingfromgridsormeshes,usinginteractively,79273PARAMinternaldatastructure,convex,269,287413portablility,429parameterspositiveinteger,408sequenceof,18POWERinternaldatastructure,withinprocedures,413414parse,30,218powers,414,416partition,27precision,238partitioning,8àoating-pointnumbers,235pipes,192preface,1plotdrivers,256print,207,232,385plotting,246,249printf,211,381,385animations,301printing,206,207AXESSTYLE,262bytes,210COLOR,258columns,215colors,275formatted,186,187,211CURVES,257,258,262strangeexpressions,19datastructures,254Û256,259,strings,210262toßles,186formulí,246,252printlevel,381functions,247,252,288priorityqueue,111GRID,264proc,44MESH,265PROCinternaldatastructure,non-numericvalues,257,287,414291,297proceduresnumericalapproximations,224asreturnedobjects,22options,248,249callformats,340POINTS,258deßning,414POLYGONS,258,262,269dispatching,99SCALING,269executiondetails,41STYLE,263nested,5,9,17TEXT,258,275parameterswithin,413undeßnedvalues,287,291,passinginformation,22297passinginputto,27withplottools,273thatreturnprocedures,14polygonmeshes,272,281processingoptions,252cuttingfacesof,281procname,48stellating,283PRODinternaldatastructure,POLYGONS416COLOR,308products,416 Index¯441programmingfromdefault,197generic,44,117,124,125,linesfromßles,197129remainderofßle,198numerical,223statements,204withcolor,308stringsfromterminal,27withgraphics,245readline,27,195,197,383withplotstructures,266ReadRows,203readstat,28,219,383Quaternions,34,35,40advantages,28associativityof,40record,57inverseof,37records,72quaternions,75instantiating,72quick-sortalgorithm,8representingquaternions,75quit,381,397,420types,74quotientßeld,129rectangulartables,429quotients,416REF,343referencerand,11,14callby,340randomàoatingpointnum-remembertables,36,240,427bers,11returnstatement,48,417randomdistribution,11RETURNinternaldatastructure,randomnumbers417generating,11RGB,255range,416rootßnding,14RANGEinternaldatastructure,rotatingplots,274416rounding,225rational,416roundoÞerrors,236,237RATIONALinternaldatastruc-catastrophiccancellation,238,ture,416241read,417IEEEstandard,237READinternaldatastructure,increasingprecision,238417similarmagnitudes,237readabilityrtable,417,429ofcode,6RTABLEinternaldatastructure,readbytes,197417,429readdata,189,204rtables,212,214,215,232readingbytesfromßles,197samplesdirectory,46columns,204save,419data,187SAVEinternaldatastructure,419expressionsfromterminal,28protect,198 442¯IndexscanningSTATSEQinternaldatastruc-ßles,189,198ture,420strings,220stop,381,420scopingrules,6STOPinternaldatastructure,420searching,426streamcall,385selectionoperation,18STRINGinternaldatastructure,sequenceofsets420Cartesianproduct,22strings,420sequencesconvertingtoexpressions,30ofarguments,251parsing,30ofstatements,420readingfromterminal,27series,399,427submodules,58SERIESinternaldatastructure,subsop,399419Sum,227SETinternaldatastructure,420sum,227sets,19SUMinternaldatastructure,421shadows,276sums,421Shapes,58,94numerical,227object-orientedapproach,115suppressingshiftsymbolicevaluation,227multivariatefunction,18systemunivariatefunction,17integrity,374signofzero,236table,428simplißcationtable,426TABLEinternaldatastructure,simplify421,428extending,40tablereferences,421Smithcharts,280TABLEREFinternaldatastruc-softwareàoating-pointnumbers,ture,421224,235,297tables,421accuracyof,225terminators,28,219baseof,225thismodule,48digitsof,224,225tilde,21solutionstilings,278analytical,224Truchet,279numerical,224trace,57,381sort,427transformingplots,281sorting,8Truchettilings,279sprintf,220try,232,422sscanf,220TRYinternaldatastructure,422standardworksheet,2type Index¯443record,74versiontype,400classicworksheet,2extending,31command-line,2typematch,40standardworksheet,2typesandmodules,60worksheetchecking,27,32,250classic,2deßningnew,31,35graphicalinterface,2enumerated,339standard,2matching,259versions,2structured,32wrapper,331custom,331,350unapply,15Maple-generated,331,338unbuÞeredßles,190writebytes,210undefined,236writedata,187,215UNEVALinternaldatastructure,writeline,210422writeto,217,383,384unevaluatedexpressions,229,422uniformdistribution,11xor,423uniformrandomnumbergenera-XORinternaldatastructure,423tor,11zerounload,57àoating-pointrepresentation,use,46,103,422236USEinternaldatastructure,422signof,236userinput,27,30ZPPOLYinternaldatastructure,userinterface,398423userinfo,41variablesexportedvs.local,118global,20,21identifying,20lexicallyscoped,409local,19,26,410scopeof,6unassigning,21undeclared,7vectorßelds,286Vectors,214,215read,215write,215 444¯Index

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。
关闭