Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

算法讨论 #1

Open
1 task
emptymalei opened this issue Oct 2, 2014 · 56 comments
Open
1 task

算法讨论 #1

emptymalei opened this issue Oct 2, 2014 · 56 comments

Comments

@emptymalei
Copy link
Member

  • 历法加公元元年

InterImm/InterImmBook#46


转移过来的内容:

讨论转移到 https://github.com/InterImm/marsCalendar 新的 repo 中。


火星历

需要一个 js 程序,放在网页中,用于换算。或者就是一个简单的 iPython Notebook,写好文档,等等。

可能有用的参考,其中有两个现成的:

  1. http://jtauber.github.io/mars-clock/ or http://github.com/jtauber/mars-clock/
  2. http://www-mars.lmd.jussieu.fr/mars/time/martian_time.html
  3. http://www.giss.nasa.gov/tools/mars24/ or http://www.giss.nasa.gov/research/briefs/allison_02/
  4. http://marstime.readthedocs.org/en/latest/ or https://github.com/ashima/pyMarsTime/

计算闰年还算比较方便,大概也就类似这样吧:

# will return True if a year is a leap year on Mars
def is_leap_year(year):
    if year % 3000 == 0:
        return False
    elif year % 1000 == 0:
        return True
    elif year % 100 == 0:
        return False
    elif (year % 2 == 0) and (year % 10 == 0):
        return True
    else:
        return False

补充:

G 历换算到 J 历

http://scienceworld.wolfram.com/astronomy/JulianDate.html


Probe

我想到一个问题,火星与地球的距离时刻在变化,大概是几光分到十几光分,这样的话换算出来的时间到底是什么时候的时间??需要考虑对钟么?


emptymalei

我看了pyMarsTime那个,就是现成的程序,不需要做任何改动。

不过我们不需要这么复杂的,可以写一个简化版的。

闰年的函数我给了,剩下一个非常简单的事情就是计算我们地球日历的julian 天数,用这个来和火星的类似对应起来,也可以算,基本上几行程序。思路就是这样。周末我看看写出来。我还可以写一个mathematica 版的。

虽然我不怎么会写 js,但我觉得 js 也就是几行程序。再想想看。


styra

我也在想写来着,不知道怎么能做成互动的。iPython Notebook不能在线运行吧,js应该是可以,不过完全没用过。

嗯,从长远看,我们还是需要有交互式网页,一些小计算器转换器之类的。


emptymalei

嗯,感觉那些就后面考虑吧。我倒是学过 js,不过如果程序比较复杂我估计比较困难。比较好的方法是,我们就把函数/算法写出来,然后看看谁比较熟悉 js 就找其翻译过去就好了。

  1. 计算地球时间当前 julian date, 就知道多少天数了
  2. 计算火星元年第一天对应的 julian date 的天数
  3. 计算从火星元年到要换算的日期的 julian date 天数
  4. 把这些天数换算成火星天
  5. 计算这些火星日对应多少火星年、月(需要利用上面的 is_leap_year() 函数)

这里忽略了日出日落/一天开始的问题,先这样吧,主要是为了后面写 js 方便。如果是要真的完整的计算日期以及时间的对应,就直接用那个 pyMarsTime 吧。


https://github.com/jtauber/mars-clock/

这个是 js 版本的,估计就直接改一下关键的数字就可以了。不过需要自己看他的代码看看是不是跟我们定的一致。

@emptymalei emptymalei changed the title 先前的讨论 算法讨论 Oct 3, 2014
@unionx
Copy link
Member

unionx commented Oct 4, 2014

可以做成 IPython Notebook,然后放在这里:

http://nbviewer.ipython.org/

@emptymalei
Copy link
Member Author

@unionx
Copy link
Member

unionx commented Oct 4, 2014

国庆这几天出去玩了=。=

我看看一下最近的内容,哈哈哈哈哈

@emptymalei
Copy link
Member Author

@unionx 啊哈哈哈,帝老师我们也要放假了··~~ 等我也消失几天以示我还有生活……

@ProtossProbe
Copy link
Member

还好在edX学了Python的入门,姑且能看懂代码......

@ProtossProbe
Copy link
Member

为啥用2000-01-06这一天校准呢

@emptymalei
Copy link
Member Author

