From 814545b187af73abdc6a8d2c6b7b4d813679b1d2 Mon Sep 17 00:00:00 2001 From: Ryan Harvey Date: Sun, 20 Oct 2024 14:02:45 -0400 Subject: [PATCH 01/11] Create ci.yml --- .github/workflows/ci.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..02de573 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,24 @@ +name: MATLAB CI + +on: + push: + branches: + - add-CI + pull_request: + branches: + - add-CI + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Set up MATLAB + uses: matlab-actions/setup-matlab@v1 + + - name: Run MATLAB tests + run: | + matlab -batch "results = runtests('test', 'IncludeSubfolders', true); assertSuccess(results);" From e56e4e17fdd99c220a5952b8c69af2bc98ae70f7 Mon Sep 17 00:00:00 2001 From: Ryan Harvey Date: Sun, 20 Oct 2024 14:07:26 -0400 Subject: [PATCH 02/11] add all to path --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 02de573..c6e3577 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,4 +21,4 @@ jobs: - name: Run MATLAB tests run: | - matlab -batch "results = runtests('test', 'IncludeSubfolders', true); assertSuccess(results);" + matlab -batch "addpath(genpath('neurocode')); results = runtests('test', 'IncludeSubfolders', true); assertSuccess(results);" From 8b9415c17e2c98f23531c917fe999f8d0156af33 Mon Sep 17 00:00:00 2001 From: Ryan Harvey Date: Sun, 20 Oct 2024 14:14:41 -0400 Subject: [PATCH 03/11] cd to neurocode before tests --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c6e3577..5d98511 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,4 +21,5 @@ jobs: - name: Run MATLAB tests run: | - matlab -batch "addpath(genpath('neurocode')); results = runtests('test', 'IncludeSubfolders', true); assertSuccess(results);" + cd neurocode + matlab -batch "addpath(genpath('.')); results = runtests('test', 'IncludeSubfolders', true); assertSuccess(results);" From d52c95e65308636c633529fbfef77e03aa1155fa Mon Sep 17 00:00:00 2001 From: Ryan Harvey Date: Sun, 20 Oct 2024 14:17:13 -0400 Subject: [PATCH 04/11] debugging to check directory --- .github/workflows/ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5d98511..dcab43f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,9 @@ jobs: - name: Set up MATLAB uses: matlab-actions/setup-matlab@v1 + - name: List directory contents (debug step) + run: ls -R + - name: Run MATLAB tests run: | - cd neurocode matlab -batch "addpath(genpath('.')); results = runtests('test', 'IncludeSubfolders', true); assertSuccess(results);" From 9f1e2dd3a7f482b29c307a1ec568f7dfa490b81e Mon Sep 17 00:00:00 2001 From: Ryan Harvey Date: Sun, 20 Oct 2024 14:40:33 -0400 Subject: [PATCH 05/11] compile mex before tests --- .github/workflows/ci.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dcab43f..14827aa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,8 +19,10 @@ jobs: - name: Set up MATLAB uses: matlab-actions/setup-matlab@v1 - - name: List directory contents (debug step) - run: ls -R + - name: Compile MEX files + run: | + matlab -batch "cd utilities/intervalsC+; mex CountInIntervals.c; mex FindInInterval.c; mex MatchUpIndices.c" + matlab -batch "cd utilities/mapsC+; mex Contiguous.c; mex FindField.c" - name: Run MATLAB tests run: | From df75fe5097cf54b0579e1ac7b3334311852d4a11 Mon Sep 17 00:00:00 2001 From: Ryan Harvey Date: Sun, 20 Oct 2024 14:52:23 -0400 Subject: [PATCH 06/11] try TestSuite, runtests only detects first file --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 14827aa..e58ebd7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,4 +26,4 @@ jobs: - name: Run MATLAB tests run: | - matlab -batch "addpath(genpath('.')); results = runtests('test', 'IncludeSubfolders', true); assertSuccess(results);" + matlab -batch "addpath(genpath('.')); suite = TestSuite.fromFolder('test', 'IncludeSubfolders', true); results = run(suite); assertSuccess(results);" From fd582bb52e2144d6734280bab5de1d1b84b707af Mon Sep 17 00:00:00 2001 From: Ryan Harvey Date: Sun, 20 Oct 2024 18:09:33 -0400 Subject: [PATCH 07/11] Update ci.yml --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e58ebd7..dc5dd08 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,4 +26,4 @@ jobs: - name: Run MATLAB tests run: | - matlab -batch "addpath(genpath('.')); suite = TestSuite.fromFolder('test', 'IncludeSubfolders', true); results = run(suite); assertSuccess(results);" + matlab -batch "addpath(genpath('.')); results = runtests('test'); assertSuccess(results);" From 7e62e3931cd9ed50826b89b83b1d411293b352f8 Mon Sep 17 00:00:00 2001 From: Ryan Harvey Date: Sun, 20 Oct 2024 18:10:28 -0400 Subject: [PATCH 08/11] update union, plus, setdiff --- core/IntervalArray.m | 191 +++++++++++++++++++++++-------------------- 1 file changed, 103 insertions(+), 88 deletions(-) diff --git a/core/IntervalArray.m b/core/IntervalArray.m index 12b2676..7eff468 100644 --- a/core/IntervalArray.m +++ b/core/IntervalArray.m @@ -315,54 +315,50 @@ function disp(obj) function new = union(obj, other) - if isa(other, 'IntervalArray') - intervals_ = obj.intervals; - other_intervals = other.intervals; - % check if intervals and other_intervals are not empty - if ~isempty(intervals_) && ~isempty(other_intervals) - i = 1; - j = 1; - while (i <= size(intervals_, 1) && j <= size(other_intervals, 1)) - if (intervals_(i, 1) < other_intervals(j, 1)) - if (intervals_(i, 2) < other_intervals(j, 1)) - i = i + 1; - else - if (intervals_(i, 2) < other_intervals(j, 2)) - intervals_(i, 2) = other_intervals(j, 2); - j = j + 1; - else - j = j + 1; - end - end - else - if (other_intervals(j, 2) < intervals_(i, 1)) - j = j + 1; - else - if (other_intervals(j, 2) < intervals_(i, 2)) - intervals_ = [intervals_(1:i-1, :); ... - other_intervals(j, :); intervals_(i:end, :)]; - i = i + 1; - j = j + 1; - else - intervals_(i, 1) = other_intervals(j, 1); - j = j + 1; - end - end - end - end - if (j <= size(other_intervals, 1)) - intervals_ = [intervals_; other_intervals(j:end, :)]; - end - elseif isempty(intervals_) - intervals_ = other_intervals; - end - new = IntervalArray(intervals_); - else + if ~isa(other, 'IntervalArray') error("unsupported operand type(s) for union: %s and %s", ... class(obj), class(other)); end + + intervals_ = obj.intervals; + other_intervals = other.intervals; + + % Check if intervals and other_intervals are not empty + if isempty(intervals_) && isempty(other_intervals) + new = IntervalArray([]); + return; + elseif isempty(intervals_) + new = IntervalArray(other_intervals); + return; + elseif isempty(other_intervals) + new = IntervalArray(intervals_); + return; + end + + % Combine and sort intervals + combined_intervals = [intervals_; other_intervals]; + combined_intervals = sortrows(combined_intervals, 1); % Sort by start time + + % Initialize merged intervals + merged_intervals = combined_intervals(1, :); % Start with the first interval + + for i = 2:size(combined_intervals, 1) + current_interval = combined_intervals(i, :); + last_merged_interval = merged_intervals(end, :); + + if current_interval(1) <= last_merged_interval(2) % Overlapping or adjacent intervals + % Merge intervals + merged_intervals(end, 2) = max(last_merged_interval(2), current_interval(2)); + else + % No overlap, just add the current interval + merged_intervals = [merged_intervals; current_interval]; + end + end + + new = IntervalArray(merged_intervals); end + function new = complement(obj) new = IntervalArray(); % Get intervals @@ -390,67 +386,86 @@ function disp(obj) end end + function new = plus(obj, other) if isa(other, 'IntervalArray') - new = IntervalArray(); + % Combine the current intervals with the other intervals intervals_ = obj.intervals; other_intervals = other.intervals; - % check if intervals and other_intervals are not empty - if ~isempty(intervals_) && ~isempty(other_intervals) - new_intervals = [intervals_; other_intervals]; - new_intervals = sortrows(new_intervals); - new.intervals = new_intervals; - elseif isempty(intervals_) - new = other; + + % Concatenate intervals from both arrays + all_intervals = [intervals_; other_intervals]; + + % Sort intervals by the start time + all_intervals = sortrows(all_intervals); + + % Initialize the merged intervals + merged_intervals = []; + + % Merge overlapping intervals + for i = 1:size(all_intervals, 1) + if isempty(merged_intervals) || merged_intervals(end, 2) < all_intervals(i, 1) + % No overlap, add the interval + merged_intervals = [merged_intervals; all_intervals(i, :)]; + else + % Overlap, merge intervals + merged_intervals(end, 2) = max(merged_intervals(end, 2), all_intervals(i, 2)); + end end + + new = IntervalArray(merged_intervals); else - error("unsupported operand type(s) for +: %s and %s", ... + error("unsupported operand type(s) for plus: %s and %s", ... class(obj), class(other)); end end + + + + function new = setdiff(obj, other) - if isa(other, 'IntervalArray') - new = IntervalArray(); - other_intervals = other.intervals; - intervals_ = obj.intervals; - % loop through the intervals of other - for i = 1:size(other_intervals, 1) - % loop through the intervals of the object - j = 1; - for jj = 1:size(intervals_, 1) - if (intervals_(j, 1) >= other_intervals(i, 1) && ... - intervals_(j, 2) <= other_intervals(i, 2)) - % interval is completely inside the other interval - intervals_(j, :) = []; - continue - elseif (intervals_(j, 1) < other_intervals(i, 1) && ... - intervals_(j, 2) > other_intervals(i, 1) && ... - intervals_(j, 2) <= other_intervals(i, 2)) - % interval starts before and ends inside the other interval - intervals_(j, 2) = other_intervals(i, 1); - elseif (intervals_(j, 1) >= other_intervals(i, 1) && ... - intervals_(j, 1) < other_intervals(i, 2) && ... - intervals_(j, 2) > other_intervals(i, 2)) - % interval starts inside and ends after the other interval - intervals_(j, 1) = other_intervals(i, 2); - elseif (intervals_(j, 1) < other_intervals(i, 1) && ... - intervals_(j, 2) > other_intervals(i, 2)) - % interval starts before and ends after the other interval - new_interval = [other_intervals(i, 2), intervals_(j, 2)]; - intervals_(j, 2) = other_intervals(i, 1); - intervals_ = [intervals_; new_interval]; - end - j = j + 1; - end - end - new.intervals = intervals_; - else + if ~isa(other, 'IntervalArray') error("unsupported operand type(s) for setdiff: %s and %s", ... class(obj), class(other)); end + + intervals_ = obj.intervals; + other_intervals = other.intervals; + + if isempty(intervals_) + new = IntervalArray([]); + return; + elseif isempty(other_intervals) + new = IntervalArray(intervals_); + return; + end + + new_intervals = []; % Initialize the result array + + for i = 1:size(intervals_, 1) + interval = intervals_(i, :); + is_overlapping = false; + + for j = 1:size(other_intervals, 1) + other_interval = other_intervals(j, :); + + % Check if there is an overlap + if (interval(1) < other_interval(2)) && (other_interval(1) < interval(2)) + is_overlapping = true; + break; % No need to check further + end + end + + if ~is_overlapping + new_intervals = [new_intervals; interval]; % Keep this interval + end + end + + new = IntervalArray(new_intervals); end + function out = plot(obj, varargin) if isempty(varargin) yLim = ylim; From a72e17427b4e3aba9775163ac77e90846653dca5 Mon Sep 17 00:00:00 2001 From: Ryan Harvey Date: Sun, 20 Oct 2024 18:11:08 -0400 Subject: [PATCH 09/11] convert to format understood by runtests --- test/test_IntervalArray.m | 241 ++++++++++++++++++++++++-------------- test/test_SpikeArray.m | 115 +++++++++++------- test/test_regress_out.m | 48 ++++---- 3 files changed, 251 insertions(+), 153 deletions(-) diff --git a/test/test_IntervalArray.m b/test/test_IntervalArray.m index e6c5557..c604776 100644 --- a/test/test_IntervalArray.m +++ b/test/test_IntervalArray.m @@ -1,90 +1,151 @@ -function test_IntervalArray() - % Test constructor - myIntervalArray = IntervalArray([0,5;10,15]); - assert(isequal(myIntervalArray.intervals,[0,5;10,15]),'Error: constructor not working'); - - % Test validate_intervals - myIntervalArray.intervals = [10,5;10,15]; - try - myIntervalArray.validate_intervals(); - error('Error: validate_intervals not working') - catch - end - - % Test sort - myIntervalArray.intervals = [10,15;0,5]; - myIntervalArray.sort(); - assert(isequal(myIntervalArray.intervals,[0,5;10,15]),'Error: sort not working'); - - % Test starts - assert(isequal(myIntervalArray.starts(),[0;10]),'Error: starts not working'); - - % Test stops - assert(isequal(myIntervalArray.stops(),[5;15]),'Error: stops not working'); - - % Test n_intervals - assert(isequal(myIntervalArray.n_intervals(),2),'Error: n_intervals not working'); - - % Test expand - myIntervalArray = myIntervalArray.expand(1); - assert(isequal(myIntervalArray.intervals,[-1,6;9,16]),'Error: expand not working'); - - % Test isempty - assert(isequal(myIntervalArray.isempty(),false),'Error: isempty not working'); - - % Test lengths - assert(isequal(myIntervalArray.lengths(),[7;7]),'Error: lengths not working'); - - % Test duration - assert(isequal(myIntervalArray.duration(),14),'Error: duration not working'); - - % Test intersect - otherIntervalArray = IntervalArray([-2,2;8,12]); - myIntervalArray = myIntervalArray.intersect(otherIntervalArray); - assert(isequal(myIntervalArray.intervals,[-1,2;9,12]),'Error: intersect not working'); - - % Test union - otherIntervalArray = IntervalArray([-2,2;8,12]); - myIntervalArray = myIntervalArray.union(otherIntervalArray); - assert(isequal(myIntervalArray.intervals,[-2,2;8,12]),'Error: union not working'); - - % Test setdiff - otherIntervalArray = IntervalArray([-2,2;18,20]); - myIntervalArray = myIntervalArray.setdiff(otherIntervalArray); - assert(isequal(myIntervalArray.intervals,[8,12]),'Error: setdiff not working'); - - % Test complement - myIntervalArray = myIntervalArray.complement(); - assert(isequal(myIntervalArray.intervals,[-inf,8;12,inf]),'Error: complement not working'); - - % Test merge - myIntervalArray = IntervalArray([10,20;15,25]); - myIntervalArray = myIntervalArray.merge(); - assert(isequal(myIntervalArray.intervals,[10,25]),'Error: merge not working'); - - % Test plus - otherIntervalArray = IntervalArray([-2,2;8,12]); - myIntervalArray = myIntervalArray.plus(otherIntervalArray); - assert(isequal(myIntervalArray.intervals,[-2,2;8,12;10,25]),'Error: plus not working'); - - % Test remove_empty - myIntervalArray = IntervalArray([0,2;5,5;8,12]); - myIntervalArray = myIntervalArray.remove_empty(); - assert(isequal(myIntervalArray.intervals,[0,2;8,12]),'Error: remove_empty not working'); - - % Test eq - myIntervalArray = IntervalArray([0,2;8,12]); - otherIntervalArray = IntervalArray([0,2;8,12]); - is_equal = myIntervalArray.eq(otherIntervalArray); - assert(isequal(is_equal,true),'Error: eq not working'); - - % Test in - myIntervalArray = IntervalArray([0,2;8,12]); - point = 9; - contain = myIntervalArray.in(point); - assert(isequal(contain,true),'Error: in not working'); - - % Test empty interval - myIntervalArray = IntervalArray([]); - assert(isequal(myIntervalArray.isempty,true),'Error: empty intervals not working'); -end \ No newline at end of file +function tests = test_IntervalArray +% Create a test suite for the IntervalArray class +tests = functiontests(localfunctions); +end + +function testConstructor(testCase) +% Test constructor +myIntervalArray = IntervalArray([0, 5; 10, 15]); +verifyEqual(testCase, myIntervalArray.intervals, [0, 5; 10, 15], 'Error: constructor not working'); +end + +function testValidateIntervals(testCase) +% Test validate_intervals +myIntervalArray = IntervalArray([0, 5; 10, 15]); +myIntervalArray.intervals = [10, 5; 10, 15]; +% Try to validate intervals and catch any error +try + myIntervalArray.validate_intervals(); + % If no error is thrown, the test should fail + testCase.verifyFail('Expected an error but did not receive one.'); +catch ME + % Check if the caught error message is the expected one + testCase.verifyEqual(ME.message, 'Invalid intervals: start time must be less than end time', ... + 'Error: validate_intervals did not throw the expected message.'); +end +end + +function testSort(testCase) +% Test sort +myIntervalArray = IntervalArray([10, 15; 0, 5]); +myIntervalArray.sort(); +verifyEqual(testCase, myIntervalArray.intervals, [0, 5; 10, 15], 'Error: sort not working'); +end + +function testStarts(testCase) +% Test starts +myIntervalArray = IntervalArray([0, 5; 10, 15]); +verifyEqual(testCase, myIntervalArray.starts(), [0; 10], 'Error: starts not working'); +end + +function testStops(testCase) +% Test stops +myIntervalArray = IntervalArray([0, 5; 10, 15]); +verifyEqual(testCase, myIntervalArray.stops(), [5; 15], 'Error: stops not working'); +end + +function testNIntervals(testCase) +% Test n_intervals +myIntervalArray = IntervalArray([0, 5; 10, 15]); +verifyEqual(testCase, myIntervalArray.n_intervals(), 2, 'Error: n_intervals not working'); +end + +function testExpand(testCase) +% Test expand +myIntervalArray = IntervalArray([0, 5; 10, 15]); +myIntervalArray = myIntervalArray.expand(1); +verifyEqual(testCase, myIntervalArray.intervals, [-1, 6; 9, 16], 'Error: expand not working'); +end + +function testIsEmpty(testCase) +% Test isempty +myIntervalArray = IntervalArray([0, 5; 10, 15]); +verifyEqual(testCase, myIntervalArray.isempty(), false, 'Error: isempty not working'); +end + +function testLengths(testCase) +% Test lengths +myIntervalArray = IntervalArray([0, 5; 10, 15]); +verifyEqual(testCase, myIntervalArray.lengths(), [5; 5], 'Error: lengths not working'); +end + +function testDuration(testCase) +% Test duration +myIntervalArray = IntervalArray([0, 5; 10, 15]); +verifyEqual(testCase, myIntervalArray.duration(), 10, 'Error: duration not working'); +end + +function testIntersect(testCase) +% Test intersect +myIntervalArray = IntervalArray([0, 5; 10, 15]); +otherIntervalArray = IntervalArray([-2, 2; 8, 12]); +myIntervalArray = myIntervalArray.intersect(otherIntervalArray); +verifyEqual(testCase, myIntervalArray.intervals, [0, 2; 10, 12], 'Error: intersect not working'); +end + +function testUnion(testCase) +% Test union +myIntervalArray = IntervalArray([0, 5; 10, 15]); +otherIntervalArray = IntervalArray([-2, 2; 8, 12]); +myIntervalArray = myIntervalArray.union(otherIntervalArray); +verifyEqual(testCase, myIntervalArray.intervals, [-2, 5; 8, 15], 'Error: union not working'); +end + +function testSetDiff(testCase) +% Test setdiff +myIntervalArray = IntervalArray([0, 5; 10, 15]); +otherIntervalArray = IntervalArray([-2, 2; 18, 20]); +myIntervalArray = myIntervalArray.setdiff(otherIntervalArray); +verifyEqual(testCase, myIntervalArray.intervals, [10, 15], 'Error: setdiff not working'); +end + +function testComplement(testCase) +% Test complement +myIntervalArray = IntervalArray([0, 5; 10, 15]); +myIntervalArray = myIntervalArray.complement(); +verifyEqual(testCase, myIntervalArray.intervals, [-inf, 0; 5, 10; 15, inf], 'Error: complement not working'); +end + +function testMerge(testCase) +% Test merge +myIntervalArray = IntervalArray([10, 20; 15, 25]); +myIntervalArray = myIntervalArray.merge(); +verifyEqual(testCase, myIntervalArray.intervals, [10, 25], 'Error: merge not working'); +end + +function testPlus(testCase) +% Test plus +myIntervalArray = IntervalArray([10, 20; 15, 25]); +otherIntervalArray = IntervalArray([-2, 2; 8, 12]); +myIntervalArray = myIntervalArray.plus(otherIntervalArray); +verifyEqual(testCase, myIntervalArray.intervals, [-2, 2; 8, 25], 'Error: plus not working'); +end + +function testRemoveEmpty(testCase) +% Test remove_empty +myIntervalArray = IntervalArray([0, 2; 5, 5; 8, 12]); +myIntervalArray = myIntervalArray.remove_empty(); +verifyEqual(testCase, myIntervalArray.intervals, [0, 2; 8, 12], 'Error: remove_empty not working'); +end + +function testEq(testCase) +% Test eq +myIntervalArray = IntervalArray([0, 2; 8, 12]); +otherIntervalArray = IntervalArray([0, 2; 8, 12]); +is_equal = myIntervalArray.eq(otherIntervalArray); +verifyEqual(testCase, is_equal, true, 'Error: eq not working'); +end + +function testIn(testCase) +% Test in +myIntervalArray = IntervalArray([0, 2; 8, 12]); +point = 9; +contain = myIntervalArray.in(point); +verifyEqual(testCase, contain, true, 'Error: in not working'); +end + +function testEmptyInterval(testCase) +% Test empty interval +myIntervalArray = IntervalArray([]); +verifyEqual(testCase, myIntervalArray.isempty(), true, 'Error: empty intervals not working'); +end diff --git a/test/test_SpikeArray.m b/test/test_SpikeArray.m index ed8dd8a..e57ecd1 100644 --- a/test/test_SpikeArray.m +++ b/test/test_SpikeArray.m @@ -1,73 +1,106 @@ -function test_SpikeArray() +function tests = test_SpikeArray + % Create a test suite for the SpikeArray class + tests = functiontests(localfunctions); +end + +function testConstructor(testCase) % Test SpikeArray constructor spikes_cell = {[1, 2, 3], [4, 5, 6], [7, 8, 9]}; spike_array = SpikeArray(spikes_cell); - assert(isequal(spike_array.spikes, [1, 2, 3, 4, 5, 6, 7, 8, 9])); - assert(isequal(spike_array.uid, [1, 1, 1, 2, 2, 2, 3, 3, 3])); + verifyEqual(testCase, spike_array.spikes, [1, 2, 3, 4, 5, 6, 7, 8, 9], 'Error: SpikeArray constructor not working'); + verifyEqual(testCase, spike_array.uid, [1, 1, 1, 2, 2, 2, 3, 3, 3], 'Error: UID not working'); uid = [1, 1, 3, 1, 3]; spike_array = SpikeArray([1, 2, 3, 4, 5], uid); - assert(isequal(spike_array.spikes, [1, 2, 3, 4, 5])); - assert(isequal(spike_array.uid, uid)); + verifyEqual(testCase, spike_array.spikes, [1, 2, 3, 4, 5], 'Error: SpikeArray constructor with UID not working'); + verifyEqual(testCase, spike_array.uid, uid, 'Error: UID not working'); +end +function testRestrict(testCase) % Test restrict method - spikes_cell = {[1, 2, 3], [4, 5, 6], [7, 8, 9]}; - spike_array = SpikeArray(spikes_cell); interval_array = IntervalArray([3, 5; 7, 10]); + spike_array = SpikeArray({[1, 2, 3], [4, 5, 6], [7, 8, 9]}); restricted_spike_array = spike_array(interval_array); - assert(isequal(restricted_spike_array.spikes, [3, 4, 5, 7, 8, 9])); - assert(isequal(restricted_spike_array.uid, [1, 2, 2, 3, 3, 3])); + verifyEqual(testCase, restricted_spike_array.spikes, [3, 4, 5, 7, 8, 9], 'Error: restrict method not working'); + verifyEqual(testCase, restricted_spike_array.uid, [1, 2, 2, 3, 3, 3], 'Error: restrict method UID not working'); +end +function testNCells(testCase) % Test n_cells method - assert(spike_array.n_cells() == 3); + spike_array = SpikeArray({[1, 2, 3], [4, 5, 6], [7, 8, 9]}); + verifyEqual(testCase, spike_array.n_cells(), 3, 'Error: n_cells not working'); +end +function testIds(testCase) % Test ids method - assert(isequal(spike_array.ids(), [1, 2, 3]')); + spike_array = SpikeArray({[1, 2, 3], [4, 5, 6], [7, 8, 9]}); + verifyEqual(testCase, spike_array.ids(), [1, 2, 3]', 'Error: ids not working'); +end +function testNSpikes(testCase) % Test n_spikes method - assert(isequal(spike_array.n_spikes(), [3, 3, 3]')); + spike_array = SpikeArray({[1, 2, 3], [4, 5, 6], [7, 8, 9]}); + verifyEqual(testCase, spike_array.n_spikes(), [3, 3, 3]', 'Error: n_spikes not working'); +end +function testFirstEvent(testCase) % Test first_event method - assert(spike_array.first_event() == 1); + spike_array = SpikeArray({[1, 2, 3], [4, 5, 6], [7, 8, 9]}); + verifyEqual(testCase, spike_array.first_event(), 1, 'Error: first_event not working'); +end +function testLastEvent(testCase) % Test last_event method - assert(spike_array.last_event() == 9); + spike_array = SpikeArray({[1, 2, 3], [4, 5, 6], [7, 8, 9]}); + verifyEqual(testCase, spike_array.last_event(), 9, 'Error: last_event not working'); +end +function testIsSorted(testCase) % Test issorted method - assert(spike_array.issorted() == 1); + spike_array = SpikeArray({[1, 2, 3], [4, 5, 6], [7, 8, 9]}); + verifyEqual(testCase, spike_array.issorted(), true, 'Error: issorted not working'); +end +function testIsEmpty(testCase) % Test isempty method - assert(spike_array.isempty() == 0); - + spike_array = SpikeArray({[1, 2, 3], [4, 5, 6], [7, 8, 9]}); + verifyEqual(testCase, spike_array.isempty(), false, 'Error: isempty not working'); +end + +function testCellSelection(testCase) % Test cell selection method + spike_array = SpikeArray({[1, 2, 3], [4, 5, 6], [7, 8, 9]}); first_cell_array = spike_array(1); - assert(first_cell_array.n_cells() == 3); - assert(first_cell_array.n_active_cells() == 1); - assert(all(first_cell_array.ids() == [1,2,3]')); - assert(all(first_cell_array.n_spikes() == [3,0,0]')); - assert(first_cell_array.first_event() == 1); - assert(first_cell_array.last_event() == 3); - assert(first_cell_array.issorted() == 1); - assert(first_cell_array.isempty() == 0); - + verifyEqual(testCase, first_cell_array.n_cells(), 3, 'Error: cell selection n_cells not working'); + verifyEqual(testCase, first_cell_array.n_active_cells(), 1, 'Error: cell selection n_active_cells not working'); + verifyEqual(testCase, first_cell_array.ids(), [1, 2, 3]', 'Error: cell selection ids not working'); + verifyEqual(testCase, first_cell_array.n_spikes(), [3, 0, 0]', 'Error: cell selection n_spikes not working'); + verifyEqual(testCase, first_cell_array.first_event(), 1, 'Error: cell selection first_event not working'); + verifyEqual(testCase, first_cell_array.last_event(), 3, 'Error: cell selection last_event not working'); + verifyEqual(testCase, first_cell_array.issorted(), true, 'Error: cell selection issorted not working'); + verifyEqual(testCase, first_cell_array.isempty(), false, 'Error: cell selection isempty not working'); +end + +function testBin(testCase) % Test bin - spikes_cell = {[1, 2, 3], [4, 5, 6], [7, 8, 9]}; - spike_array = SpikeArray(spikes_cell); - bst = spike_array.bin('ds',1); - X = [1,0,0;... - 1,0,0;... - 1,0,0;... - 0,1,0;... - 0,1,0;... - 0,1,0;... - 0,0,1;... - 0,0,1;... - 0,0,1]; - assert(isequal(bst.data,X)) - + spike_array = SpikeArray({[1, 2, 3], [4, 5, 6], [7, 8, 9]}); + bst = spike_array.bin('ds', 1); + X = [1, 0, 0;... + 1, 0, 0;... + 1, 0, 0;... + 0, 1, 0;... + 0, 1, 0;... + 0, 1, 0;... + 0, 0, 1;... + 0, 0, 1;... + 0, 0, 1]; + verifyEqual(testCase, bst.data, X, 'Error: bin method not working'); +end + +function testToCellArray(testCase) % Test to_cell_array spikes_cell = {[1, 2, 3], [4, 5, 6], [7, 8, 9]}; spike_array = SpikeArray(spikes_cell); spikes_cell_2 = spike_array.to_cell_array(); - assert(isequal(spikes_cell,spikes_cell_2)) + verifyEqual(testCase, spikes_cell, spikes_cell_2, 'Error: to_cell_array not working'); end diff --git a/test/test_regress_out.m b/test/test_regress_out.m index 4a18323..5cf88f2 100644 --- a/test/test_regress_out.m +++ b/test/test_regress_out.m @@ -1,26 +1,30 @@ -function test_regress_out() - % Test case 1 - a = [1 2 3 4 5]; - b = [2 4 6 8 10]; - expected_result = double([3.0 3.0 3.0 3.0 3.0]); - result = regress_out(a, b); - assert(all(abs(result-expected_result) < 1e4*eps(min(abs(result),abs(expected_result)))), 'Test case 1 failed.'); +function tests = test_regress_out +% Create a test suite for the regress_out function +tests = functiontests(localfunctions); +end - % Test case 2 - a = [1 2 3 4 5]; - b = [0 0 0 0 0]; - expected_result = [1 2 3 4 5]; - result = regress_out(a, b); - assert(all(abs(result-expected_result) < 1e4*eps(min(abs(result),abs(expected_result)))), 'Test case 2 failed.'); +function testCase1(testCase) +a = [1, 2, 3, 4, 5]; +b = [2, 4, 6, 8, 10]; +expected_result = double([3.0, 3.0, 3.0, 3.0, 3.0]); +result = regress_out(a, b); +verifyEqual(testCase, result, expected_result, 'AbsTol', 1e-4, 'Test case 1 failed.'); +end - % Test case 3 - a = [1 2 3 4 5]; - b = [1 1 1 1 1]; - expected_result = [1 2 3 4 5]; - result = regress_out(a, b); - assert(all(abs(result-expected_result) < 1e4*eps(min(abs(result),abs(expected_result)))), 'Test case 3 failed.'); +function testCase2(testCase) +a = [1, 2, 3, 4, 5]; +b = [0, 0, 0, 0, 0]; +expected_result = [1, 2, 3, 4, 5]; +result = regress_out(a, b); +verifyEqual(testCase, result, expected_result, 'AbsTol', 1e-4, 'Test case 2 failed.'); +end - % Add more test cases as needed +function testCase3(testCase) +a = [1, 2, 3, 4, 5]; +b = [1, 1, 1, 1, 1]; +expected_result = [1, 2, 3, 4, 5]; +result = regress_out(a, b); +verifyEqual(testCase, result, expected_result, 'AbsTol', 1e-4, 'Test case 3 failed.'); +end - disp('All test cases passed.'); -end \ No newline at end of file +% Add more test functions as needed From 7195e1a96ee07d46c9264834d81a0044c9a8edf5 Mon Sep 17 00:00:00 2001 From: Ryan Harvey Date: Sun, 20 Oct 2024 18:14:21 -0400 Subject: [PATCH 10/11] matlab v2 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dc5dd08..e437b0a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: uses: actions/checkout@v2 - name: Set up MATLAB - uses: matlab-actions/setup-matlab@v1 + uses: matlab-actions/setup-matlab@v2 - name: Compile MEX files run: | From 9d410d0c86da058440c72ff46e61cad8a363c640 Mon Sep 17 00:00:00 2001 From: Ryan Harvey Date: Sun, 20 Oct 2024 18:17:34 -0400 Subject: [PATCH 11/11] Revert "matlab v2" This reverts commit 7195e1a96ee07d46c9264834d81a0044c9a8edf5. --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e437b0a..dc5dd08 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: uses: actions/checkout@v2 - name: Set up MATLAB - uses: matlab-actions/setup-matlab@v2 + uses: matlab-actions/setup-matlab@v1 - name: Compile MEX files run: |