{"group":{"id":1,"name":"Community","lockable":false,"created_at":"2012-01-18T18:02:15.000Z","updated_at":"2025-12-14T01:33:56.000Z","description":"Problems submitted by members of the MATLAB Central community.","is_default":true,"created_by":161519,"badge_id":null,"featured":false,"trending":false,"solution_count_in_trending_period":0,"trending_last_calculated":"2025-12-14T00:00:00.000Z","image_id":null,"published":true,"community_created":false,"status_id":2,"is_default_group_for_player":false,"deleted_by":null,"deleted_at":null,"restored_by":null,"restored_at":null,"description_opc":null,"description_html":null,"published_at":null},"problems":[{"id":44832,"title":"Generate Convolution Matrix of 2D Kernel with Different Convolution Shapes (Full, Same, Valid)","description":"In this problem the challenge is to build the Matrix Form equivalent of the function `conv2()` of MATLAB.\r\n\r\nThe function to be built will generate a sparse matrix `mK` which is the convolution matrix of the 2D Kernel 'mH' (Which is an input to the function).  \r\nThe input to the function is the 2D Kernel and dimensions of the image to apply the convolution upon and the shape of the convolution ('full', 'same', 'valid' as in 'conv2()').\r\n\r\nThe output sparse matrix should match the output of using 'conv2()' on the same image using the same convolution shape.\r\n\r\nFor instance:\r\n\r\n  CONVOLUTION_SHAPE_FULL  = 1;\r\n  CONVOLUTION_SHAPE_SAME  = 2;\r\n  CONVOLUTION_SHAPE_VALID = 3;\r\n  \r\n  numRowsImage = 100;\r\n  numColsImage = 80;\r\n  \r\n  numRowsKernel = 7;\r\n  numColsKernel = 5;\r\n  \r\n  mI = rand(numRowsImage, numColsImage);\r\n  mH = rand(numRowsKernel, numColsKernel);\r\n  \r\n  maxThr = 1e-9;\r\n  \r\n  \r\n  %% Full Convolution\r\n  \r\n  convShape       = CONVOLUTION_SHAPE_FULL;\r\n  \r\n  numRowsOut = numRowsImage + numRowsKernel - 1;\r\n  numColsOut = numColsImage + numColsKernel - 1;\r\n  \r\n  mORef   = conv2(mI, mH, 'full');\r\n  mK      = CreateImageConvMtx(mH, numRowsImage, numColsImage, convShape);\r\n  mO      = reshape(mK * mI(:), numRowsOut, numColsOut);\r\n  \r\n  mE = mO - mORef;\r\n  assert(max(abs(mE(:))) \u003c maxThr);\r\n\r\nThe test case will examine all 3 modes.\r\nTry to solve it once with very clear code (No vectorization tricks) and then optimize.\r\n\r\nA good way to build the output sparse function is using:\r\n\r\n  mK = sparse(vRows, vCols, vVals, numElementsOutputImage, numElementsInputImage);\r\n\r\nLook for the documentation of `sparse()` function for more details.","description_html":"\u003cp\u003eIn this problem the challenge is to build the Matrix Form equivalent of the function `conv2()` of MATLAB.\u003c/p\u003e\u003cp\u003eThe function to be built will generate a sparse matrix `mK` which is the convolution matrix of the 2D Kernel 'mH' (Which is an input to the function).  \r\nThe input to the function is the 2D Kernel and dimensions of the image to apply the convolution upon and the shape of the convolution ('full', 'same', 'valid' as in 'conv2()').\u003c/p\u003e\u003cp\u003eThe output sparse matrix should match the output of using 'conv2()' on the same image using the same convolution shape.\u003c/p\u003e\u003cp\u003eFor instance:\u003c/p\u003e\u003cpre class=\"language-matlab\"\u003eCONVOLUTION_SHAPE_FULL  = 1;\r\nCONVOLUTION_SHAPE_SAME  = 2;\r\nCONVOLUTION_SHAPE_VALID = 3;\r\n\u003c/pre\u003e\u003cpre class=\"language-matlab\"\u003enumRowsImage = 100;\r\nnumColsImage = 80;\r\n\u003c/pre\u003e\u003cpre class=\"language-matlab\"\u003enumRowsKernel = 7;\r\nnumColsKernel = 5;\r\n\u003c/pre\u003e\u003cpre class=\"language-matlab\"\u003emI = rand(numRowsImage, numColsImage);\r\nmH = rand(numRowsKernel, numColsKernel);\r\n\u003c/pre\u003e\u003cpre class=\"language-matlab\"\u003emaxThr = 1e-9;\r\n\u003c/pre\u003e\u003cpre class=\"language-matlab\"\u003e%% Full Convolution\r\n\u003c/pre\u003e\u003cpre class=\"language-matlab\"\u003econvShape       = CONVOLUTION_SHAPE_FULL;\r\n\u003c/pre\u003e\u003cpre class=\"language-matlab\"\u003enumRowsOut = numRowsImage + numRowsKernel - 1;\r\nnumColsOut = numColsImage + numColsKernel - 1;\r\n\u003c/pre\u003e\u003cpre class=\"language-matlab\"\u003emORef   = conv2(mI, mH, 'full');\r\nmK      = CreateImageConvMtx(mH, numRowsImage, numColsImage, convShape);\r\nmO      = reshape(mK * mI(:), numRowsOut, numColsOut);\r\n\u003c/pre\u003e\u003cpre class=\"language-matlab\"\u003emE = mO - mORef;\r\nassert(max(abs(mE(:))) \u0026lt; maxThr);\r\n\u003c/pre\u003e\u003cp\u003eThe test case will examine all 3 modes.\r\nTry to solve it once with very clear code (No vectorization tricks) and then optimize.\u003c/p\u003e\u003cp\u003eA good way to build the output sparse function is using:\u003c/p\u003e\u003cpre class=\"language-matlab\"\u003emK = sparse(vRows, vCols, vVals, numElementsOutputImage, numElementsInputImage);\r\n\u003c/pre\u003e\u003cp\u003eLook for the documentation of `sparse()` function for more details.\u003c/p\u003e","function_template":"function [ mK ] = CreateImageConvMtx( mH, numRows, numCols, convShape )\r\n%Generates a Convolution Matrix for the 2D Kernel (The Matrix mH) with\r\n%support for different convolution shapes (Full / Same / Valid).\r\n% Input:\r\n%   - mH                -   Input 2D Convolution Kernel.\r\n%                           Structure: Matrix.\r\n%                           Type: 'Single' / 'Double'.\r\n%                           Range: (-inf, inf).\r\n%   - numRows           -   Number of Rows.\r\n%                           Number of rows in the output convolution\r\n%                           matrix.\r\n%                           Structure: Scalar.\r\n%                           Type: 'Single' / 'Double'.\r\n%                           Range: {1, 2, 3, ...}.\r\n%   - numCols           -   Number of Columns.\r\n%                           Number of columns in the output convolution\r\n%                           matrix.\r\n%                           Structure: Scalar.\r\n%                           Type: 'Single' / 'Double'.\r\n%                           Range: {1, 2, 3, ...}.\r\n%   - convShape         -   Convolution Shape.\r\n%                           The shape of the convolution which the output\r\n%                           convolution matrix should represent. The\r\n%                           options should match MATLAB's conv2() function\r\n%                           - Full / Same / Valid.\r\n%                           Structure: Scalar.\r\n%                           Type: 'Single' / 'Double'.\r\n%                           Range: {1, 2, 3}.\r\n% Output:\r\n%   - mK                -   Convolution Matrix.\r\n%                           The output convolution matrix. Multiplying in\r\n%                           the column stack form on an image should be\r\n%                           equivalent to applying convolution on the\r\n%                           image.\r\n%                           Structure: Matrix (Sparse).\r\n%                           Type: 'Single' / 'Double'.\r\n%                           Range: (-inf, inf).\r\n% References:\r\n%   1.  MATLAB's 'convmtx2()' - https://www.mathworks.com/help/images/ref/convmtx2.html.\r\n% Remarks:\r\n%   1.  gf\r\n% TODO:\r\n%   1.  \r\n%   Release Notes:\r\n%   -   1.0.000     dd/mm/yyyy  firstName lastName\r\n%       *   First release version.\r\n% ----------------------------------------------------------------------------------------------- %\r\n\r\nCONVOLUTION_SHAPE_FULL  = 1;\r\nCONVOLUTION_SHAPE_SAME  = 2;\r\nCONVOLUTION_SHAPE_VALID = 3;\r\n\r\nswitch(convShape)\r\n    case(CONVOLUTION_SHAPE_FULL)\r\n        % Code for the 'full' case\r\n    case(CONVOLUTION_SHAPE_SAME)\r\n        % Code for the 'same' case\r\n    case(CONVOLUTION_SHAPE_VALID)\r\n        % Code for the 'valid' case\r\nend\r\n\r\n\r\nend\r\n\r\n","test_suite":"%% Testing\r\n\r\n\r\nCONVOLUTION_SHAPE_FULL  = 1;\r\nCONVOLUTION_SHAPE_SAME  = 2;\r\nCONVOLUTION_SHAPE_VALID = 3;\r\n\r\nmaxThr = 1e-9;\r\n\r\n\r\nfor numRowsImage = 28:32\r\n    for numColsImage = 28:32\r\n        \r\n        mI = rand(numRowsImage, numColsImage);\r\n        \r\n        for numRowsKernel = 3:7\r\n            for numColsKernel = 3:7\r\n                \r\n                mH = rand(numRowsKernel, numColsKernel);\r\n                \r\n                for convShape = 1:3\r\n                    \r\n                    switch(convShape)\r\n                        case(CONVOLUTION_SHAPE_FULL)\r\n                            numRowsOut = numRowsImage + numRowsKernel - 1;\r\n                            numColsOut = numColsImage + numColsKernel - 1;\r\n                            \r\n                            convShapeString = 'full';\r\n                        case(CONVOLUTION_SHAPE_SAME)\r\n                            numRowsOut = numRowsImage;\r\n                            numColsOut = numColsImage;\r\n                            \r\n                            convShapeString = 'same';\r\n                        case(CONVOLUTION_SHAPE_VALID)\r\n                            numRowsOut = numRowsImage - numRowsKernel + 1;\r\n                            numColsOut = numColsImage - numColsKernel + 1;\r\n                            \r\n                            convShapeString = 'valid';\r\n                    end\r\n                    \r\n                    mORef   = conv2(mI, mH, convShapeString);\r\n                    mK      = CreateImageConvMtx(mH, numRowsImage, numColsImage, convShape);\r\n                    mO      = reshape(mK * mI(:), numRowsOut, numColsOut);\r\n                    \r\n                    disp([' ']);\r\n                    disp(['Validating solution for the following parameters:']);\r\n                    disp(['Image Size - [', num2str(numRowsImage), ' x ', num2str(numColsImage), ']']);\r\n                    disp(['Kernel Size - [', num2str(numRowsKernel), ' x ', num2str(numColsKernel), ']']);\r\n                    disp(['Convolution Shape - ', convShapeString]);\r\n                    \r\n                    mE = mO - mORef;\r\n                    maxAbsDev = max(abs(mE(:)));\r\n                    if(maxAbsDev \u003e= maxThr)\r\n                        disp([' ']);\r\n                        disp(['Validation Failed']);\r\n                        disp([' ']);\r\n                    end\r\n                    assert(maxAbsDev \u003c maxThr);\r\n                    \r\n                end\r\n            end\r\n        end\r\n    end\r\nend\r\n            \r\n\r\n\r\n\r\n","published":true,"deleted":false,"likes_count":0,"comments_count":0,"created_by":6204,"edited_by":null,"edited_at":null,"deleted_by":null,"deleted_at":null,"solvers_count":3,"test_suite_updated_at":"2019-01-15T23:13:37.000Z","rescore_all_solutions":false,"group_id":1,"created_at":"2019-01-15T21:20:18.000Z","updated_at":"2019-01-15T23:13:37.000Z","published_at":"2019-01-15T21:20:18.000Z","restored_at":null,"restored_by":null,"spam":false,"simulink":false,"admin_reviewed":false,"description_opc":"{\"relationships\":[{\"relationshipType\":\"http://schemas.mathworks.com/matlab/code/2013/relationships/document\",\"targetMode\":\"\",\"relationshipId\":\"rId1\",\"target\":\"/matlab/document.xml\"},{\"relationshipType\":\"http://schemas.mathworks.com/matlab/code/2013/relationships/output\",\"targetMode\":\"\",\"relationshipId\":\"rId2\",\"target\":\"/matlab/output.xml\"}],\"parts\":[{\"partUri\":\"/matlab/document.xml\",\"relationship\":[],\"contentType\":\"application/vnd.mathworks.matlab.code.document+xml\",\"content\":\"\u003c?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?\u003e\\n\u003cw:document xmlns:w=\\\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\\\"\u003e\u003cw:body\u003e\u003cw:p\u003e\u003cw:pPr\u003e\u003cw:pStyle w:val=\\\"text\\\"/\u003e\u003c/w:pPr\u003e\u003cw:r\u003e\u003cw:t\u003eIn this problem the challenge is to build the Matrix Form equivalent of the function `conv2()` of MATLAB.\u003c/w:t\u003e\u003c/w:r\u003e\u003c/w:p\u003e\u003cw:p\u003e\u003cw:pPr\u003e\u003cw:pStyle w:val=\\\"text\\\"/\u003e\u003c/w:pPr\u003e\u003cw:r\u003e\u003cw:t\u003eThe function to be built will generate a sparse matrix `mK` which is the convolution matrix of the 2D Kernel 'mH' (Which is an input to the function). The input to the function is the 2D Kernel and dimensions of the image to apply the convolution upon and the shape of the convolution ('full', 'same', 'valid' as in 'conv2()').\u003c/w:t\u003e\u003c/w:r\u003e\u003c/w:p\u003e\u003cw:p\u003e\u003cw:pPr\u003e\u003cw:pStyle w:val=\\\"text\\\"/\u003e\u003c/w:pPr\u003e\u003cw:r\u003e\u003cw:t\u003eThe output sparse matrix should match the output of using 'conv2()' on the same image using the same convolution shape.\u003c/w:t\u003e\u003c/w:r\u003e\u003c/w:p\u003e\u003cw:p\u003e\u003cw:pPr\u003e\u003cw:pStyle w:val=\\\"text\\\"/\u003e\u003c/w:pPr\u003e\u003cw:r\u003e\u003cw:t\u003eFor instance:\u003c/w:t\u003e\u003c/w:r\u003e\u003c/w:p\u003e\u003cw:p\u003e\u003cw:pPr\u003e\u003cw:pStyle w:val=\\\"code\\\"/\u003e\u003c/w:pPr\u003e\u003cw:r\u003e\u003cw:t\u003e\u003c![CDATA[CONVOLUTION_SHAPE_FULL  = 1;\\nCONVOLUTION_SHAPE_SAME  = 2;\\nCONVOLUTION_SHAPE_VALID = 3;\\n\\nnumRowsImage = 100;\\nnumColsImage = 80;\\n\\nnumRowsKernel = 7;\\nnumColsKernel = 5;\\n\\nmI = rand(numRowsImage, numColsImage);\\nmH = rand(numRowsKernel, numColsKernel);\\n\\nmaxThr = 1e-9;\\n\\n%%Full Convolution\\n\\nconvShape       = CONVOLUTION_SHAPE_FULL;\\n\\nnumRowsOut = numRowsImage + numRowsKernel - 1;\\nnumColsOut = numColsImage + numColsKernel - 1;\\n\\nmORef   = conv2(mI, mH, 'full');\\nmK      = CreateImageConvMtx(mH, numRowsImage, numColsImage, convShape);\\nmO      = reshape(mK * mI(:), numRowsOut, numColsOut);\\n\\nmE = mO - mORef;\\nassert(max(abs(mE(:))) \u003c maxThr);]]\u003e\u003c/w:t\u003e\u003c/w:r\u003e\u003c/w:p\u003e\u003cw:p\u003e\u003cw:pPr\u003e\u003cw:pStyle w:val=\\\"text\\\"/\u003e\u003c/w:pPr\u003e\u003cw:r\u003e\u003cw:t\u003eThe test case will examine all 3 modes. Try to solve it once with very clear code (No vectorization tricks) and then optimize.\u003c/w:t\u003e\u003c/w:r\u003e\u003c/w:p\u003e\u003cw:p\u003e\u003cw:pPr\u003e\u003cw:pStyle w:val=\\\"text\\\"/\u003e\u003c/w:pPr\u003e\u003cw:r\u003e\u003cw:t\u003eA good way to build the output sparse function is using:\u003c/w:t\u003e\u003c/w:r\u003e\u003c/w:p\u003e\u003cw:p\u003e\u003cw:pPr\u003e\u003cw:pStyle w:val=\\\"code\\\"/\u003e\u003c/w:pPr\u003e\u003cw:r\u003e\u003cw:t\u003e\u003c![CDATA[mK = sparse(vRows, vCols, vVals, numElementsOutputImage, numElementsInputImage);]]\u003e\u003c/w:t\u003e\u003c/w:r\u003e\u003c/w:p\u003e\u003cw:p\u003e\u003cw:pPr\u003e\u003cw:pStyle w:val=\\\"text\\\"/\u003e\u003c/w:pPr\u003e\u003cw:r\u003e\u003cw:t\u003eLook for the documentation of `sparse()` function for more details.\u003c/w:t\u003e\u003c/w:r\u003e\u003c/w:p\u003e\u003c/w:body\u003e\u003c/w:document\u003e\"},{\"partUri\":\"/matlab/output.xml\",\"contentType\":\"text/xml\",\"content\":\"\u003c?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\" standalone=\\\"no\\\" ?\u003e\u003cembeddedOutputs\u003e\u003cmetaData\u003e\u003cevaluationState\u003emanual\u003c/evaluationState\u003e\u003clayoutState\u003ecode\u003c/layoutState\u003e\u003coutputStatus\u003eready\u003c/outputStatus\u003e\u003c/metaData\u003e\u003coutputArray type=\\\"array\\\"/\u003e\u003cregionArray type=\\\"array\\\"/\u003e\u003c/embeddedOutputs\u003e\"}]}"}],"problem_search":{"errors":[],"problems":[{"id":44832,"title":"Generate Convolution Matrix of 2D Kernel with Different Convolution Shapes (Full, Same, Valid)","description":"In this problem the challenge is to build the Matrix Form equivalent of the function `conv2()` of MATLAB.\r\n\r\nThe function to be built will generate a sparse matrix `mK` which is the convolution matrix of the 2D Kernel 'mH' (Which is an input to the function).  \r\nThe input to the function is the 2D Kernel and dimensions of the image to apply the convolution upon and the shape of the convolution ('full', 'same', 'valid' as in 'conv2()').\r\n\r\nThe output sparse matrix should match the output of using 'conv2()' on the same image using the same convolution shape.\r\n\r\nFor instance:\r\n\r\n  CONVOLUTION_SHAPE_FULL  = 1;\r\n  CONVOLUTION_SHAPE_SAME  = 2;\r\n  CONVOLUTION_SHAPE_VALID = 3;\r\n  \r\n  numRowsImage = 100;\r\n  numColsImage = 80;\r\n  \r\n  numRowsKernel = 7;\r\n  numColsKernel = 5;\r\n  \r\n  mI = rand(numRowsImage, numColsImage);\r\n  mH = rand(numRowsKernel, numColsKernel);\r\n  \r\n  maxThr = 1e-9;\r\n  \r\n  \r\n  %% Full Convolution\r\n  \r\n  convShape       = CONVOLUTION_SHAPE_FULL;\r\n  \r\n  numRowsOut = numRowsImage + numRowsKernel - 1;\r\n  numColsOut = numColsImage + numColsKernel - 1;\r\n  \r\n  mORef   = conv2(mI, mH, 'full');\r\n  mK      = CreateImageConvMtx(mH, numRowsImage, numColsImage, convShape);\r\n  mO      = reshape(mK * mI(:), numRowsOut, numColsOut);\r\n  \r\n  mE = mO - mORef;\r\n  assert(max(abs(mE(:))) \u003c maxThr);\r\n\r\nThe test case will examine all 3 modes.\r\nTry to solve it once with very clear code (No vectorization tricks) and then optimize.\r\n\r\nA good way to build the output sparse function is using:\r\n\r\n  mK = sparse(vRows, vCols, vVals, numElementsOutputImage, numElementsInputImage);\r\n\r\nLook for the documentation of `sparse()` function for more details.","description_html":"\u003cp\u003eIn this problem the challenge is to build the Matrix Form equivalent of the function `conv2()` of MATLAB.\u003c/p\u003e\u003cp\u003eThe function to be built will generate a sparse matrix `mK` which is the convolution matrix of the 2D Kernel 'mH' (Which is an input to the function).  \r\nThe input to the function is the 2D Kernel and dimensions of the image to apply the convolution upon and the shape of the convolution ('full', 'same', 'valid' as in 'conv2()').\u003c/p\u003e\u003cp\u003eThe output sparse matrix should match the output of using 'conv2()' on the same image using the same convolution shape.\u003c/p\u003e\u003cp\u003eFor instance:\u003c/p\u003e\u003cpre class=\"language-matlab\"\u003eCONVOLUTION_SHAPE_FULL  = 1;\r\nCONVOLUTION_SHAPE_SAME  = 2;\r\nCONVOLUTION_SHAPE_VALID = 3;\r\n\u003c/pre\u003e\u003cpre class=\"language-matlab\"\u003enumRowsImage = 100;\r\nnumColsImage = 80;\r\n\u003c/pre\u003e\u003cpre class=\"language-matlab\"\u003enumRowsKernel = 7;\r\nnumColsKernel = 5;\r\n\u003c/pre\u003e\u003cpre class=\"language-matlab\"\u003emI = rand(numRowsImage, numColsImage);\r\nmH = rand(numRowsKernel, numColsKernel);\r\n\u003c/pre\u003e\u003cpre class=\"language-matlab\"\u003emaxThr = 1e-9;\r\n\u003c/pre\u003e\u003cpre class=\"language-matlab\"\u003e%% Full Convolution\r\n\u003c/pre\u003e\u003cpre class=\"language-matlab\"\u003econvShape       = CONVOLUTION_SHAPE_FULL;\r\n\u003c/pre\u003e\u003cpre class=\"language-matlab\"\u003enumRowsOut = numRowsImage + numRowsKernel - 1;\r\nnumColsOut = numColsImage + numColsKernel - 1;\r\n\u003c/pre\u003e\u003cpre class=\"language-matlab\"\u003emORef   = conv2(mI, mH, 'full');\r\nmK      = CreateImageConvMtx(mH, numRowsImage, numColsImage, convShape);\r\nmO      = reshape(mK * mI(:), numRowsOut, numColsOut);\r\n\u003c/pre\u003e\u003cpre class=\"language-matlab\"\u003emE = mO - mORef;\r\nassert(max(abs(mE(:))) \u0026lt; maxThr);\r\n\u003c/pre\u003e\u003cp\u003eThe test case will examine all 3 modes.\r\nTry to solve it once with very clear code (No vectorization tricks) and then optimize.\u003c/p\u003e\u003cp\u003eA good way to build the output sparse function is using:\u003c/p\u003e\u003cpre class=\"language-matlab\"\u003emK = sparse(vRows, vCols, vVals, numElementsOutputImage, numElementsInputImage);\r\n\u003c/pre\u003e\u003cp\u003eLook for the documentation of `sparse()` function for more details.\u003c/p\u003e","function_template":"function [ mK ] = CreateImageConvMtx( mH, numRows, numCols, convShape )\r\n%Generates a Convolution Matrix for the 2D Kernel (The Matrix mH) with\r\n%support for different convolution shapes (Full / Same / Valid).\r\n% Input:\r\n%   - mH                -   Input 2D Convolution Kernel.\r\n%                           Structure: Matrix.\r\n%                           Type: 'Single' / 'Double'.\r\n%                           Range: (-inf, inf).\r\n%   - numRows           -   Number of Rows.\r\n%                           Number of rows in the output convolution\r\n%                           matrix.\r\n%                           Structure: Scalar.\r\n%                           Type: 'Single' / 'Double'.\r\n%                           Range: {1, 2, 3, ...}.\r\n%   - numCols           -   Number of Columns.\r\n%                           Number of columns in the output convolution\r\n%                           matrix.\r\n%                           Structure: Scalar.\r\n%                           Type: 'Single' / 'Double'.\r\n%                           Range: {1, 2, 3, ...}.\r\n%   - convShape         -   Convolution Shape.\r\n%                           The shape of the convolution which the output\r\n%                           convolution matrix should represent. The\r\n%                           options should match MATLAB's conv2() function\r\n%                           - Full / Same / Valid.\r\n%                           Structure: Scalar.\r\n%                           Type: 'Single' / 'Double'.\r\n%                           Range: {1, 2, 3}.\r\n% Output:\r\n%   - mK                -   Convolution Matrix.\r\n%                           The output convolution matrix. Multiplying in\r\n%                           the column stack form on an image should be\r\n%                           equivalent to applying convolution on the\r\n%                           image.\r\n%                           Structure: Matrix (Sparse).\r\n%                           Type: 'Single' / 'Double'.\r\n%                           Range: (-inf, inf).\r\n% References:\r\n%   1.  MATLAB's 'convmtx2()' - https://www.mathworks.com/help/images/ref/convmtx2.html.\r\n% Remarks:\r\n%   1.  gf\r\n% TODO:\r\n%   1.  \r\n%   Release Notes:\r\n%   -   1.0.000     dd/mm/yyyy  firstName lastName\r\n%       *   First release version.\r\n% ----------------------------------------------------------------------------------------------- %\r\n\r\nCONVOLUTION_SHAPE_FULL  = 1;\r\nCONVOLUTION_SHAPE_SAME  = 2;\r\nCONVOLUTION_SHAPE_VALID = 3;\r\n\r\nswitch(convShape)\r\n    case(CONVOLUTION_SHAPE_FULL)\r\n        % Code for the 'full' case\r\n    case(CONVOLUTION_SHAPE_SAME)\r\n        % Code for the 'same' case\r\n    case(CONVOLUTION_SHAPE_VALID)\r\n        % Code for the 'valid' case\r\nend\r\n\r\n\r\nend\r\n\r\n","test_suite":"%% Testing\r\n\r\n\r\nCONVOLUTION_SHAPE_FULL  = 1;\r\nCONVOLUTION_SHAPE_SAME  = 2;\r\nCONVOLUTION_SHAPE_VALID = 3;\r\n\r\nmaxThr = 1e-9;\r\n\r\n\r\nfor numRowsImage = 28:32\r\n    for numColsImage = 28:32\r\n        \r\n        mI = rand(numRowsImage, numColsImage);\r\n        \r\n        for numRowsKernel = 3:7\r\n            for numColsKernel = 3:7\r\n                \r\n                mH = rand(numRowsKernel, numColsKernel);\r\n                \r\n                for convShape = 1:3\r\n                    \r\n                    switch(convShape)\r\n                        case(CONVOLUTION_SHAPE_FULL)\r\n                            numRowsOut = numRowsImage + numRowsKernel - 1;\r\n                            numColsOut = numColsImage + numColsKernel - 1;\r\n                            \r\n                            convShapeString = 'full';\r\n                        case(CONVOLUTION_SHAPE_SAME)\r\n                            numRowsOut = numRowsImage;\r\n                            numColsOut = numColsImage;\r\n                            \r\n                            convShapeString = 'same';\r\n                        case(CONVOLUTION_SHAPE_VALID)\r\n                            numRowsOut = numRowsImage - numRowsKernel + 1;\r\n                            numColsOut = numColsImage - numColsKernel + 1;\r\n                            \r\n                            convShapeString = 'valid';\r\n                    end\r\n                    \r\n                    mORef   = conv2(mI, mH, convShapeString);\r\n                    mK      = CreateImageConvMtx(mH, numRowsImage, numColsImage, convShape);\r\n                    mO      = reshape(mK * mI(:), numRowsOut, numColsOut);\r\n                    \r\n                    disp([' ']);\r\n                    disp(['Validating solution for the following parameters:']);\r\n                    disp(['Image Size - [', num2str(numRowsImage), ' x ', num2str(numColsImage), ']']);\r\n                    disp(['Kernel Size - [', num2str(numRowsKernel), ' x ', num2str(numColsKernel), ']']);\r\n                    disp(['Convolution Shape - ', convShapeString]);\r\n                    \r\n                    mE = mO - mORef;\r\n                    maxAbsDev = max(abs(mE(:)));\r\n                    if(maxAbsDev \u003e= maxThr)\r\n                        disp([' ']);\r\n                        disp(['Validation Failed']);\r\n                        disp([' ']);\r\n                    end\r\n                    assert(maxAbsDev \u003c maxThr);\r\n                    \r\n                end\r\n            end\r\n        end\r\n    end\r\nend\r\n            \r\n\r\n\r\n\r\n","published":true,"deleted":false,"likes_count":0,"comments_count":0,"created_by":6204,"edited_by":null,"edited_at":null,"deleted_by":null,"deleted_at":null,"solvers_count":3,"test_suite_updated_at":"2019-01-15T23:13:37.000Z","rescore_all_solutions":false,"group_id":1,"created_at":"2019-01-15T21:20:18.000Z","updated_at":"2019-01-15T23:13:37.000Z","published_at":"2019-01-15T21:20:18.000Z","restored_at":null,"restored_by":null,"spam":false,"simulink":false,"admin_reviewed":false,"description_opc":"{\"relationships\":[{\"relationshipType\":\"http://schemas.mathworks.com/matlab/code/2013/relationships/document\",\"targetMode\":\"\",\"relationshipId\":\"rId1\",\"target\":\"/matlab/document.xml\"},{\"relationshipType\":\"http://schemas.mathworks.com/matlab/code/2013/relationships/output\",\"targetMode\":\"\",\"relationshipId\":\"rId2\",\"target\":\"/matlab/output.xml\"}],\"parts\":[{\"partUri\":\"/matlab/document.xml\",\"relationship\":[],\"contentType\":\"application/vnd.mathworks.matlab.code.document+xml\",\"content\":\"\u003c?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?\u003e\\n\u003cw:document xmlns:w=\\\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\\\"\u003e\u003cw:body\u003e\u003cw:p\u003e\u003cw:pPr\u003e\u003cw:pStyle w:val=\\\"text\\\"/\u003e\u003c/w:pPr\u003e\u003cw:r\u003e\u003cw:t\u003eIn this problem the challenge is to build the Matrix Form equivalent of the function `conv2()` of MATLAB.\u003c/w:t\u003e\u003c/w:r\u003e\u003c/w:p\u003e\u003cw:p\u003e\u003cw:pPr\u003e\u003cw:pStyle w:val=\\\"text\\\"/\u003e\u003c/w:pPr\u003e\u003cw:r\u003e\u003cw:t\u003eThe function to be built will generate a sparse matrix `mK` which is the convolution matrix of the 2D Kernel 'mH' (Which is an input to the function). The input to the function is the 2D Kernel and dimensions of the image to apply the convolution upon and the shape of the convolution ('full', 'same', 'valid' as in 'conv2()').\u003c/w:t\u003e\u003c/w:r\u003e\u003c/w:p\u003e\u003cw:p\u003e\u003cw:pPr\u003e\u003cw:pStyle w:val=\\\"text\\\"/\u003e\u003c/w:pPr\u003e\u003cw:r\u003e\u003cw:t\u003eThe output sparse matrix should match the output of using 'conv2()' on the same image using the same convolution shape.\u003c/w:t\u003e\u003c/w:r\u003e\u003c/w:p\u003e\u003cw:p\u003e\u003cw:pPr\u003e\u003cw:pStyle w:val=\\\"text\\\"/\u003e\u003c/w:pPr\u003e\u003cw:r\u003e\u003cw:t\u003eFor instance:\u003c/w:t\u003e\u003c/w:r\u003e\u003c/w:p\u003e\u003cw:p\u003e\u003cw:pPr\u003e\u003cw:pStyle w:val=\\\"code\\\"/\u003e\u003c/w:pPr\u003e\u003cw:r\u003e\u003cw:t\u003e\u003c![CDATA[CONVOLUTION_SHAPE_FULL  = 1;\\nCONVOLUTION_SHAPE_SAME  = 2;\\nCONVOLUTION_SHAPE_VALID = 3;\\n\\nnumRowsImage = 100;\\nnumColsImage = 80;\\n\\nnumRowsKernel = 7;\\nnumColsKernel = 5;\\n\\nmI = rand(numRowsImage, numColsImage);\\nmH = rand(numRowsKernel, numColsKernel);\\n\\nmaxThr = 1e-9;\\n\\n%%Full Convolution\\n\\nconvShape       = CONVOLUTION_SHAPE_FULL;\\n\\nnumRowsOut = numRowsImage + numRowsKernel - 1;\\nnumColsOut = numColsImage + numColsKernel - 1;\\n\\nmORef   = conv2(mI, mH, 'full');\\nmK      = CreateImageConvMtx(mH, numRowsImage, numColsImage, convShape);\\nmO      = reshape(mK * mI(:), numRowsOut, numColsOut);\\n\\nmE = mO - mORef;\\nassert(max(abs(mE(:))) \u003c maxThr);]]\u003e\u003c/w:t\u003e\u003c/w:r\u003e\u003c/w:p\u003e\u003cw:p\u003e\u003cw:pPr\u003e\u003cw:pStyle w:val=\\\"text\\\"/\u003e\u003c/w:pPr\u003e\u003cw:r\u003e\u003cw:t\u003eThe test case will examine all 3 modes. Try to solve it once with very clear code (No vectorization tricks) and then optimize.\u003c/w:t\u003e\u003c/w:r\u003e\u003c/w:p\u003e\u003cw:p\u003e\u003cw:pPr\u003e\u003cw:pStyle w:val=\\\"text\\\"/\u003e\u003c/w:pPr\u003e\u003cw:r\u003e\u003cw:t\u003eA good way to build the output sparse function is using:\u003c/w:t\u003e\u003c/w:r\u003e\u003c/w:p\u003e\u003cw:p\u003e\u003cw:pPr\u003e\u003cw:pStyle w:val=\\\"code\\\"/\u003e\u003c/w:pPr\u003e\u003cw:r\u003e\u003cw:t\u003e\u003c![CDATA[mK = sparse(vRows, vCols, vVals, numElementsOutputImage, numElementsInputImage);]]\u003e\u003c/w:t\u003e\u003c/w:r\u003e\u003c/w:p\u003e\u003cw:p\u003e\u003cw:pPr\u003e\u003cw:pStyle w:val=\\\"text\\\"/\u003e\u003c/w:pPr\u003e\u003cw:r\u003e\u003cw:t\u003eLook for the documentation of `sparse()` function for more details.\u003c/w:t\u003e\u003c/w:r\u003e\u003c/w:p\u003e\u003c/w:body\u003e\u003c/w:document\u003e\"},{\"partUri\":\"/matlab/output.xml\",\"contentType\":\"text/xml\",\"content\":\"\u003c?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\" standalone=\\\"no\\\" ?\u003e\u003cembeddedOutputs\u003e\u003cmetaData\u003e\u003cevaluationState\u003emanual\u003c/evaluationState\u003e\u003clayoutState\u003ecode\u003c/layoutState\u003e\u003coutputStatus\u003eready\u003c/outputStatus\u003e\u003c/metaData\u003e\u003coutputArray type=\\\"array\\\"/\u003e\u003cregionArray type=\\\"array\\\"/\u003e\u003c/embeddedOutputs\u003e\"}]}"}],"term":"tag:\"matrix form\"","current_player_id":null,"fields":[{"name":"page","type":"integer","callback":null,"default":1,"directive":null,"facet":null,"facet_method":"and","operator":null,"param":null,"static":null,"prepend":true},{"name":"per_page","type":"integer","callback":null,"default":50,"directive":null,"facet":null,"facet_method":"and","operator":null,"param":null,"static":null,"prepend":true},{"name":"sort","type":"string","callback":null,"default":null,"directive":null,"facet":null,"facet_method":"and","operator":null,"param":null,"static":null,"prepend":true},{"name":"body","type":"text","callback":null,"default":"*:*","directive":null,"facet":null,"facet_method":"and","operator":null,"param":"term","static":null,"prepend":false},{"name":"group","type":"string","callback":null,"default":null,"directive":"group","facet":true,"facet_method":"and","operator":null,"param":"term","static":null,"prepend":true},{"name":"difficulty_rating_bin","type":"string","callback":null,"default":null,"directive":"difficulty_rating_bin","facet":true,"facet_method":"and","operator":null,"param":"term","static":null,"prepend":true},{"name":"id","type":"integer","callback":null,"default":null,"directive":"id","facet":null,"facet_method":"and","operator":null,"param":"term","static":null,"prepend":true},{"name":"tag","type":"string","callback":null,"default":null,"directive":"tag","facet":null,"facet_method":"and","operator":null,"param":"term","static":null,"prepend":true},{"name":"product","type":"string","callback":null,"default":null,"directive":"product","facet":null,"facet_method":"and","operator":null,"param":"term","static":null,"prepend":true},{"name":"created_at","type":"timeframe","callback":{},"default":null,"directive":"created_at","facet":null,"facet_method":"and","operator":null,"param":"term","static":null,"prepend":true},{"name":"profile_id","type":"integer","callback":null,"default":null,"directive":"author_id","facet":null,"facet_method":"and","operator":null,"param":"term","static":null,"prepend":true},{"name":"created_by","type":"string","callback":null,"default":null,"directive":"author","facet":null,"facet_method":"and","operator":null,"param":"term","static":null,"prepend":true},{"name":"player_id","type":"integer","callback":null,"default":null,"directive":"solver_id","facet":null,"facet_method":"and","operator":null,"param":"term","static":null,"prepend":true},{"name":"player","type":"string","callback":null,"default":null,"directive":"solver","facet":null,"facet_method":"and","operator":null,"param":"term","static":null,"prepend":true},{"name":"solvers_count","type":"integer","callback":null,"default":null,"directive":"solvers_count","facet":null,"facet_method":"and","operator":null,"param":"term","static":null,"prepend":true},{"name":"comments_count","type":"integer","callback":null,"default":null,"directive":"comments_count","facet":null,"facet_method":"and","operator":null,"param":"term","static":null,"prepend":true},{"name":"likes_count","type":"integer","callback":null,"default":null,"directive":"likes_count","facet":null,"facet_method":"and","operator":null,"param":"term","static":null,"prepend":true},{"name":"leader_id","type":"integer","callback":null,"default":null,"directive":"leader_id","facet":null,"facet_method":"and","operator":null,"param":"term","static":null,"prepend":true},{"name":"leading_solution","type":"integer","callback":null,"default":null,"directive":"leading_solution","facet":null,"facet_method":"and","operator":null,"param":"term","static":null,"prepend":true}],"filters":[{"name":"asset_type","type":"string","callback":null,"default":null,"directive":null,"facet":null,"facet_method":"and","operator":null,"param":null,"static":"\"cody:problem\"","prepend":true},{"name":"profile_id","type":"integer","callback":{},"default":null,"directive":null,"facet":null,"facet_method":"and","operator":null,"param":"author_id","static":null,"prepend":true}],"query":{"params":{"per_page":50,"term":"tag:\"matrix form\"","current_player":null,"sort":"map(difficulty_value,0,0,999) asc"},"parser":"MathWorks::Search::Solr::QueryParser","directives":{"term":{"directives":{"tag":[["tag:\"matrix form\"","","\"","matrix form","\""]]}}},"facets":{"#\u003cMathWorks::Search::Field:0x00007f4f277d0a00\u003e":null,"#\u003cMathWorks::Search::Field:0x00007f4f277d0960\u003e":null},"filters":{"#\u003cMathWorks::Search::Field:0x00007f4f277d00a0\u003e":"\"cody:problem\""},"fields":{"#\u003cMathWorks::Search::Field:0x00007f4f277d0c80\u003e":1,"#\u003cMathWorks::Search::Field:0x00007f4f277d0be0\u003e":50,"#\u003cMathWorks::Search::Field:0x00007f4f277d0b40\u003e":"map(difficulty_value,0,0,999) asc","#\u003cMathWorks::Search::Field:0x00007f4f277d0aa0\u003e":"tag:\"matrix form\""},"user_query":{"#\u003cMathWorks::Search::Field:0x00007f4f277d0aa0\u003e":"tag:\"matrix form\""},"queried_facets":{}},"query_backend":{"connection":{"configuration":{"index_url":"http://index-op-v2/solr/","query_url":"http://search-op-v2/solr/","direct_access_index_urls":["http://index-op-v2/solr/"],"direct_access_query_urls":["http://search-op-v2/solr/"],"timeout":10,"vhost":"search","exchange":"search.topic","heartbeat":30,"pre_index_mode":false,"host":"rabbitmq-eks","port":5672,"username":"search","password":"J3bGPZzQ7asjJcCk","virtual_host":"search","indexer":"amqp","http_logging":"true","core":"cody"},"query_connection":{"uri":"http://search-op-v2/solr/cody/","proxy":null,"connection":{"parallel_manager":null,"headers":{"User-Agent":"Faraday v1.0.1"},"params":{},"options":{"params_encoder":"Faraday::FlatParamsEncoder","proxy":null,"bind":null,"timeout":null,"open_timeout":null,"read_timeout":null,"write_timeout":null,"boundary":null,"oauth":null,"context":null,"on_data":null},"ssl":{"verify":true,"ca_file":null,"ca_path":null,"verify_mode":null,"cert_store":null,"client_cert":null,"client_key":null,"certificate":null,"private_key":null,"verify_depth":null,"version":null,"min_version":null,"max_version":null},"default_parallel_manager":null,"builder":{"adapter":{"name":"Faraday::Adapter::NetHttp","args":[],"block":null},"handlers":[{"name":"Faraday::Response::RaiseError","args":[],"block":null}],"app":{"app":{"ssl_cert_store":{"verify_callback":null,"error":null,"error_string":null,"chain":null,"time":null},"app":{},"connection_options":{},"config_block":null}}},"url_prefix":"http://search-op-v2/solr/cody/","manual_proxy":false,"proxy":null},"update_format":"RSolr::JSON::Generator","update_path":"update","options":{"url":"http://search-op-v2/solr/cody"}}},"query":{"params":{"per_page":50,"term":"tag:\"matrix form\"","current_player":null,"sort":"map(difficulty_value,0,0,999) asc"},"parser":"MathWorks::Search::Solr::QueryParser","directives":{"term":{"directives":{"tag":[["tag:\"matrix form\"","","\"","matrix form","\""]]}}},"facets":{"#\u003cMathWorks::Search::Field:0x00007f4f277d0a00\u003e":null,"#\u003cMathWorks::Search::Field:0x00007f4f277d0960\u003e":null},"filters":{"#\u003cMathWorks::Search::Field:0x00007f4f277d00a0\u003e":"\"cody:problem\""},"fields":{"#\u003cMathWorks::Search::Field:0x00007f4f277d0c80\u003e":1,"#\u003cMathWorks::Search::Field:0x00007f4f277d0be0\u003e":50,"#\u003cMathWorks::Search::Field:0x00007f4f277d0b40\u003e":"map(difficulty_value,0,0,999) asc","#\u003cMathWorks::Search::Field:0x00007f4f277d0aa0\u003e":"tag:\"matrix form\""},"user_query":{"#\u003cMathWorks::Search::Field:0x00007f4f277d0aa0\u003e":"tag:\"matrix form\""},"queried_facets":{}},"options":{"fields":["id","difficulty_rating"]},"join":" "},"results":[{"id":44832,"difficulty_rating":"unrated"}]}}