@SpaceXploration 因为这一天地球上零度经线的午夜也正好是火星上零度经线的午夜。

@syrte
Copy link

syrte commented Oct 7, 2014

@emptymalei 在网上查了查,时间转换真是个坑啊。
有点奇怪这里,

2012 年 07 月 01 日,因为这一天增加了 35 + 32.184 秒的闰秒

这是国际原子时(TAI)?


噢,不对。我再仔细看看注释里链接的说法。真晕。

@ProtossProbe
Copy link
Member

算法搞定了?怎么生成可交互的网页啊。。。?

@ProtossProbe
Copy link
Member

怎么在Python里算出了错误的结果??代码没动
qq 20141007210147
qq 20141007210205

@emptymalei
Copy link
Member Author

@SpaceXploration 没搞定呢,有个 bug 不知道在哪。

@unionx
Copy link
Member

unionx commented Oct 7, 2014

JS 我能写,我先把这部分内容看看

而且感觉这种页面小工具可以弄一个集合,方便大家查看使用

@emptymalei
Copy link
Member Author

帝老师,我这个 ipynb 里面有个函数写错了,大概是某个加减1有问题,等我捉虫。

@unionx
Copy link
Member

unionx commented Oct 7, 2014

@emptymalei 哪里啊?你描述一下,我也看看

@emptymalei
Copy link
Member Author

calendar_date(days, year) 这个函数。

看 SpaceXploration 那条。看起来应该是忘记减掉每月的天数了。

另外,还有一个错误迹象是 earth2mars_calendar([1970,4,29,20]) 这个给出了一个错误的日期。

你看看吧,应该就是比较愚蠢的那种 bug

@syrte
Copy link

syrte commented Oct 8, 2014

我也写了个此函数实现,供参考。

# returns the month and date given a number of dates.
# calendar_date(a number of days, which year we are calculating)
def calendar_date(days, year):
    if days > total_days(year):
        return "Error! Given number of days are more than the overall possible days of the year."
    if days ==0:
        return (1, 0)
    else:
        season = (days - 1) // 167 #167=28*5+27
        days = (days - 1) % 167
        if season == 4:
            return (24, 28)
        else:
            month = season * 6 + days // 28 + 1
            days = days % 28 + 1
            return (month, days)

不过这里算法对日数为小于1的浮点数不对,对负数日期也不对。要求日期为整数的话,0可以单独work around.

@emptymalei
Copy link
Member Author

我找到问题了。之前写对了,后来改的时候改错了。

@emptymalei
Copy link
Member Author

我改好了,这下应该没问题了。

@ProtossProbe
Copy link
Member

又运行了一下应该没有问题吧。

