Generating days based on leap years
이 질문을 팔로우합니다.
- 팔로우하는 게시물 피드에서 업데이트를 확인할 수 있습니다.
- 정보 수신 기본 설정에 따라 이메일을 받을 수 있습니다.
오류 발생
페이지가 변경되었기 때문에 동작을 완료할 수 없습니다. 업데이트된 상태를 보려면 페이지를 다시 불러오십시오.
이전 댓글 표시
0 개 추천
Hi,
I wanted to generate a matrix like below. Basically, years in the first column, start days, end days for the year by conditional check of first column. Fourth row is basically MOD function to check if a leap year or not.
1960 1 366 366
1961 367 731 365
1962 732 1096 365
1963 1097 1461 365
1964 1462 1827 366
1965 1828 2192 365
1966 2193 2557 365
. . . .
2014
Does anybody have an idea?
Thanks in advance.
채택된 답변
Star Strider
2014년 9월 16일
There may be more efficient approaches, but this works:
yr = [1960:2014]';
lpyr = (mod(yr,4)==0);
dpy = ones(size(yr))*365+lpyr;
csd = cumsum(dpy);
M = [yr [1; csd(1:end-1)+1] csd dpy];
댓글 수: 12
Damith
2014년 9월 16일
Thanks a lot.
Star Strider
2014년 9월 16일
My pleasure!
Honglei Chen
2014년 9월 16일
Just to add one little remark, the algorithm definitely works but the leap year computation is a little more than an integer multiple of 4. It also cannot be an integer multiple of 100 yet an integer multiple of 400 is ok.
Star Strider
2014년 9월 16일
@Honglei — Correct. I considered that. We were lucky in this series in that 2000 was a leap year, so I didn’t include that logic here.
Damith
2014년 9월 17일
Thanks guys for valuable comments.
The new chanlenge I facing at the moment is to dynamically create the array for varying number of years (start year and end year are different)
Any ideas?
If the same format holds, and if I understand your new objective correctly, my code should work regardless. If you are including other centuries, Honglei’s comment applies: years divisible by 100 are not leap years unless they are also divisible by 400. So 1900 was not a leap year, but 2000 was.
This should work for those exceptions as well:
yr = [1960:2014]';
cyr = mod(yr,100)==0; % Century Years
clpyr = mod(yr,400)==0; % Century Leap Year
lpyr = (mod(yr,4)==0) + (clpyr - cyr); % Leap Years Vector
dpy = ones(size(yr))*365+lpyr; % Create ‘Days/Year’ + Leap Years Vector
csd = cumsum(dpy); % Sum ‘Days/Year’
M = [yr [1; csd(1:end-1)+1] csd dpy]
The construction ‘+(clpyr - cyr)’ removes century years but adds years divisible by 400 to the leap year vector. I tested it with various years and it works for them.
I don’t know what you mean by ‘dynamically create the array’. (My code works only for single years and for vectors of consecutive years.) You could likely wrap it in a function m-file if you want to. The input argument is the year vector ‘yr’, and the output is the matrix ‘M’.
Damith
2014년 9월 18일
Thanks again for the revised code. But now the challenge is my start year and end year changes in "yr" array for 123 files.
Star Strider
2014년 9월 18일
My pleasure!
The start and end years shouldn’t be a problem providing they are either (1) single years, or (2) an array of consecutive years. I tested it on a variety of year vectors to be certain it worked for various century years. Obviously, it only applies to the Gregorian Calendar, but that applies for the last few centuries, so you should be OK.
If you are having a problem, tell me what it is and I’ll do my best to adapt my code to it. Please be a specific as possible.
Thanks. I have prioratize this from the prevous challenge.
I have 50 years slots of 10,000 years of data (suppose starting from 1998) meaning 200 rows.
1 1 18262 (1998-2047)
2 18263 36524 (2048-2097)
. . . .
200
I have 'output" array has 20,000 years of daily data meaning output(7305000 x 8) array has 7305000 rows and 8 columns. I need to read 5th column of first 10,000 years of "output" meaning row 1 to 3652500 and store in "output2" matrix which has rows equivalent to 50 years (considering the leap years). So, the "output2" matrix has 18262 rows and 200 columns.
Hope you understand my question.
I am not certain I do understand what you want to do, but this revision of my previous code should work:
yr1 = 1998;
epok = 200;
Mprev = [0 0];
for k1 = 1:epok
yr = yr1:yr1+49;
cyr = mod(yr,100)==0; % Century Years
clpyr = mod(yr,400)==0; % Century Leap Year
lpyr = (mod(yr,4)==0) + (clpyr - cyr); % Leap Years Vector
dpy = ones(size(yr))*365+lpyr; % Create ‘Days/Year’ + Leap Years Vector
csd = cumsum(dpy); % Sum ‘Days/Year’
M = [[0 csd(1:end-1)]'+1 csd'];
Mepok(k1,:) = sum([Mprev; [M(1,1) M(end,2)]],1);
Mprev = [Mepok(max([1 k1]),2) Mepok(end,2)];
end
The ‘epok’ variable is the number of 50-year segments (epochs) you want data for, and the ‘Mepok’ matrix is the output in the format you outlined in your previous Comment. I just incorporated my previous code and added the ‘Mepok’ matrix. I tested it on epok=5, but it should work on all 200.
Damith
2014년 9월 19일
Thanks again but this is not the result I want. The output matrix needs to have 18263 rows and 200 columns. Please see the attached excel file. Number of rows changes from 18262 to 18263 alternatively for 50 year segments from 1998 to 10000 years.
Your Excel sheet doesn’t exactly match your description, but this seems to do what you want:
yr1 = 1998;
epok = 50;
Mprev = [0 0];
for k1 = 1:epok
yr = yr1:yr1+49;
cyr = mod(yr,100)==0; % Century Years
clpyr = mod(yr,400)==0; % Century Leap Year
lpyr = (mod(yr,4)==0) + (clpyr - cyr); % Leap Years Vector
dpy = ones(size(yr))*365+lpyr; % Create ‘Days/Year’ + Leap Years Vector
csd = cumsum(dpy); % Sum ‘Days/Year’
M = [[0 csd(1:end-1)]'+1 csd'];
Mepok(k1,:) = sum([Mprev; [M(1,1) M(end,2)]],1);
Mprev = [Mepok(max([1 k1]),2) Mepok(end,2)];
Mout(k1,:) = [k1 Mepok(k1,:) (yr+k1-1):50:(yr+k1-1)+200*(epok-1)];
end
Mout % Display Output Matrix
I tweaked my previous code, and created a new output matrix ‘Mout’.
I would never have understood what you want without the spreadsheet.
추가 답변 (0개)
카테고리
도움말 센터 및 File Exchange에서 Calendar에 대해 자세히 알아보기
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!웹사이트 선택
번역된 콘텐츠를 보고 지역별 이벤트와 혜택을 살펴보려면 웹사이트를 선택하십시오. 현재 계신 지역에 따라 다음 웹사이트를 권장합니다:
또한 다음 목록에서 웹사이트를 선택하실 수도 있습니다.
사이트 성능 최적화 방법
최고의 사이트 성능을 위해 중국 사이트(중국어 또는 영어)를 선택하십시오. 현재 계신 지역에서는 다른 국가의 MathWorks 사이트 방문이 최적화되지 않았습니다.
미주
- América Latina (Español)
- Canada (English)
- United States (English)
유럽
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
