{"id":2942,"date":"2011-01-07T18:08:28","date_gmt":"2011-01-07T17:08:28","guid":{"rendered":"http:\/\/www.walkingrandomly.com\/?p=2942"},"modified":"2011-01-07T18:08:28","modified_gmt":"2011-01-07T17:08:28","slug":"weighted-polynomial-fitting-in-matlab-without-any-toolboxes","status":"publish","type":"post","link":"https:\/\/walkingrandomly.com\/?p=2942","title":{"rendered":"Weighted polynomial fitting in MATLAB (without any toolboxes)"},"content":{"rendered":"<p>Someone recently contacted me with a problem &#8211; she wanted to use MATLAB to perform a weighted quadratic curve fit to a set of data.\u00a0 Now, if she had the curve fitting toolbox this would be nice and easy:<\/p>\n<pre>x=[ 1 2 3 4 5];\r\ny=[1.4 2.2 3.5 4.9 2.3];\r\nw=[1 1 1 1 0.1];\r\n\r\nf=fittype('poly2');\r\noptions=fitoptions('poly2');\r\noptions.Weights=[1 1 1 1 0.1];\r\nfun=fit(x',y',f,options);\r\np1=fun.p1;\r\np2=fun.p2;\r\np3=fun.p3;\r\n\r\nmyfit = [p1 p2 p3]\r\n\r\nmyfit =\r\n   -0.1599    1.8554   -0.5014<\/pre>\n<p>So, our weighted quadratic curve fit is<strong> y = -0.4786*x^2 + 3.3214*x &#8211; 1.84<\/strong><\/p>\n<p>So far so good but she didn&#8217;t have access to the curve fitting toolbox so what to do? One function that<strong> almost<\/strong> meets her needs is the standard MATLAB function <a href=\"http:\/\/www.mathworks.com\/help\/techdoc\/ref\/polyfit.html\"><strong>polyfit<\/strong><\/a> which can do everything apart from the weighted part.<\/p>\n<pre>polyfit(x,y,2)\r\nans =\r\n   -0.4786    3.3214   -1.8400<\/pre>\n<p>which would agree with the curve fitting toolbox if we set the weights to all ones. Sadly, however, we cannot supply the weights to the polyfit function as it currently stands (as of 2010b). My solution was to create a new function, <strong>wpolyfit<\/strong>, that does accept a vector of weights:<\/p>\n<pre>wpolyfit(x,y,2,w)\r\nans =\r\n   -0.1599    1.8554   -0.5014<\/pre>\n<p>So where is this new function I hear you ask? Normally this is where I would provide you with a download link but unfortunately I created wpolyfit by making a very small modification to the original built-in polyfit function and so I might be on dicey ground by distributing it. So, instead I will give you instructions on how to make it yourself.\u00a0 I did this using MATLAB 2010b but it should work with other versions assuming that the polyfit function hasn&#8217;t changed much.<\/p>\n<p>First, open up the polyfit function in the MATLAB editor<\/p>\n<pre>edit polyfit<\/pre>\n<p>change the first line so that it reads<\/p>\n<pre>function [p,S,mu] = wpolyfit(x,y,n,w)<\/pre>\n<p>Now, just <strong>before<\/strong> the line that reads<\/p>\n<pre>% Solve least squares problem.<\/pre>\n<p>add the following<\/p>\n<pre>w=sqrt(w(:));\r\ny=y.*w;\r\nfor j=1:n+1\r\n    V(:,j) = w.*V(:,j);\r\nend<\/pre>\n<p>Save the file as <strong>wpolyfit.m<\/strong> and you are done. I won&#8217;t go over the theory of how this works because it is covered very nicely <a href=\"http:\/\/www.mathworks.com\/moler\/leastsquares.pdf\">here<\/a>.\u00a0 Comments welcomed.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Someone recently contacted me with a problem &#8211; she wanted to use MATLAB to perform a weighted quadratic curve fit to a set of data.\u00a0 Now, if she had the curve fitting toolbox this would be nice and easy: x=[ 1 2 3 4 5]; y=[1.4 2.2 3.5 4.9 2.3]; w=[1 1 1 1 0.1]; [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[11,7],"tags":[],"class_list":["post-2942","post","type-post","status-publish","format-standard","hentry","category-matlab","category-programming"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p3swhs-Ls","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/posts\/2942","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2942"}],"version-history":[{"count":24,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/posts\/2942\/revisions"}],"predecessor-version":[{"id":3116,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/posts\/2942\/revisions\/3116"}],"wp:attachment":[{"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2942"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2942"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2942"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}