In [25]:
earth2mars_calendar([2014,10,8,13.5])
Out[25]:
[24, (16, 16.0)

今天是火历24年立冬月16号,星期一

这个只是转换日期吧?时刻怎么转换呢。。?

@ProtossProbe
Copy link
Member

想到了一个问题:火星上时区怎么划分。因为不是24小时制,相隔15°的区域时差不是1小时,而是
1.02748842593个小时,而火星上时差为1小时的区域经度相差14.5987°
是按15°划时区好还是14.5987°....?

@syrte
Copy link

syrte commented Oct 8, 2014

@SpaceXploration 个人以为用14.5987°吧,时间好换算。然后在 +12h 与 -12h 两条经线间额外增加一个 宽 9.6312° 的小时区。或者把 +11.5h 到 -11.5h 两条经线间算一个大时区,宽24.2299°。
不过这样,火星上的孩子学地理真是好烦人啊。


上面的讲法不对。地球上 ±12H 区是在 +11.5 到 -11.5h 的经线之间的。
或者把 +11.5h 到 +12h 记作 +12h 区,-11.5h 到 -12h 记作 -12h 区。然后 +12h 与 180° 经线(~±12.33h)间是 +12.33h 区, -12h 与180° 经线间是 -12.33h 区。180° 经线是日期变更线。
或者让 +11.5h 到 +12.33h 是 +12 区,-11.5h 到 -12.33h 是 -12 区。

@ProtossProbe
Copy link
Member

不要时区,用统一时间现不现实…?

@syrte
Copy link

syrte commented Oct 8, 2014

@SpaceXploration 统一时间离当地时有点远,比较麻烦吧?在不同的地方就要在不同的钟表时刻作息。
要不还是用15°?反正让时钟自己去算时区的时间差好了。

@syrte
Copy link

syrte commented Oct 8, 2014

@SpaceXploration 突然觉得统一时间也好了。地球上的时区 好花吖。

@ProtossProbe
Copy link
Member

@styra 刚刚意识到统一时间的一个问题。多出来的30多分钟不好处理……如果某个地区他们的工作时间横跨24:00-00:00,就不好定日程表。而如果分时区的话,可以把24:00-00:00的30多分钟作为深夜,对白天的日程没有影响。时区的话可能还是需要相隔一小时,不然的话时区切换比较麻烦……

@ProtossProbe
Copy link
Member

地球上这么花完全是政治原因……

@emptymalei
Copy link
Member Author

我原来也想过不分时区。各地按照自己的习惯来使用时间。

如果还是间隔一小时,只有 24 个时区的话,转了一圈之后,回不到原来的时区时间,这也不好。

如果加一个附加时区呢?每个间隔 1 小时,但是附加时区间隔 30 多分钟?把附加时区放在一个比较荒凉的地方如何?这样可以保证转一圈能回来。

@syrte
Copy link

syrte commented Oct 8, 2014

把附加时区放在 +12 和 -12 时区之间呗?

在 2014-10-08 15:47:55,"OctoMieow" notifications@github.com 写道:

我原来也想过不分时区。各地按照自己的习惯来使用时间。

如果还是间隔一小时,只有 24 个时区的话,转了一圈之后,回不到原来的时区时间,这也不好。

如果加一个附加时区呢?每个间隔 1 小时,但是附加时区间隔 30 多分钟?把附加时区放在一个比较荒凉的地方如何?这样可以保证转一圈能回来。


Reply to this email directly or view it on GitHub.

@emptymalei
Copy link
Member Author

@SpaceXploration

又运行了一下应该没有问题吧。

In [25]:
earth2mars_calendar([2014,10,8,13.5])
Out[25]:
[24, (16, 16.0)

今天是火历24年立冬月16号,星期一

这个只是转换日期吧?时刻怎么转换呢。。?

时刻也能换的,把函数换一下就行了。之所以没有写这个,是因为觉得没有什么用处。而且实际上这些程序写的时候,并没有非常严格的添加所有的修正,所以如果要换算精确的时间,需要把另外两个修正也考虑进来。也不算多麻烦,就是多加两个判断。等再考虑一下。

@emptymalei
Copy link
Member Author

@styra 感觉可以啊。

@ProtossProbe
Copy link
Member

我觉得时间换算的话还是精确到秒比较好。

@ProtossProbe
Copy link
Member

In [39]:
month_name = ('春分','清明','谷雨','立夏','小满','芒种','夏至','小暑','大暑','立秋','处暑','白露','秋分','寒露','霜降','立冬','小雪','大雪','冬至','小寒','大寒','立春','雨水','惊蛰')
week_name = ('六','日','一','二','三','四','五')
def chinese_character(mars_calendar):
return "火历"+str(mars_calendar[0])+"年 "+str(month_name[mars_calendar[1][0]])+"月"+str(int(mars_calendar[1][1]))+"日 "+"星期"+str(week_name[int(mars_calendar[1][1])%7])

In [41]:
print chinese_character([16, (20, 5.0)])

火历16年 大寒月5日 星期四

写了一点转换成汉语...

@emptymalei
Copy link
Member Author

@SpaceXploration 有时间的话把这个 push 到 repo 里面吧~~

@ProtossProbe
Copy link
Member

.ipynb_checkpoints 里的代码需要改么?

@emptymalei
Copy link
Member Author

@SpaceXploration 不需要啦,那个是自动保存产生的。

@emptymalei
Copy link
Member Author

更新:

  1. 添加时刻的换算函数
  2. 将元年开始时间改为 1970 年 04 月 28 日,21:17:30,这样是为了保证 2000 - 01 - 06 午夜正好是跟火星上的午夜对其

最后还剩下一件事情,就是填写闰秒修正。

@emptymalei
Copy link
Member Author

闰秒修正这个似乎需要按照每年添加闰秒的情况来添加。考虑到算法的精度,而且从 72 年到 2014 年一共也就是 35s 的样子,所以感觉添加闰秒修正的意义不大。

所以 @unionx 帝老师我们的 python 版本已经算是完成了。

@SpaceXploration @styra

@unionx
Copy link
Member

unionx commented Oct 12, 2014

我研究一下......js 的话应该写在哪里呢?

@ProtossProbe
Copy link
Member

输入和输出都统一成
[年,月,日,时,分,秒]
是不是比较好,输入带小数点的小时的话好像比较麻烦。

@ProtossProbe
Copy link
Member

闰秒我觉得也不需要......不然的话以后地球加闰秒的时候我们也要加,好麻烦。不过可以在时间换算的网页上注明一下这个误差

@emptymalei
Copy link
Member Author

@SpaceXploration 现在输入格式是 [年,月,日,时,分] ,秒没有必要了。

@emptymalei
Copy link
Member Author

@unionx

打算放在 这个 页面的。

@emptymalei
Copy link
Member Author

@unionx 其实我们最终网页上的“需求”是,填入一个地球的日期和时刻,输出火星日期和时刻。不知道这样可不可以做?

@ProtossProbe
Copy link
Member

在改输出格式函数的时候遇到点问题
多余的30多分钟,是按照book里写的记作 +xx:xx好,还是直接记作24:xx:xx好??

以及...需不需要一个逆转换程序?

@ProtossProbe
Copy link
Member

发现一个问题,earth2mars_calendar_time()算出来的时间,和Mars24上的AMT差别很大,按理说应该相差1.02倍才对啊。
qq 20141014002133
qq 20141014002156

@emptymalei
Copy link
Member Author

@SpaceXploration 这下问题大了。哎我看看。

@emptymalei
Copy link
Member Author

@SpaceXploration 我们的输入是 UTC 的时间。我试了下,相差大约 21 分钟的样子。

image

另外测试了 2000 年那个校准时刻,大约相差几十秒的修正,估计来自那几十秒的闰秒。

@emptymalei
Copy link
Member Author

进一步测试了一下,发现有浮动但是一直在一个小时之内。(更正,是一个小时之内)

另外排除了由于 AMT 使用当地的太阳日而不是平均太阳日的可能性。

那么问题在哪里呢?想不通。

@emptymalei
Copy link
Member Author

【更新】

添加了火星历到 Gregorian 历的换算函数。

@ProtossProbe
Copy link
Member

修改了几个地方

*1 is_leap_year_mars(year)改正
*2 新增函数 month_total_days(),用于计算任意一年任意一个月的天数
*3 新增时区划分部分,函数还没写完......

另外发现了几个可能是误差产生原因的地方?

Mars24以及http://jtauber.github.io/mars-clock/ 都比较精确,m2e的值用的是1.027491252,而我们的程序用的是88775.0/86400 = 1.02748842593。不过把m2e用精确的值替代后,同样有误差,而且还变大了......
此外,2000-01-06这一天的午夜与火星零度经线的午夜并不是完全对其,相差0.00096天,也就是83s,看起来这个应该不是主要影响因素。

@emptymalei
Copy link
Member Author

@SpaceXploration 我想不明白为什么会有这么大的差异,而且不规律的在一小时之内浮动。

@emptymalei
Copy link
Member Author

@SpaceXploration 我之前想到过一个可能性是我用来计算 Julian days 的公式不准确,但是后来看了看 python 的一个库,还不如我这个考虑的因素多。而且我换上那个库之后得到的结果也不准确。

如果我们的结果跟 Mars24 的结果的差异越来越大或者越来越小,都可以理解,但是我们现在却偏偏是上下浮动,实在难以理解。

@emptymalei
Copy link
Member Author

想想下面能做的,就是跟这个 https://github.com/ashima/pyMarsTime/blob/master/marstime/__init__.py 对照一下了。

@ProtossProbe
Copy link
Member

搞定了时区部分,现在地球上任意时区时间可以和火星上任意时区时间互换啦!

@emptymalei
Copy link
Member Author

赞。越来越好了。

@syrte
Copy link

syrte commented Jan 31, 2015

刚想到啊,一周从周日开始,每个1号是周日,2号是周一,7号是周六,这对中国人来说真是有点反直觉呢。不过也没办法喽。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants