{"id":17222772,"url":"https://github.com/cheind/rmds","last_synced_at":"2025-04-14T00:16:51.061Z","repository":{"id":56892430,"uuid":"905210","full_name":"cheind/rmds","owner":"cheind","description":"Ruby Multidimensional Scaling Library","archived":false,"fork":false,"pushed_at":"2010-09-24T09:06:46.000Z","size":416,"stargazers_count":13,"open_issues_count":0,"forks_count":20,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-14T00:16:41.229Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://rdoc.info/github/cheind/rmds/master/frames","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cheind.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2010-09-12T15:02:20.000Z","updated_at":"2025-04-03T14:49:24.000Z","dependencies_parsed_at":"2022-08-20T16:10:33.848Z","dependency_job_id":null,"html_url":"https://github.com/cheind/rmds","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cheind%2Frmds","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cheind%2Frmds/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cheind%2Frmds/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cheind%2Frmds/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cheind","download_url":"https://codeload.github.com/cheind/rmds/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248799950,"owners_count":21163404,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-15T04:06:19.699Z","updated_at":"2025-04-14T00:16:51.037Z","avatar_url":"https://github.com/cheind.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ruby Multidimensional Scaling Library\n\n## Introduction\n\nRMDS is a library for performing multidimensional scaling. \n\n[Wikipedia][wiki_mds] describes multidimensional scaling (MDS) as\n\u003e [...] a set of related statistical techniques often used in information \n\u003e visualization for exploring similarities or dissimilarities in data.\n\nIn essence, multidimensional scaling takes a matrix of similarities or dissimilarities between pairwise observations as input and outputs a matrix of observations in Cartesian coordinates that preserve the similarities/dissimilarities given. The dimensionality of the output is a parameter to the algorithm.\n\n## Metric Multidimensional Scaling\n\nRMDS implements metric multidimensional scaling in which dissimilarities are assumed to be distances. The result of this multidimensional scaling variant are coordinates in the Euclidean space that explain the given distances. In general, the embedding found is not unique as any rigid transformation (rotation, translation, reflection) applied to the resulting coordinates does not change the pairwise distances.\n\n## Linear Algebra Backends\n\nRMDS makes heavy use of linear algebra routines, but does not ship with linear algebra algorithms. Instead, RMDS has a non-intrusive adapter architecture to connect existing linear algebra packages to RMDS. For how-to details on providing new adapters for RMDS see {MDS::MatrixInterface}.\n\nNote that the performance of most RMDS algorithms is dominated by the algorithms and performance of the linear algebra backend used. \n\nCurrently the following linear algebra backends are supported\n\n- {MDS::StdlibInterface} - Connects Ruby's core matrix class to RMDS.\n- {MDS::GSLInterface} - Connects the GNU Scientific Library to RMDS.\n- {MDS::LinalgInterface} - Connects LAPACK and BLAS via Linalg to RMDS.\n\n## Installation\n\nRMDS is available as gem and as git repository. To install RMDS using Ruby gems invoke\n\n    \u003e gem install rmds\n    \nor clone the git repository\n\n    \u003e git clone git://github.com/cheind/rmds.git\n   \nIf you like to contribute, drop note at christoph.heindl@gmail.com\n\n## Examples\n\nThe following successfully calculates a two dimensional Cartesian embedding for a given distance matrix.\n  \n    require 'mds'\n    require 'mds/interfaces/gsl_interface'\n    \n    # Tell RMDS the linear algebra backend to be used.\n    MDS::Backend.interface = MDS::GSLInterface\n    \n    # The squared Euclidean distance matrix.\n    d2 = MDS::Matrix.create_rows(\n      [0.0, 10.0, 2.0], \n      [10.0, 0.0, 20.0], \n      [2.0, 20.0, 0.0]\n    )\n    \n    # Find a Cartesian embedding in two dimensions\n    # that approximates the distances in two dimensions.\n    x = MDS::Metric.projectd(d2, 2)\n    \nThe result, *x*, of the above example is shown in the following image. In red the coordinates that yield the input matrix *d2*. In green, the resulting embedding *x* which preserves distances between individual observations and is unique up to rigid transformations.\n\n![Result of MDS](http://github.com/cheind/rmds/raw/master/docs/readme_example.png)\n\nThe following example works on a distance matrix which originates from air distances between european cities. It does not require a concrete linear algebra backend, but rather chooses an available one. The results are diagrammed graphically using Gnuplot and compared to the result from a mapping tool.\n\n    require 'mds'\n    require 'gnuplot' # gem install gnuplot\n    \n    # Load backends\n    MDS::Backend.load_backends\n    MDS::Backend.active = MDS::Backend.first\n    puts \"Using backend #{MDS::Backend.active}\"\n    \n    # Load distance matrix from file, contains city names in first column\n    path = File.join(File.dirname(__FILE__), 'european_city_distances.csv')\n    cities = []\n    rows = MDS::IO::read_csv(path, ';') do |entry|\n      begin\n        f = Float(entry)\n        f * f # we use squared distances\n      rescue ArgumentError\n        cities \u003c\u003c entry\n        nil\n      end\n    end\n    \n    # Invoke MDS\n\n    d2 = MDS::Matrix.create_rows(*rows)      \n    # Find a projection that preserves 90 percent of the variance of the distances.\n    proj = MDS::Metric.projectk(d2, 0.9) \n    \n    # Plot results\n    \n    Gnuplot.open do |gp|\n      Gnuplot::Plot.new( gp ) do |plot|\n        \n        # Uncomment the following lines to write result to image.\n        # plot.term 'png size'\n        # plot.output 'visualization.png'\n        \n        plot.title \"Air Distances between European Cities\"  \n        plot.xrange \"[-2000:2000]\"\n        plot.yrange \"[-1500:1200]\"\n        \n        plot.data \u003c\u003c Gnuplot::DataSet.new(proj.columns) do |ds|\n          ds.with = \"points\"\n          ds.notitle\n        end\n        \n        cities.each_with_index do |name, i|\n          plot.label \"'#{name}' at #{proj[i,0] + 30}, #{proj[i,1] + 30}\"\n        end\n      end\n    end\n\nThe following image show the result of the above script. A map is shown in a separate image for comparison. \n\nKeep in mind that \n \n - MDS finds an embedding invariant to rigid transformations (rotation, translation, reflection)\n - The input matrix contains air-distances and the map shows correct goedesic distances.\n\n![Result of MDS](http://github.com/cheind/rmds/raw/master/docs/readme_mds_cities.png) \n\n![Result of Mapping](http://github.com/cheind/rmds/raw/master/docs/readme_cities.png)\n    \n## Benchmarks\nThe following tables show the results of benchmarking different linear algebra packages against three test scenarios. They were generated by invoking 'rake test:bench:all' on a QuadCore 2.4 GHz machine, running Ubuntu 10.4 inside a virtual machine.\n\nNote that the each test involves creation of the observations randomly, calculating the squared euclidean distance matrix of observations and invoking MDS. The first two steps are not listed explicitely since they only take roughly 5 percent of the total runtime.\n\n    Benchmarking RMDS for 10 observations in 2-dimensional space\n                    user     system      total        real\n    stdlib:     3.710000   1.220000   4.930000 (  5.195076)\n    gsl:        0.000000   0.000000   0.000000 (  0.067544)\n    linalg:     0.000000   0.000000   0.000000 (  0.005462)\n    \n    Benchmarking RMDS for 100 observations in 5-dimensional space\n                    user     system      total        real\n    stdlib:          inf        inf        inf (       inf)\n    gsl:        0.030000   0.010000   0.040000 (  0.043115)\n    linalg:     0.020000   0.010000   0.030000 (  0.043157)\n    \n    Benchmarking RMDS for 1000 observations in 10-dimensional space\n                    user     system      total        real\n    stdlib:          inf        inf        inf (       inf)\n    gsl:       34.070000   1.390000  35.460000 ( 39.013276)\n    linalg:    12.750000   0.340000  13.090000 ( 13.645427)\n    \nBecause of documented limitations of {MDS::StdlibInterface} timings for this interface are shown only for the smallest of the three scenarios. Neither GSL nor LAPACK/BLAS was re-compiled for optimal performance.\n\n## Documentation\n\nChoose your version\n\n- Documentation of [master branch](http://rdoc.info/github/cheind/rmds/master/frames)\n- Documentation of [release 0.2](http://rdoc.info/gems/rmds/0.2/frames)\n\n## Requirements\n\nRMDS itself does not have any dependencies except Ruby. Each matrix interface is likley to depend on one or more external projects, such as bindings and native libraries.\n\nRMDS is tested against Ruby 1.8.7 and Ruby 1.9.1.\n\n## References\n\n- [Modern Multidimensional Scaling](http://people.few.eur.nl/groenen/mmds/)\n- [Multidimensional Scaling](http://webcourse.cs.technion.ac.il/236861/Winter2007-2008/ho/WCFiles/multidimensional_scaling.pdf)\n\n## License\n\n*RMDS* is copyright 2010 Christoph Heindl. It is free software, and may be redistributed under the terms specified in the {file:LICENSE.md} file.\n\n[wiki_mds]: http://en.wikipedia.org/wiki/Multidimensional_scaling \"Wikipedia - Multidimensional Scaling\"\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcheind%2Frmds","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcheind%2Frmds","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcheind%2Frmds/lists"}