{"id":5164,"date":"2024-03-21T16:23:05","date_gmt":"2024-03-21T15:23:05","guid":{"rendered":"https:\/\/gdksoftware.com\/?post_type=knowledge&#038;p=5164"},"modified":"2024-03-21T16:23:05","modified_gmt":"2024-03-21T15:23:05","slug":"polynomiale-kromme-best-passend","status":"publish","type":"knowledge","link":"https:\/\/gdksoftware.com\/nl\/kennisbank\/polynomiale-kromme-best-passend","title":{"rendered":"Polynomiale Kromme Best Passend"},"content":{"rendered":"<h3>Achtergrond<\/h3>\n<p>Onlangs moesten we voor een klant een best-fit curve berekenen voor een set punten. De software die we implementeerden wordt gebruikt om een metaalbewerkingsmachine aan te sturen en moest een uitvoer produceren die een vloeiende curve was, gebaseerd op een set bemonsterde punten. Omdat ik eerder aan soortgelijke problemen had gewerkt, had ik een ruw idee hoe dit wiskundig zou moeten werken, maar zoals meestal het geval is bij het ontwikkelen van software, was ik er zeker van dat iemand anders dit specifieke probleem al had opgelost.<\/p>\n<h3>Vereisten<\/h3>\n<p>We hebben een set punten met X- en Y-co\u00f6rdinaten. De software moet een kromme berekenen die het beste past bij de punten. Daarbij moet het ook extra tussenliggende punten introduceren zodat de curve zo vloeiend mogelijk is. Bijvoorbeeld, voor een set van 400 punten berekent de software 5.000 punten die allemaal op de best passende curve liggen.<\/p>\n<h3>Onderzoek<\/h3>\n<p>Een snelle zoektocht op Google leverde een aantal mogelijke Delphi-oplossingen voor dit probleem op.<\/p>\n<p>De oplossing die het meest veelbelovend leek, was deze oplossing van David Taylor: <a href=\"https:\/\/www.satsignal.eu\/software\/components.html#CurveFit\">https:\/\/www.satsignal.eu\/software\/components.html#CurveFit<\/a><\/p>\n<p>Dit was een enkele Delphi unit die niet afhankelijk was van andere componenten en gewoon de System.Math unit gebruikte.<br \/>\nDe routine was geschreven in Delphi 5, maar het testproject compileerde zonder problemen in de nieuwste versie van Delphi, zoals je zou verwachten van een puur wiskundige Delphi unit.<\/p>\n<h3>De code gebruiken<\/h3>\n<h5>Inputs<\/h5>\n<p>De hoofdfunctie accepteert:<\/p>\n<ul>\n<li>Een array van floating-point X-waarden.<\/li>\n<li>Een array van floating-point Y-waarden.<\/li>\n<li>Het aantal termen dat gebruikt moet worden.<\/li>\n<\/ul>\n<p>Het aantal termen heeft betrekking op de graad van de polynoomformule die zal worden gebruikt.<\/p>\n<p>Een enkele term is gelijk aan een horizontale lijn op een grafiek, bijv.\u00a0 \u00a0<em>y = 2<\/em><\/p>\n<p>Het gebruik van twee termen staat gelijk aan een rechte lijn op een grafiek, bijv.\u00a0 \u00a0<em>y = 3x + 2<\/em><\/p>\n<p>Drie termen gebruiken is gelijk aan een kwadratische vergelijking, bijv.\u00a0 \u00a0<em>y = 4x\u00b2 + 3x + 2<\/em><\/p>\n<h5>Outputs<\/h5>\n<p>De berekeningsfunctie vult een array van floating-point waarden die overeenkomen met de co\u00ebffici\u00ebnten van de vergelijking. Als we bijvoorbeeld drie termen willen gebruiken (een kwadratische vergelijking), kunnen we een matrix van drie drijvendekomma getallen doorgeven. In het bovenstaande kwadratische voorbeeld zouden de co\u00ebffici\u00ebnten respectievelijk 2, 3 en 4 zijn. De berekening geeft ook een correlatieco\u00ebffici\u00ebnt terug, die ons vertelt hoe nauw de curve correleert met de opgegeven invoerpunten. Hoe dichter deze co\u00ebffici\u00ebnt bij 1 ligt, hoe nauwkeuriger de fit.<\/p>\n<h3>Resultaten<\/h3>\n<p>Bij het gebruik van de code werden unit tests geschreven op basis van een set testpunten die door onze klant waren aangeleverd. De geleverde punten waren typisch voor de samples die ze in de productie zouden gebruiken. Met deze testpunten werd de nauwkeurigste curve geproduceerd wanneer de functie met zes termen werd aangeroepen. Dit komt overeen met een polynoomfunctie van de vijfde graad.<\/p>\n<p>Bij gebruik van meer dan zes termen ontstonden er af en toe floating-point overflowfouten, waarschijnlijk omdat de berekende co\u00ebffici\u00ebnten te klein waren om te worden weergegeven in een Double-type in Delphi. Bij gebruik van minder dan zes termen berekende de routine nog steeds de best passende curve, maar de fit was natuurlijk niet zo nauwkeurig. Met minder termen was de correlatieco\u00ebffici\u00ebnt lager.<\/p>\n<p>Met zes termen kregen we zes co\u00ebffici\u00ebnten terug in de array die aan de functie werd geleverd.<\/p>\n<p>Zodra we de co\u00ebffici\u00ebnten hebben, kunnen we de Y-waarde berekenen voor elke waarde van X. Om de gewenste curve te krijgen, werd een matrix van 5000 gelijkmatig gespreide X-punten berekend, begrensd door de maximale en minimale X-waarden van de steekproef.<\/p>\n<pre style=\"background: #ffffff; overflow: auto; width: auto; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;\">function CalculateY(const X: Double; const Coefficients: TArray&lt;Double&gt;): Double;\r\nbegin\r\n  var yc := 0.0;\r\n  var xc := 1.0;\r\n\r\n  for var i := Low(Coefficients) to High(Coefficients) do\r\n  begin\r\n    yc := yc + Coefficients[i] * xc;\r\n    xc := xc * X;\r\n  end;\r\n\r\n  Result := yc;\r\nend;<\/pre>\n<p>Hier is een voorbeeld van enkele van de invoerpunten:<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-5158\" src=\"https:\/\/gdksoftware.com\/wp-content\/uploads\/2024\/03\/Image1.png\" alt=\"\" width=\"679\" height=\"344\" srcset=\"https:\/\/gdksoftware.com\/wp-content\/uploads\/2024\/03\/Image1.png 679w, https:\/\/gdksoftware.com\/wp-content\/uploads\/2024\/03\/Image1-300x152.png 300w\" sizes=\"(max-width: 679px) 100vw, 679px\" \/><\/p>\n<p>In de software wordt de best passende curve berekend en als volgt over de punten gelegd:<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-5161\" src=\"https:\/\/gdksoftware.com\/wp-content\/uploads\/2024\/03\/Image2.png\" alt=\"\" width=\"679\" height=\"344\" srcset=\"https:\/\/gdksoftware.com\/wp-content\/uploads\/2024\/03\/Image2.png 679w, https:\/\/gdksoftware.com\/wp-content\/uploads\/2024\/03\/Image2-300x152.png 300w\" sizes=\"(max-width: 679px) 100vw, 679px\" \/><\/p>\n<h3>Implementatie<\/h3>\n<p>De functie gebruikt een algoritme voor het passen van de kleinste kwadratencurve met <a href=\"https:\/\/nl.wikipedia.org\/wiki\/Gauss-eliminatie\">Gauss-Jordan eliminatie<\/a>.<\/p>\n<p>Dit is een bekend algoritme voor het vinden van een best passende polynomiale curve voor een verzameling punten.<\/p>\n<h3>Conclusie<\/h3>\n<p>We hebben gezien dat wiskundige code die oorspronkelijk was geschreven in Turbo Pascal en vroege versies van Delphi zonder wijzigingen kan worden gebruikt in de nieuwste versies van Delphi.<\/p>\n<p>Deze code kan nauwkeurige en vloeiende curven produceren voor de beste fit van een set gegevenspunten.<br \/>\nHoe hoger het aantal termen en dus de graad van de polynoom, hoe nauwkeuriger de fit.<\/p>\n","protected":false},"featured_media":0,"parent":0,"template":"","class_list":["post-5164","knowledge","type-knowledge","status-publish","hentry","knowledge-category-delphi"],"acf":{"author":560,"type_hero":"compact","hero_image":5156,"hero_image_position":"","hero_title":"Polynomiale Kromme Best Passend","hero_content":"","hero_link":null,"hero_show_h1":false},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.8 (Yoast SEO v27.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Polynomiale Kromme Best Passend - GDK Software<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/gdksoftware.com\/nl\/kennisbank\/polynomiale-kromme-best-passend\" \/>\n<meta property=\"og:locale\" content=\"nl_NL\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Polynomiale Kromme Best Passend\" \/>\n<meta property=\"og:description\" content=\"Achtergrond Onlangs moesten we voor een klant een best-fit curve berekenen voor een set punten. De software die we implementeerden wordt gebruikt om een metaalbewerkingsmachine aan te sturen en moest een uitvoer produceren die een vloeiende curve was, gebaseerd op een set bemonsterde punten. Omdat ik eerder aan soortgelijke problemen had gewerkt, had ik een [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/gdksoftware.com\/nl\/kennisbank\/polynomiale-kromme-best-passend\" \/>\n<meta property=\"og:site_name\" content=\"GDK Software\" \/>\n<meta property=\"og:image\" content=\"https:\/\/gdksoftware.com\/wp-content\/uploads\/2024\/03\/Image1.png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Geschatte leestijd\" \/>\n\t<meta name=\"twitter:data1\" content=\"4 minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/gdksoftware.com\\\/nl\\\/kennisbank\\\/polynomiale-kromme-best-passend\",\"url\":\"https:\\\/\\\/gdksoftware.com\\\/nl\\\/kennisbank\\\/polynomiale-kromme-best-passend\",\"name\":\"Polynomiale Kromme Best Passend - GDK Software\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/gdksoftware.com\\\/nl#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/gdksoftware.com\\\/nl\\\/kennisbank\\\/polynomiale-kromme-best-passend#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/gdksoftware.com\\\/nl\\\/kennisbank\\\/polynomiale-kromme-best-passend#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/gdksoftware.com\\\/wp-content\\\/uploads\\\/2024\\\/03\\\/Image1.png\",\"datePublished\":\"2024-03-21T15:23:05+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/gdksoftware.com\\\/nl\\\/kennisbank\\\/polynomiale-kromme-best-passend#breadcrumb\"},\"inLanguage\":\"nl-NL\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/gdksoftware.com\\\/nl\\\/kennisbank\\\/polynomiale-kromme-best-passend\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"nl-NL\",\"@id\":\"https:\\\/\\\/gdksoftware.com\\\/nl\\\/kennisbank\\\/polynomiale-kromme-best-passend#primaryimage\",\"url\":\"https:\\\/\\\/gdksoftware.com\\\/wp-content\\\/uploads\\\/2024\\\/03\\\/Image1.png\",\"contentUrl\":\"https:\\\/\\\/gdksoftware.com\\\/wp-content\\\/uploads\\\/2024\\\/03\\\/Image1.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/gdksoftware.com\\\/nl\\\/kennisbank\\\/polynomiale-kromme-best-passend#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/gdksoftware.com\\\/nl\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Knowledgebase\",\"item\":\"https:\\\/\\\/gdksoftware.com\\\/nl\\\/kennisbank\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Polynomiale Kromme Best Passend\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/gdksoftware.com\\\/nl#website\",\"url\":\"https:\\\/\\\/gdksoftware.com\\\/nl\",\"name\":\"GDK Software\",\"description\":\"Zet de stip op je horizon\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/gdksoftware.com\\\/nl?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"nl-NL\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Polynomiale Kromme Best Passend - GDK Software","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/gdksoftware.com\/nl\/kennisbank\/polynomiale-kromme-best-passend","og_locale":"nl_NL","og_type":"article","og_title":"Polynomiale Kromme Best Passend","og_description":"Achtergrond Onlangs moesten we voor een klant een best-fit curve berekenen voor een set punten. De software die we implementeerden wordt gebruikt om een metaalbewerkingsmachine aan te sturen en moest een uitvoer produceren die een vloeiende curve was, gebaseerd op een set bemonsterde punten. Omdat ik eerder aan soortgelijke problemen had gewerkt, had ik een [&hellip;]","og_url":"https:\/\/gdksoftware.com\/nl\/kennisbank\/polynomiale-kromme-best-passend","og_site_name":"GDK Software","og_image":[{"url":"https:\/\/gdksoftware.com\/wp-content\/uploads\/2024\/03\/Image1.png","type":"","width":"","height":""}],"twitter_card":"summary_large_image","twitter_misc":{"Geschatte leestijd":"4 minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/gdksoftware.com\/nl\/kennisbank\/polynomiale-kromme-best-passend","url":"https:\/\/gdksoftware.com\/nl\/kennisbank\/polynomiale-kromme-best-passend","name":"Polynomiale Kromme Best Passend - GDK Software","isPartOf":{"@id":"https:\/\/gdksoftware.com\/nl#website"},"primaryImageOfPage":{"@id":"https:\/\/gdksoftware.com\/nl\/kennisbank\/polynomiale-kromme-best-passend#primaryimage"},"image":{"@id":"https:\/\/gdksoftware.com\/nl\/kennisbank\/polynomiale-kromme-best-passend#primaryimage"},"thumbnailUrl":"https:\/\/gdksoftware.com\/wp-content\/uploads\/2024\/03\/Image1.png","datePublished":"2024-03-21T15:23:05+00:00","breadcrumb":{"@id":"https:\/\/gdksoftware.com\/nl\/kennisbank\/polynomiale-kromme-best-passend#breadcrumb"},"inLanguage":"nl-NL","potentialAction":[{"@type":"ReadAction","target":["https:\/\/gdksoftware.com\/nl\/kennisbank\/polynomiale-kromme-best-passend"]}]},{"@type":"ImageObject","inLanguage":"nl-NL","@id":"https:\/\/gdksoftware.com\/nl\/kennisbank\/polynomiale-kromme-best-passend#primaryimage","url":"https:\/\/gdksoftware.com\/wp-content\/uploads\/2024\/03\/Image1.png","contentUrl":"https:\/\/gdksoftware.com\/wp-content\/uploads\/2024\/03\/Image1.png"},{"@type":"BreadcrumbList","@id":"https:\/\/gdksoftware.com\/nl\/kennisbank\/polynomiale-kromme-best-passend#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/gdksoftware.com\/nl"},{"@type":"ListItem","position":2,"name":"Knowledgebase","item":"https:\/\/gdksoftware.com\/nl\/kennisbank"},{"@type":"ListItem","position":3,"name":"Polynomiale Kromme Best Passend"}]},{"@type":"WebSite","@id":"https:\/\/gdksoftware.com\/nl#website","url":"https:\/\/gdksoftware.com\/nl","name":"GDK Software","description":"Zet de stip op je horizon","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/gdksoftware.com\/nl?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"nl-NL"}]}},"_links":{"self":[{"href":"https:\/\/gdksoftware.com\/nl\/wp-json\/wp\/v2\/knowledge\/5164","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gdksoftware.com\/nl\/wp-json\/wp\/v2\/knowledge"}],"about":[{"href":"https:\/\/gdksoftware.com\/nl\/wp-json\/wp\/v2\/types\/knowledge"}],"acf:post":[{"embeddable":true,"href":"https:\/\/gdksoftware.com\/nl\/wp-json\/wp\/v2\/team\/560"}],"wp:attachment":[{"href":"https:\/\/gdksoftware.com\/nl\/wp-json\/wp\/v2\/media?parent=5164"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}